Skip to content

Commit cc927a5

Browse files
rodrieizsantib
andauthored
Replace CodeClimate with SonarQube (#1130)
Co-authored-by: Santiago Bartesaghi <[email protected]>
1 parent dc8242b commit cc927a5

File tree

5 files changed

+92
-38
lines changed

5 files changed

+92
-38
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ permissions:
1212

1313
env:
1414
RAILS_ENV: test
15-
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
1615
CI: true
1716
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1817
REPO: ${{ github.repository }}
@@ -132,11 +131,6 @@ jobs:
132131
uses: ruby/setup-ruby@v1
133132
with:
134133
bundler-cache: true
135-
- name: Setup Code Climate test-reporter
136-
run: |
137-
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
138-
chmod +x ./cc-test-reporter
139-
./cc-test-reporter before-build
140134
- name: Let Rails generate the secret_key_base
141135
run: bundle exec rails runner 'puts Rails.application.secret_key_base'
142136
- name: Setup Database
@@ -164,13 +158,13 @@ jobs:
164158
uses: rootstrap/check_untracked_changes@v1
165159
with:
166160
path: "./app/ ./spec/"
167-
- name: Report to CodeClimate
168-
run: ./cc-test-reporter format-coverage --output "coverage/coverage.${{ matrix.ci_node_index }}.json"
169-
- name: Upload partial coverage
161+
- name: Rename coverage files
162+
run: mv coverage/coverage.json coverage/coverage-${{ matrix.ci_node_index }}.json
163+
- name: Upload coverage report
170164
uses: actions/upload-artifact@v4
171165
with:
172-
name: coverage
173-
path: "coverage/coverage.${{ matrix.ci_node_index }}.json"
166+
name: "coverage-${{ matrix.ci_node_index }}"
167+
path: coverage/coverage-${{ matrix.ci_node_index }}.json
174168
- name: Merge API Docs from threads
175169
env:
176170
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
@@ -192,32 +186,27 @@ jobs:
192186
with:
193187
fetch-depth: 0
194188
ssh-key: "${{ secrets.PUSH_KEY }}"
195-
- name: Set ENV for CodeClimate
196-
if: github.event_name == 'pull_request'
197-
run: |
198-
git fetch --no-tags --prune --depth=1 origin +refs/heads/$GITHUB_HEAD_REF:refs/remotes/origin/$GITHUB_HEAD_REF
199-
echo "GIT_BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV
200-
echo "GIT_COMMIT_SHA=$(git rev-parse origin/$GITHUB_HEAD_REF)" >> $GITHUB_ENV
201-
echo "PULL_REQUEST_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
202189
- name: Set ENV for API Docs
203190
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
204191
run: |
205192
if [ $(git diff ${{ github.event.before }} ${{ github.event.after }} --name-only | grep 'spec/requests/api' | wc -l) -gt 0 ]; then
206193
echo "OPENAPI=true" >> $GITHUB_ENV
207194
fi
208-
- name: Setup Code Climate test-reporter
209-
run: |
210-
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
211-
chmod +x ./cc-test-reporter
212-
- name: Download coverage reports
213-
uses: actions/download-artifact@v5
195+
- name: Download coverage report
196+
uses: actions/download-artifact@v4
214197
with:
215-
name: coverage
216-
path: coverage/coverage.*.json
217-
- name: Report coverage
198+
pattern: coverage-*
199+
path: coverage/
200+
merge-multiple: true
201+
- name: Set ENV for SonarQube
218202
run: |
219-
./cc-test-reporter sum-coverage coverage/**/*.json
220-
./cc-test-reporter upload-coverage
203+
echo "SONAR_PROJECT_VERSION=$(echo $GITHUB_SHA | cut -c1-8)" >> $GITHUB_ENV
204+
echo "SONAR_REPORT_PATHS=$(ls coverage/coverage-*.json | paste -sd "," -)" >> $GITHUB_ENV
205+
- name: SonarQube Scanner
206+
uses: sonarsource/[email protected]
207+
env:
208+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
209+
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
221210
- name: Enable Corepack
222211
run: corepack enable
223212
- name: Setup Node

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Rails API Template
22

33
[![Github Actions CI](https://github.com/rootstrap/rails_api_base/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/rootstrap/rails_api_base/actions)
4-
[![Code Climate](https://codeclimate.com/github/rootstrap/rails_api_base/badges/gpa.svg)](https://codeclimate.com/github/rootstrap/rails_api_base)
5-
[![Test Coverage](https://api.codeclimate.com/v1/badges/63de7f82c79f5fe82f46/test_coverage)](https://codeclimate.com/github/rootstrap/rails_api_base/test_coverage)
4+
[![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-white.svg)](https://sonarcloud.io/project/overview?id=rootstrap_rails_api_base)
5+
66

77
Rails API Base is a boilerplate project for JSON RESTful APIs. It follows the community best practices in terms of standards, security and maintainability, integrating a variety of testing and code quality tools. It's based on Rails 8.0 and Ruby 3.4.
88

@@ -134,6 +134,26 @@ With `bundle exec rails code:analysis` you can run the code analysis tool, you c
134134
- [Rails Best Practices](https://github.com/flyerhzm/rails_best_practices#custom-configuration) Edit `config/rails_best_practices.yml`
135135
- [Brakeman](https://github.com/presidentbeef/brakeman) Run `brakeman -I` to generate `config/brakeman.ignore`
136136

137+
## Code quality and test coverage
138+
139+
The project uses SonarQube Community Edition to ensure code quality and monitor test coverage. The configuration can be found in `sonar-project.properties`.
140+
141+
To set up SonarQube:
142+
143+
1. Install SonarQube locally (see [CI documentation](docs/ci.md#setting-up-sonarqube) for details)
144+
2. Configure your environment variables:
145+
```bash
146+
export SONAR_TOKEN=your_token
147+
export SONAR_HOST_URL=http://localhost:9000
148+
```
149+
3. Run the analysis:
150+
```bash
151+
bundle exec rspec
152+
sonar-scanner
153+
```
154+
155+
For more details about the CI process and SonarQube setup, check the [CI documentation](docs/ci.md).
156+
137157
## More linters
138158
- [Hadolint](https://github.com/hadolint/hadolint) Install with `brew install hadolint` and run `hadolint Dockerfile*`. Edit `.hadolint.yml` to omit additional rules.
139159

@@ -148,12 +168,6 @@ See [Impersonation docs](./docs/impersonation.md) for more info
148168
In order to use [New Relic](https://newrelic.com) to monitor your application requests and metrics, you must setup `NEW_RELIC_API_KEY` and `NEW_RELIC_APP_NAME` environment variables.
149169
To obtain an API key you must create an account in the platform.
150170

151-
## Configuring Code Climate
152-
153-
1. After adding the project to CC, go to `Repo Settings`
154-
1. On the `Test Coverage` tab, copy the `Test Reporter ID`
155-
1. Set the current value of `CC_TEST_REPORTER_ID` in the [GitHub secrets and variables](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository)
156-
157171
## Code Owners
158172

159173
You can use [CODEOWNERS](https://help.github.com/en/articles/about-code-owners) file to define individuals or teams that are responsible for code in the repository.

docs/ci.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,36 @@
1-
# CI
1+
# Continuous Integration
2+
3+
This project uses GitHub Actions for continuous integration. The workflow is defined in `.github/workflows/ci.yml`.
4+
5+
## What's being tested and analyzed?
6+
7+
The CI process includes:
8+
1. Running all RSpec tests
9+
2. Running code style checks via RuboCop
10+
3. Running security checks via Brakeman
11+
4. Running best practices checks via Rails Best Practices
12+
5. Running code quality and test coverage analysis via SonarQube
13+
6. Checking for missing annotations
14+
7. Linting Dockerfiles
15+
8. Building Docker images
16+
9. Generating and updating API documentation
17+
18+
## CI Setup Requirements
19+
20+
### SonarCloud Configuration
21+
Create an account in [SonarCloud](https://sonarcloud.io) and create a new project
22+
Configure these secrets in your GitHub repository (Settings → Secrets and variables → Actions):
23+
- `SONAR_TOKEN`: Your SonarQube token
24+
- `SONAR_HOST_URL`: Your SonarQube server URL, default is https://sonarcloud.io
25+
Configure these properties in `sonar-project.properties`:
26+
- `sonar.projectKey`: Your SonarQube project key
27+
- `sonar.organization`: Your SonarQube organization
28+
29+
30+
The CI will automatically run tests, generate coverage reports, and upload results to SonarQube.
231

332
## Parallelization with Parallel Tests & Knapsack
33+
434
Knapsack and Parallel Tests gems allow us to run tests in several nodes at the same time, benefiting us in the execution time. Knapsack parallelizes them at node level while Parallel Tests does it at CPU level.
535

636
Knapsack splits tests based on an execution time report. In case there are files that were not added in the report, they will all run on the same node and may overload it, so it is strongly recommended to update the report frequently.

sonar-project.properties

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sonar.sources=.
2+
sonar.projectBaseDir=.
3+
sonar.projectKey=rootstrap_rails_api_base
4+
sonar.organization=rootstrap
5+
sonar.projectVersion=1.0.0
6+
sonar.sources=app,lib
7+
sonar.exclusions=app/**/*.js,lib/tasks/**/*.rake
8+
sonar.tests=spec
9+
sonar.test.inclusions=**/*_spec.rb
10+
sonar.ruby.coverage.reportPaths=${env.SONAR_REPORT_PATHS}
11+
sonar.qualitygate.wait=true
12+
sonar.scm.provider=git
13+
sonar.java.binaries=/tmp

spec/spec_helper.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
require 'shoulda/matchers'
1212
require 'pundit/rspec'
1313
require 'capybara/rspec'
14+
require 'simplecov_json_formatter'
1415

1516
Knapsack.tracker.config(enable_time_offset_warning: false)
1617
Knapsack::Adapters::RSpecAdapter.bind
@@ -68,3 +69,10 @@
6869
ActionMailer::Base.deliveries.clear
6970
end
7071
end
72+
73+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
74+
[
75+
SimpleCov::Formatter::JSONFormatter,
76+
SimpleCov::Formatter::HTMLFormatter
77+
]
78+
)

0 commit comments

Comments
 (0)