Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 18 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ permissions:

env:
RAILS_ENV: test
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
CI: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
Expand Down Expand Up @@ -132,11 +131,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Setup Code Climate test-reporter
run: |
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
- name: Let Rails generate the secret_key_base
run: bundle exec rails runner 'puts Rails.application.secret_key_base'
- name: Setup Database
Expand Down Expand Up @@ -164,13 +158,13 @@ jobs:
uses: rootstrap/check_untracked_changes@v1
with:
path: "./app/ ./spec/"
- name: Report to CodeClimate
run: ./cc-test-reporter format-coverage --output "coverage/coverage.${{ matrix.ci_node_index }}.json"
- name: Upload partial coverage
- name: Rename coverage files
run: mv coverage/coverage.json coverage/coverage-${{ matrix.ci_node_index }}.json
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage
path: "coverage/coverage.${{ matrix.ci_node_index }}.json"
name: "coverage-${{ matrix.ci_node_index }}"
path: coverage/coverage-${{ matrix.ci_node_index }}.json
- name: Merge API Docs from threads
env:
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
Expand All @@ -192,32 +186,27 @@ jobs:
with:
fetch-depth: 0
ssh-key: "${{ secrets.PUSH_KEY }}"
- name: Set ENV for CodeClimate
if: github.event_name == 'pull_request'
run: |
git fetch --no-tags --prune --depth=1 origin +refs/heads/$GITHUB_HEAD_REF:refs/remotes/origin/$GITHUB_HEAD_REF
echo "GIT_BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV
echo "GIT_COMMIT_SHA=$(git rev-parse origin/$GITHUB_HEAD_REF)" >> $GITHUB_ENV
echo "PULL_REQUEST_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
- name: Set ENV for API Docs
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
if [ $(git diff ${{ github.event.before }} ${{ github.event.after }} --name-only | grep 'spec/requests/api' | wc -l) -gt 0 ]; then
echo "OPENAPI=true" >> $GITHUB_ENV
fi
- name: Setup Code Climate test-reporter
run: |
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
- name: Download coverage reports
uses: actions/download-artifact@v5
- name: Download coverage report
uses: actions/download-artifact@v4
with:
name: coverage
path: coverage/coverage.*.json
- name: Report coverage
pattern: coverage-*
path: coverage/
merge-multiple: true
- name: Set ENV for SonarQube
run: |
./cc-test-reporter sum-coverage coverage/**/*.json
./cc-test-reporter upload-coverage
echo "SONAR_PROJECT_VERSION=$(echo $GITHUB_SHA | cut -c1-8)" >> $GITHUB_ENV
echo "SONAR_REPORT_PATHS=$(ls coverage/coverage-*.json | paste -sd "," -)" >> $GITHUB_ENV
- name: SonarQube Scanner
uses: sonarsource/[email protected]
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- name: Enable Corepack
run: corepack enable
- name: Setup Node
Expand Down
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Rails API Template

[![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)
[![Code Climate](https://codeclimate.com/github/rootstrap/rails_api_base/badges/gpa.svg)](https://codeclimate.com/github/rootstrap/rails_api_base)
[![Test Coverage](https://api.codeclimate.com/v1/badges/63de7f82c79f5fe82f46/test_coverage)](https://codeclimate.com/github/rootstrap/rails_api_base/test_coverage)
[![Quality Gate Status](${SONAR_HOST_URL}/api/project_badges/measure?project=rails-api-base&metric=alert_status)](${SONAR_HOST_URL}/dashboard?id=rails-api-base)
[![Coverage](${SONAR_HOST_URL}/api/project_badges/measure?project=rails-api-base&metric=coverage)](${SONAR_HOST_URL}/dashboard?id=rails-api-base)

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.

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

## Code quality and test coverage

The project uses SonarQube Community Edition to ensure code quality and monitor test coverage. The configuration can be found in `sonar-project.properties`.

To set up SonarQube:

1. Install SonarQube locally (see [CI documentation](docs/ci.md#setting-up-sonarqube) for details)
2. Configure your environment variables:
```bash
export SONAR_TOKEN=your_token
export SONAR_HOST_URL=http://localhost:9000
```
3. Run the analysis:
```bash
bundle exec rspec
sonar-scanner
```

For more details about the CI process and SonarQube setup, check the [CI documentation](docs/ci.md).

## More linters
- [Hadolint](https://github.com/hadolint/hadolint) Install with `brew install hadolint` and run `hadolint Dockerfile*`. Edit `.hadolint.yml` to omit additional rules.

Expand All @@ -148,12 +168,6 @@ See [Impersonation docs](./docs/impersonation.md) for more info
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.
To obtain an API key you must create an account in the platform.

## Configuring Code Climate

1. After adding the project to CC, go to `Repo Settings`
1. On the `Test Coverage` tab, copy the `Test Reporter ID`
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)

## Code Owners

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.
Expand Down
27 changes: 26 additions & 1 deletion docs/ci.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
# CI
# Continuous Integration

This project uses GitHub Actions for continuous integration. The workflow is defined in `.github/workflows/ci.yml`.

## What's being tested and analyzed?

The CI process includes:
1. Running all RSpec tests
2. Running code style checks via RuboCop
3. Running security checks via Brakeman
4. Running best practices checks via Rails Best Practices
5. Running code quality and test coverage analysis via SonarQube
6. Checking for missing annotations
7. Linting Dockerfiles
8. Building Docker images
9. Generating and updating API documentation

## CI Setup Requirements

### SonarQube Configuration
Configure these secrets in your GitHub repository (Settings → Secrets and variables → Actions):
- `SONAR_TOKEN`: Your SonarQube token
- `SONAR_HOST_URL`: Your SonarQube server URL

The CI will automatically run tests, generate coverage reports, and upload results to SonarQube.

## Parallelization with Parallel Tests & Knapsack

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.

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.
Expand Down
5 changes: 5 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sonar.sources=.
sonar.projectBaseDir=.
sonar.projectKey=PROJECT_KEY
sonar.token=PROJECT_TOKEN
sonar.projectVersion=1.0.0
8 changes: 8 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require 'shoulda/matchers'
require 'pundit/rspec'
require 'capybara/rspec'
require 'simplecov_json_formatter'

Knapsack.tracker.config(enable_time_offset_warning: false)
Knapsack::Adapters::RSpecAdapter.bind
Expand Down Expand Up @@ -68,3 +69,10 @@
ActionMailer::Base.deliveries.clear
end
end

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
[
SimpleCov::Formatter::JSONFormatter,
SimpleCov::Formatter::HTMLFormatter
]
)
Loading