Scan Your Code with Ephemeral SonarQube in GitHub Actions

As developers, we all know the importance of maintaining high code quality standards. One powerful tool that can help us achieve this is SonarQube, a renowned platform for continuous code quality inspection. However, setting up and maintaining a dedicated SonarQube instance can be a cumbersome task, requiring significant resources and ongoing maintenance.

Fortunately, GitHub Actions offers a convenient solution by allowing us to spin up an ephemeral (short-lived) SonarQube instance directly within our workflow. This approach streamlines the process, eliminating the need for a permanent SonarQube server while still reaping the benefits of its code analysis capabilities.

Why Ephemeral SonarQube?

Using an ephemeral SonarQube instance in your GitHub Actions workflow provides several advantages:

  1. No Infrastructure Overhead: With ephemeral SonarQube, you don't need to worry about provisioning and maintaining a dedicated server or virtual machine for SonarQube. This reduces infrastructure costs and management overhead.
  2. Scalability: Ephemeral instances can be easily spun up and torn down as needed, making the process highly scalable and adaptable to your project's requirements.
  3. Consistent Environment: By running SonarQube within the GitHub Actions environment, you ensure a consistent and reproducible analysis environment across all your builds. For open-source projects, it validates every Pull Request without requiring a SonarQube instance and permissions for contributors.
  4. Secure and Isolated: Each ephemeral SonarQube instance is isolated and secure, reducing the risk of cross-contamination or security vulnerabilities.

Setting up Ephemeral SonarQube in GitHub Actions

Setting up an ephemeral SonarQube instance in your GitHub Actions workflow is a straightforward process. Here's a high-level overview of the steps involved:

  1. Define a GitHub Actions Workflow: Create a new workflow file (e.g., .github/workflows/sonar-check.yml) in your repository.
  2. Configure SonarQube Instance as a service: Run SonarQube instance as a service container. Specify the instance details, including the version and edition (community or enterprise) you want to use. Then, configure the custom quality profiles and quality gate for meeting the code quality standards of your project.
  3. Build Your Project and Run Tests with Reports: Build your code and run tests for coverage reports, if applicable.
  4. Trigger Code Analysis: Use the sonarsource/sonarqube-scanner-action or another community action using SonarQube Scanner CLI to run the SonarQube Scanner against your codebase, configuring any necessary analysis properties or exclusions.
  5. Check the Analysis Result: After the analysis is complete, check if the result meets the quality gate or not.
  6. Update Analysis Result to Pull Request: Write the SonarQube analysis result to the Pull Request as a new comment. It would be ideal to comment on the new code for any new finding issues.

Here's an example of how your GitHub Actions workflow might look:

 1name: code scans
 2on:
 3  pull_request: {}
 4  workflow_dispatch: {}
 5jobs:
 6  sonarqube:
 7    name: sonarqube scan
 8    runs-on: 'ubuntu-latest'
 9    services:
10      sonarqube:
11        image: public.ecr.aws/docker/library/sonarqube:10-community
12        ports:
13          - 9000:9000
14    steps:
15      - uses: actions/checkout@v4
16      - name: Setup Node.js
17        uses: actions/setup-node@v4
18        with:
19          node-version: 20.x
20      - name: Install dependencies
21        run: yarn install --check-files && yarn --cwd example/ install --check-files
22      - name: Run build and unit tests
23        run: npx projen compile && npx projen test
24      - name: Configure sonarqube
25        env:
26          SONARQUBE_URL: http://localhost:9000
27          SONARQUBE_ADMIN_PASSWORD: ${{ secrets.SONARQUBE_ADMIN_PASSWORD }}
28        run: |
29          bash .github/workflows/sonarqube/sonar-configure.sh          
30      - name: SonarQube Scan
31        uses: sonarsource/sonarqube-scan-action@master
32        env:
33          SONAR_HOST_URL: http://sonarqube:9000
34          SONAR_TOKEN: ${{ env.SONARQUBE_TOKEN }}
35        with:
36          args: >
37            -Dsonar.projectKey=pr-${{ github.event.pull_request.number }}            
38      # Check the Quality Gate status.
39      - name: SonarQube Quality Gate check
40        id: sonarqube-quality-gate-check
41        uses: sonarsource/sonarqube-quality-gate-action@master
42        # Force to fail step after specific time.
43        timeout-minutes: 5
44        env:
45          SONAR_TOKEN: ${{ env.SONARQUBE_TOKEN }}
46          SONAR_HOST_URL: http://localhost:9000
47      - uses: phwt/sonarqube-quality-gate-action@v1
48        id: quality-gate-check
49        if: always()
50        with:
51          sonar-project-key: pr-${{ github.event.pull_request.number }}
52          sonar-host-url: http://sonarqube:9000
53          sonar-token: ${{ env.SONARQUBE_TOKEN }}
54          github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
55      - name: Comment results and findings on Pull Request
56        uses: zxkane/sonar-quality-gate@master
57        if: always()
58        env:
59          DEBUG: true
60          GITHUB_TOKEN: ${{ secrets.PROJEN_GITHUB_TOKEN }}
61          GIT_URL: "https://api.github.com"
62          GIT_TOKEN: ${{ secrets.PROJEN_GITHUB_TOKEN }} 
63          SONAR_URL: http://sonarqube:9000
64          SONAR_TOKEN: ${{ env.SONARQUBE_TOKEN }}
65          SONAR_PROJECT_KEY: pr-${{ github.event.pull_request.number }}
66        with:
67          login: ${{ env.SONARQUBE_TOKEN }}
68          skipScanner: true

In this example, the workflow is triggered on pull request events to the main branch. The sonarsource/sonarqube-scanner-action is used to install the SonarQube Scanner and perform the code analysis. The SONAR_TOKEN environment variables is used to authenticate with the ephemeral SonarQube instance and its URL is specified as localhost:9000 or sonarqube:9000 which only could be accessed from the workflow runtime, respectively.

After the analysis is complete, the sonarsource/sonarqube-quality-gate-action is used to check if the code meets the defined quality gate criteria. The customize quality gate is configured in the Configure sonarqube step.

The final step comments the results on the Pull Request and adds finding issues as inline comments too.

You can check the complete sample in this repo.

Conclusion

Incorporating ephemeral SonarQube into your GitHub Actions workflow streamlines the process of continuous code quality inspection. By leveraging the power of SonarQube without the overhead of maintaining a dedicated instance, you can ensure that your codebase adheres to high quality standards with minimal effort.

Give ephemeral SonarQube a try in your next project and experience the benefits of seamless code analysis and quality assurance within your GitHub Actions workflows.