# Generate code metrics for your Golang public repositories with SonarCloud and GoSec using Github Actions
## Static Code Analysis
Static code analysis is the process of detecting errors and defects in a software's source code. As its name indicates, it is done statically, that is, the code is never executed and is evaluated by its form.
In the market, there are several static code analyzers, both free and paid. In this article, we will focus on two of them: **SonarCloud** and **GoSec**.
The result of this analysis generates quite a few useful metrics for developers.
## Code Metrics
The idea of combining SonarCloud with GoSec is to generate a set of metrics that will be used to improve code quality.
These metrics are computed according to a set of rules predefined in the tools. If business needs require specific rules that are aligned with your definition of quality, these can be added.
The metrics that will be generated by SonarCloud and GoSec are the following:
* Bugs: A coding error that will break your code and needs to be fixed immediately.
* Vulnerabilities: Code that can be exploited by hackers.
* Hotspots Reviewed: Security-sensitive code that requires manual review to assess whether or not a vulnerability exists.
* Code Smells: Code that is confusing and difficult to maintain.
* Coverage: The percentage of lines of code covered by tests.
* Duplications: Identical lines of code.
* Duplicated Blocks: The number of duplicated blocks of lines of code.
### Code Coverage
Code coverage is a software testing metric that determines the number of code lines covered by a test. It is only a metric, it does not in itself directly reflect whether the code is of quality or not. You know for sure that code coverage gives you only information on what parts of your system are not tested.
SonarCloud does not run the tests and calculate the coverage. This is done by each language's tools.
In the case of Go, it has a built-in coverage flag `-coverprofile` that generates the coverage report for the code.
#### Generate Go code coverage
To generate the coverage report for your Go code, use the following command at the root of your Go application.
```bash
go test -coverprofile=./cov.out ./...
```
It generates a `cov.out` file that contains all the information.
```out
mode: set
github.com/brayanhenao/sample-go-app/math/math.go:3.30,5.2 1 1
github.com/brayanhenao/sample-go-app/math/math.go:7.35,9.2 1 1
github.com/brayanhenao/sample-go-app/math/math.go:11.39,13.2 1 0
github.com/brayanhenao/sample-go-app/math/math.go:15.41,16.12 1 0
github.com/brayanhenao/sample-go-app/math/math.go:20.2,20.11 1 0
github.com/brayanhenao/sample-go-app/math/math.go:16.12,18.3 1 0
github.com/brayanhenao/sample-go-app/main.go:21.32,26.2 1 1
github.com/brayanhenao/sample-go-app/main.go:28.33,33.2 1 1
github.com/brayanhenao/sample-go-app/main.go:35.32,40.2 1 0
github.com/brayanhenao/sample-go-app/main.go:42.35,47.2 1 0
github.com/brayanhenao/sample-go-app/main.go:49.32,57.2 3 0
github.com/brayanhenao/sample-go-app/main.go:59.37,67.2 3 0
github.com/brayanhenao/sample-go-app/main.go:69.13,84.2 9 0
```
If you want to display the detailed information in a more user-friendly format, there is another Go tool called `cover` that generates an HTML version of the report.
```bash
go tool cover -html=cov.out -o coverage-report.html
```
You can open the generated HTML in your browser.

### Vulnerabilities
Code vulnerability is a term related to the security of your software. It is a flaw in your code that creates a potential risk of compromising security. This flaw will allow hackers to take advantage of your code by attaching an endpoint to extract data, tamper with your software, or worse, erase everything.
## SonarSource / SonarQube / SonarCloud
[SonarSource](https://www.sonarsource.com/) is a company that develops open-source software for continuous code quality and security. It has two main products: SonarQube and SonarCloud.
Both products feature the same security/coverage analysis report viewing functionality. The difference is that [SonarQube](https://www.sonarqube.org/) is an on-premise open-source solution that requires some initial configuration and requires its server to run.
[SonarCloud](https://sonarcloud.io) on the other hand is the SaaS solution by SonarSource that offers these same functionalities in cloud environments plus additional customer support. It has free plans for open-source projects/public repositories and paid enterprise plans.
## GoSec
[GoSec](https://github.com/securego/gosec) is a tool focused on analyzing security issues in your code and complements the SonarCloud scanner tool. The report generated by `gosec` can be easily integrated into SonarQube and all issues appear the same way in the UI.
### Generate a GoSec report in Sonar format
```bash
gosec -fmt=sonarqube -out report.json ./...
```
It generates a `JSON` report in this format:
```json
{
"issues": [
{
"engineId": "gosec",
"ruleId": "G104",
"cwe": {
"ID": "703",
"URL": "https://cwe.mitre.org/data/definitions/703.html"
},
"primaryLocation": {
"message": "Errors unhandled.",
"filePath": "main.go",
"textRange": {
"startLine": 83,
"endLine": 83
}
},
"type": "VULNERABILITY",
"severity": "MINOR",
"effortMinutes": 5
}
]
}
```
## Analyze your code
### Setup SonarCloud account
It's free for public repositories. If you want to use it for private repositories, you have to use the paid version. You can log in with **Github**, **Bitbucket**, **Gitlab** and **Azure DevOps**. The scope of this guide applies only to **Github** since we will be using **Github Actions**.

Once your free account is created, you will be able to create a new SonarCloud Organization or import an existing one from your VCS provider.

### Create an Organization
In this example, I will create an organization manually.

And select the free tier plan.

### Create a SonarCloud Token
To use SonarCloud resources, a token is required. To generate it, go to **Profile -> My Account -> Security**. Copy it and save it securely somewhere, since you will not be able to retrieve it again.

### Create a new project to analyze
After the organization is created, we have to create a new project on Sonarcloud.

It is really important to take note of the **project key** since it will be required by the SonarCloud properties file.
### Change SonarCloud default scan branch
SonarCloud new manually created projects have _master_ as the default branch. If your repository's default branch is master, skip this process. If your default branch is _main_ or any other, you have to change it.
Go to **Administration -> Branches & Pull Requests** and rename the default branch.

### Setup the repository
When the project is created in SonarCloud, we proceed to create the configuration files and the secret that will help us analyze the code using Github Actions.
#### SonarCloud token repository secret
Since we are going to use the SonarCloud Github Action we need to create a new repository secret. In the repository, go to **Settings -> Secrets -> New repository secret** and paste the SonarCloud token generated previously.

##### SonarCloud project properties
In the root of the repo, create a file named `sonar-project.properties` with this content:
```properties
sonar.projectKey=go-sample-app
sonar.organization=bhenao-go-analyze-demo
# This is the name and version displayed in the SonarCloud UI.
sonar.projectName=go-sample-app
sonar.projectVersion=1.0
sonar.sources=.
sonar.exclusions=**/*_test.go
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.go.coverage.reportPaths=cov.out
sonar.externalIssuesReportPaths=report.json
```
**Note:**
* Replace `sonar.projectKey`, `sonar.organization` and `sonar.projectName` with the values previously generated in the creation of the organization and the project.
* If your project requires more exclusions (e.g. autogenerated code, code that should not be taken into account, etc.), they can be added separated by commas in `sonar.exclusions`.
#### Github Workflow
Since we are going to use Github Actions, a workflow is needed to run this analysis. This action is triggered by any push on the default branch (in this case main) or a workflow dispatch (manually).
Create a file named `static-analysis.yml` inside `.github/workflows` folder with this content:
```yml
name: Static Analysis and Report
on:
push:
branches:
- main
pull_request:
types: [ opened, synchronize, reopened ]
workflow_dispatch: { }
jobs:
analyze:
name: Static analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v2.1.3
with:
go-version: 1.16.x
- name: Run unit Tests
run: |
go test -coverprofile=./cov.out ./...
- name: Run Gosec Security Scanner
run: |
go get github.com/securego/gosec/cmd/gosec
gosec -no-fail -fmt=sonarqube -out report.json ./...
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
```
If you are using a Go version < 1.6.x, change it in the **Setup Go** step.
### Check the results
Once the Github action finishes, the report will be generated on the SonarCloud page. It will give you all the metrics and information about your project.

You can even generate cool badges for the results.
[](https://sonarcloud.io/dashboard?id=go-sample-app) [](https://sonarcloud.io/dashboard?id=go-sample-app) [](https://sonarcloud.io/dashboard?id=go-sample-app) [](https://sonarcloud.io/dashboard?id=go-sample-app)