SonarScanner CLI Docker in GitHub Actions

When using SonarQube’s SonarScanner CLI in GitHub Actions it may not always be possible to use the official public action, perhaps your organisation doesn’t permit public actions, or only approves specific ones.

In such cases you may look to create your own internal action and SonarQube provide their SonarScanner CLI tool in a Docker image for easy consumption. The documentation gives you an example on how to create a container using their image:

docker run \
    --rm \
    -e SONAR_HOST_URL="http://${SONARQUBE_URL}" \
    -e SONAR_SCANNER_OPTS="-Dsonar.projectKey=${YOUR_PROJECT_KEY}" \
    -e SONAR_TOKEN="myAuthenticationToken" \
    -v "${YOUR_REPO}:/usr/src" \
    sonarsource/sonar-scanner-cli

I tried this in a GitHub Action workflow and all initially seemed fine, the code scan completed and analysis was successfully pushed to SonarQube and results returned to the workflow. Upon checking it in the UI though, I noticed that the results had been pushed to the main branch and there were no signs of SonarQube having knowledge of any branches in the GitHub repository.

After much troubleshooting, I eventually tracked this down to auto detection of branch existence and configuration not taking place by the SonarScanner CLI in the workflow. I was able to compare a scan using the Docker image vs a scan with the official GitHub Action, which uses the same Docker image under the hood. With the official Action, something similar to the following will appear in the logs:

INFO: Load project branches
INFO: Load project branches (done) | time=22ms
INFO: Load branch configuration
INFO: Detected branch/PR in 'GitHub Action'
INFO: Auto-configuring branch 'test-branch-1'
INFO: Load branch configuration (done) | time=5ms

This was not occuring in the scan with the Docker image, instead something similar to this would be observed:

INFO: Load project branches
INFO: Load project branches (done) | time=31ms
INFO: Load branch configuration
INFO: Load branch configuration (done) | time=7ms

I discovered that it was possible to manually set the branch name by supplying sonar.branch.name, however this was less than optimal, possibly wouldn’t work for PR requests and I wanted to get to the bottom of why auto detection was not occuring.

I found this SonarQube community post which put me on the track that the SonarScanner CLI was looking for built in CI environment variables and they need to be supplied to the docker run command. The post was about GitLab, not GitHub, but I figured something similar would be needed. I noticed that when the Docker container in the official Action was run, the following GitHub environment variables were supplied to it, i.e. pretty much all of them!

-e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_REPOSITORY_OWNER_ID" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_REPOSITORY_ID" -e "GITHUB_ACTOR_ID" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKFLOW_REF" -e "GITHUB_WORKFLOW_SHA" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_ENVIRONMENT" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e "ACTIONS_ID_TOKEN_REQUEST_URL" -e "ACTIONS_ID_TOKEN_REQUEST_TOKEN" -e "ACTIONS_RESULTS_URL" -e GITHUB_ACTIONS=true -e CI=true

I tried this in my workflow and branch auto detection returned. By process of elimination and lots of workflow runs I was able to get this down to a more manageable list which appear to be the required variables and formed the end result:

docker run \
    --rm \
    -v $GITHUB_WORKSPACE:/usr/src \
    -e "GITHUB_REF" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_REF_NAME" -e GITHUB_ACTIONS=true \
    -e SONAR_HOST_URL="${{ inputs.sonar_host_url }}" \
    -e SONAR_TOKEN="${{ inputs.sonar_token }}" \
    -e SONAR_SCANNER_OPTS="\
    -Dsonar.projectKey=${{ inputs.project_key }} " \
    sonarsource/sonar-scanner-cli:5.0.1

Hopefully this might get added to the official documentation some day, although based on a SonarQube rep’s comment it seems perhaps not likely: