> For the complete documentation index, see [llms.txt](https://amocsub.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://amocsub.gitbook.io/blog/posts/unlocking-code-quality-with-sonarqube-and-github-actionsge.md).

# Unlocking Code Quality with SonarQube and GitHub Actionsge

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FAayXyKck2DjxfhEIbr6S%2F1700936838542.jpeg?alt=media&amp;token=a9f6d297-0733-4620-911b-4985a4553058" alt=""><figcaption><p>sonar SDLC tools</p></figcaption></figure>

Greetings Developers! In this article, we'll explore the integration of [SonarQube](https://www.sonarsource.com/products/sonarqube/) with [GitHub Actions](https://docs.github.com/en/actions) for a streamlined code quality assessment. We'll cover the installation of [SonarQube](https://www.sonarsource.com/products/sonarqube/) Community, establishing a seamless connection with a test GitHub repository and implementing automated scans through GitHub Actions [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners). This step-by-step guide aims to empower developers to introduce **efficient code quality management** within their existing workflows.

***

### Quick intro... <a href="#ember1499" id="ember1499"></a>

#### What is SonarQube? <a href="#ember1500" id="ember1500"></a>

**SonarQube** is a premier static code analysis tool. It meticulously examines code for bugs and security issues, aiding in comprehensive code quality & security assessments. As a key player in the realm of DevOps, it facilitates streamlined integration with **GitHub Actions**.

#### What are Github Actions? <a href="#ember1502" id="ember1502"></a>

**GitHub Actions** is an automation platform from GitHub that allows developers to define workflows for their software projects. It give you the chance to automate tasks such as building, testing, and deploying code directly from your GitHub repositories. With **GitHub Actions**, you can create custom workflows using pre-defined or custom actions, streamlining your development process and enhancing collaboration among team members.

#### What are Github Actions self-hosted runners? <a href="#ember1504" id="ember1504"></a>

GitHub Actions **self-hosted** **runners** are instances of GitHub Actions runners that you set up and manage in your own environment. These runners allow you to run workflows on your own infrastructure, providing flexibility and control over the execution environment. Whether on cloud servers, on-premises hardware, or even your local machine, **self-hosted** **runners** enable you to tailor the execution environment to your specific needs, enhancing the capabilities of GitHub Actions for your projects.

***

### Setup... <a href="#ember1506" id="ember1506"></a>

#### How to run SonarQube locally: <a href="#ember1507" id="ember1507"></a>

Despite there are a few ways to run it, for the sake of this article I'm gonna showcase how to run it from a local docker container. If you want to follow this steps you should have Docker installed in your computer. For more information please refer to [this article](https://docs.sonarsource.com/sonarqube/latest/try-out-sonarqube/).

```bash
docker run -it --rm -p 9000:9000 sonarqube:10.3.0-community
```

And as simple as that we have our **SonarQube Community** instance running and on [http://localhost:9000](http://localhost:9000/) where you would be able to login with **admin:admin** credentials.

#### Let's also use a self-hosted Github Actions runner locally <a href="#ember1510" id="ember1510"></a>

From your Github repository go to **Settings -> Actions -> Runners** and add one with the commands they provide. Have in mind that the runner should be able to reach the **SonarQube** instance so it can be able to populate the results.

If you need help with this setup, please read [this article](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners).

<figure><img src="https://media.licdn.com/dms/image/D4E12AQG2OO6ih1y2hA/article-inline_image-shrink_1500_2232/0/1700932902979?e=1718841600&#x26;v=beta&#x26;t=0S0vd0J5jo0oX7w_2qU8sp-OJa1m2Zp8sov9_nHnfbk" alt=""><figcaption><p>chromebook runner added successfully to github</p></figcaption></figure>

For this test I've forked the repository [DefectDojo/django-DefectDojo](https://github.com/DefectDojo/django-DefectDojo) at which I've added the runner in a Chromebook.

#### (Optional) Grant SonarQube permissions for PR decoration <a href="#ember1515" id="ember1515"></a>

**If you have a paid SonarQube Developer edition license**, now that we have most of the things running we should only let the instance to be able to comment on our Pull requests, so we can have the decoration if something was found at the scan.

More info on how to set up the Github app in [this article](https://docs.sonarsource.com/sonarqube/latest/devops-platform-integration/github-integration/).

<figure><img src="https://media.licdn.com/dms/image/D4E12AQH188I0Rz5Z1A/article-inline_image-shrink_1500_2232/0/1700925558118?e=1718841600&#x26;v=beta&#x26;t=6kh9zMstMgGpcbwA_rZK1b5Vi312wzRJDFmhosKg_Cs" alt=""><figcaption><p>SonarQube Local Github App installed</p></figcaption></figure>

#### Add repository as a SonarQube Project <a href="#ember1519" id="ember1519"></a>

Once the app is installed we are ready to onboard some of our Github repositories, in this case we are going to add the [**django-DefectDojo**](https://github.com/amocsub/django-DefectDojo) project I've forked.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQF5119bRD-obw/article-inline_image-shrink_1500_2232/0/1700926000315?e=1718841600&#x26;v=beta&#x26;t=iK-vjLd1vqFqPQ5STjRBmJbTSh0T73cN6CYwBzSlglE" alt=""><figcaption><p>project creation from github source</p></figcaption></figure>

After adding the project, SonarQube would ask us how would we want to set up the analysis and for the purpose of this demo we are going to show up the Github Actions integration.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQEhZXgIjMmHJA/article-inline_image-shrink_1500_2232/0/1700926107104?e=1718841600&#x26;v=beta&#x26;t=S6IN24wji2a3GFNkFwh8VgZlnkGaNB7xJP1fdHuVkMY" alt=""><figcaption><p>setup with github actions pane</p></figcaption></figure>

So here comes the part where SonarQube suggest us to add both **SONAR\_TOKEN** and **SONAR\_HOST\_URL** as repository secrets, which we should always do instead of hardcoding them to follow proper secret management practices.

But after that, there is an example action workflow that for this demo we are going to avoid. Therefore the action I made is the following:

```yaml
name: SonarQube Scan

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches:
      - master
  
jobs:
  sonarqube-scan:
    name: sonarqube-scan
    runs-on: self-hosted
    permissions: read-all
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - run: |
          sonar-scanner \
          -Dsonar.sources=. \
          -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \
          -Dsonar.token=${{ secrets.SONAR_TOKEN }}
```

You can tell that in this example I'm running sonar-scanner locally, that's because the runner I'm using is a linux machine that already has **sonar-scanner** installed.

***

### And now what? <a href="#ember1527" id="ember1527"></a>

#### Run scans <a href="#ember1528" id="ember1528"></a>

With all of this we are ready to add some changes to the repo and see our action being triggered as the following image.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQG1kk7HGtkjbw/article-inline_image-shrink_1500_2232/0/1700931614222?e=1718841600&#x26;v=beta&#x26;t=1f4DO9eRa72q2Cp-1dICICX7QtuiBCuIKo9-8lpNIC0" alt=""><figcaption><p>action running in github PR commit change</p></figcaption></figure>

Once the action finishes the scan, we can head up to SonarQube platform to see the results.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQGLe5vTXbKMcw/article-inline_image-shrink_1500_2232/0/1700933218624?e=1718841600&#x26;v=beta&#x26;t=YLQnBoSzOfDyv7FSS0ST8zJDRvOogrQ2q6cYR7Dt77E" alt=""><figcaption><p>overview of finding results</p></figcaption></figure>

Due to the security features SonarQube introduces you can also find things that are not code smells or developing bad habits but also potential vulnerabilities such as the following:

<figure><img src="https://media.licdn.com/dms/image/D4E12AQH0AvhQfdkxwA/article-inline_image-shrink_1500_2232/0/1700933643326?e=1718841600&#x26;v=beta&#x26;t=jeVnwTUSi18kDV0Da5fA-5939juaOS2s_TD4wvmNn8E" alt=""><figcaption><p>possible sql injection in defect dojo migrate_surveys.py file</p></figcaption></figure>

#### How to prevent buggy code from being pushed? <a href="#ember1535" id="ember1535"></a>

You can also use [**SonarLint**](https://www.sonarsource.com/products/sonarlint/) to run the scans directly on your IDE, preventing you to introduce buggy code into the codebases. Let's use **VSCode** integration for this example but there is support for many others such as **JetBrains**, **Visual Studio** or **Eclipse**.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQGzxyVV0MfARg/article-inline_image-shrink_1500_2232/0/1700934209255?e=1718841600&#x26;v=beta&#x26;t=Cp_WfFLuB9rrGQccdlBU5gxEJWrz82RXfNH51_z-l2w" alt=""><figcaption><p>SonarLint VSCode plugin page</p></figcaption></figure>

If we install it from the **VSCode** plugins tab, then we just need to provide our SonarQube location and a token.

In our case, it's going to be [http://localhost:9000](http://localhost:9000/) and a user token generated from your user account security panel at the SonarQube's console.

Once the plugin is enabled and configured we can monitor the findings and get Sonar insights right there in the editor.

<figure><img src="https://media.licdn.com/dms/image/D4E12AQFnzFjwUHQATQ/article-inline_image-shrink_1500_2232/0/1700935235584?e=1718841600&#x26;v=beta&#x26;t=O-fa0zngSsEMUb4LRUvd9IQpgoj--lGPIhSj39PE_3Q" alt=""><figcaption><p>vscode editor with sonarlint extension showing same sqli issue</p></figcaption></figure>

***

### Conclusions... <a href="#ember1542" id="ember1542"></a>

This article is just a showcase of the capabilities you can introduce to your developing pipelines with low effort implementations that can save a lot of hours of debugging or even lower risks in your tech stack.

You can find more information at [Sonar](https://www.linkedin.com/company/sonarsource/)'s & [GitHub](https://www.linkedin.com/company/github/)'s websites with tons of examples on how to integrate them and much more.

My thought's...

> Try to keep security controls as simple as possible for your developers so that they do not perceive you as a hindrance but as an ally.

Thanks for getting this far, I hope you find this article useful and please give me your thought's on the comments.

Have you used any [Sonar](https://www.linkedin.com/pulse/unlocking-code-quality-sonarqube-github-actions-matias-busco-jp05f/?trackingId=UYzEZSj9RKmOY5RILHJr7A%3D%3D#) tool before? Do you have any similar setup? I'd be more than pleased to talk about it or **#SDLCSecurity #SonarQube #GithubActions #CyberSecurity** and much more...

Thanks!
