At Truemark, we are constantly looking to improve the code quality in our projects. And one way to do that is through the regular code review process. The code review process can quickly get exhausting if team members have to spend the majority of their time on maintaining best practices.
Enters automated code review; which reviews source code for compliance with a predefined set of rules and best practices.
In Rails projects, to define rules and best practices, we use RuboCop and for code reviews, we will be using Pronto integrated with Gitlab CI.
Pronto is a gem that uses the RuboCop configuration file to perform analysis on changes made in the given feature branch and adds a comment to merge requests based on the best practices configured. Pronto can be integrated with popular version control system managers like Gitlab. Github and Bitbucket.
It also works on the local machine and is perfect if you want to find out quickly if a branch introduces changes that conform to your style guide (rules configuration file), is DRY, and doesn’t introduce security holes.
Short answer, for automating the code review process so your team doesn’t have to manually comment and make sure that every team member is following the best practices.
Every developer has their own belief on the best practices and styles, for e.g. some want to use single quotes whereas others prefer double-quotes. Some love using semicolons, others just think it’s unnecessary. This can brew conflict in the team when teammates are reviewing merge requests, hence we let Pronto do this.
Best practices and style guides can first be setup by the team and Pronto makes sure that every member is adhering to those rules.
- RuboCop has been configured in the app, i.e. .rubocop.yml exists in the project
- Add the following to development, test group
group :development, :test do gem 'pronto' gem 'pronto-rubocop', require: false gem 'pronto-flay', require: false end
- From the command line, run
- Add specific version for the installed GemsAfter bundle install, go to your Gemfile.lock and search for the installed gem version and update the Gemfile with that version
group :development, :test do gem 'pronto', '~> 0.11.0' gem 'pronto-rubocop', '~> 0.11.1', require: false gem 'pronto-flay', '~> 0.11.0', require: false end
Create .gitlab-ci.yml in the root project and add the following:
image: ruby:3.0.0 # this should be the ruby version that your rails app is using, ours was using 3.0.0 before_script: - apt-get update && apt-get install -y cmake # Install cmake needed for pronto - bundle install # install all packages in the Gemfile - git fetch origin # fetch all branches, was throwing Rugged::ReferenceError, you can remove this and try if it works for you stages: - lint # we are only formatting/linting the changes pronto: stage: lint # runs pronto on the lint stage only: - merge_requests # run pronto only on merge requests (also runs when new changes are pushed to the merge request) script: - PRONTO_GITLAB_API_PRIVATE_TOKEN=$PRONTO_ACCESS_TOKEN bundle exec pronto run -f gitlab_mr -c origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME # Run pronto on branch of current merge request
$PRONTO_ACCESS_TOKENshould be configured in GitLab which is explained in the steps below.
$CI_MERGE_REQUEST_TARGET_BRANCH_NAMEis the predefined Gitlab CI variable that returns the branch name of the current merge request. You can read more about the predefined Gitlab CI variables here.
- In Gitlab, after login, go to personal access token
- Enter a name and optional expiry date for the token.
- In scopes, choose the only API, it is enough for our purpose as it gives all access to the project via Gitlab API.
- Click on Create token
- Copy the token and keep it somewhere safe, we will need this in the next step.
Reference: Official documentation
To use the Personal Access Token (
$PRONTO_ACCESS_TOKEN) in our Gitlab CI, we should set it up as a custom variable in settings inside CI/CD.
NOTE: Only project members with maintainer permissions can add or update project CI/CD variables, so make sure you have the correct access.
- Go to your project
- From the left menu, in Settings; choose the CI/CD
- Expand Variables Section
- Click on Add Variable
- In Key, add
PRONTO_ACCESS_TOKENas that is what we have configured in our .gitlab-ci.yml file. You can use any key name, just make sure to update it inside .gilab-ci.yml.
- In Value, add the token generated in the previous step
- In Flags section, uncheck Protect variable, checking this option will export the variable (
PRONTO_ACCESS_TOKEN) only for protected branches like master/main. But we need this variable inside all merge request branches.
- Check Mask variable so our token value is not visible in the CI job logs.
- Click on Add variable
Reference: Official documentation
- Run against master
- Run against other branches
pronto run -c branch-name
- Commit the changes made in the branch and push the code to Gitlab
- You should see Gitlab CI running automatically now and it should pass
- If Pronto finds any issues after analyzing the codes changed in the merge request, it will post those issues as comments in that merge request.
NOTE: Sometimes it throws Reference::RuggedError due to missing git branch, retry running the job in that case and it should work the second time.
If you are curious and want to see what is happening in the background, you can check the Gitlab CI Job log.
- From the left menu inside the project, hover over CI/CD and click on Jobs
- To view the log, click on job id in the Job column which starts with #, for e.g. #1290157388
Due to the installation of all gems (
bundle install) in the project, it can take up to 3 minutes for the job to be completed even when there are not many changes.
The main reason for writing this article was because I couldn’t find a decent article explaining exactly what we should do to integrate Pronto in Gitlab. The integration guide for Pronto in official documentation was not clear enough to guide us on what exactly to do for integrating Pronto with Gitlab CI.
We were able to find some blogs, and the majority of them were using Docker or were Github integrations, it took a while for the team to figure this solution out. Now, this blog should save your team’s time when you are using Pronto with Gitlab Ci in your projects. Good luck!
Thank you for reading. See you in the next blog.