Pronto, Codeship and GitHub for automatic code review

Wouldn’t it be nice if pronto posted its output as comments directly at relevant commits on GitHub, like this?Pronto is an automatic code review ruby gem. Behind the scenes, it runs some other code review tools like: rubocop, reek and flay. It can be run against a set of recent commits, so you can focus on the most recent aggressions to code quality. Particularly useful to check pull requests’ health. Pronto outputs through its formatters. There’s 3 specific formatters that are capable of communicating with GitHub: github, github_status and github_pr. Although the examples below are from a Rails application, one can easily adapt them to a plain ruby script or another ruby framework.

Pronto locally

First, you need to make sure pronto is ready and running. You can see install instructions at pronto github repository. You should choose what runners to enable and could further tailor them to your needs through their own config files (eg: Rubocop and .rubocop.yml). We have used bundler Gemfile to do that.

Gemfile example for pronto at Rails

Ruby

1

2

3

4

5

6

7

8

9

10

11

12

13

# Code Review

group:development,:testdo

gem'pronto',require:false

gem'pronto-rubocop',require:false

gem'pronto-brakeman',require:false

gem'pronto-eslint',require:false

gem'pronto-jshint',require:false

gem'pronto-poper',require:false

gem'pronto-rails_best_practices',require:false

gem'pronto-reek',require:false

gem'pronto-scss',require:false

gem'pronto-flay',require:false

end

After a bundle install we can check if pronto is working as expected. At our project we use develop branch to do releases to the staging (test) server. Then we merge into master branch to deploy to production server. So, if we want to work on a feature and make pronto check the code for us, we would do something like:

Interactive session

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# Create a feature branch to work on

git checkout-bfeature_branch_name

# Commit some code and advance feature branch tip/head

# Do some style aggression so you can see pronto's output.

# (eg: a commit message starting with lowcase letter)

git commit-a-m"fix this or that"

# Now check it against the target branch (develop)

pronto run-cdevelop

# Pronto's poper runner (pronto-poper) should output

# something like:

#

# 155f950 W: Git commit message should start with a capital letter

Pronto will walk from feature branch head until it finds the target commit and will analyze all of those commits from HEAD to it. If pronto was correctly installed it will output any warnings from the runners selected, see example above.

Integrate with GitHub

Now that everything is checked we need a way to communicate with GitHub. Pronto’s github formatters can do this through an access token. Each access token is related to a specific GitHub user account and the comments will appear as if they were written by that GitHub user. So, we prefer to have a bot account specific to this job. So, create a regular GitHub account with a pretty descriptive name. You can also give him a good profile picture. See https://github.com/gomedicalbot.

Don’t forget to grant the bot push access to the repositories you want it to write to. At the repository page go Settings -> Collaborators and invite the bot account. And, make sure you receive and confirm the invite e-mail.

Now, be sure you’re logged in as your bot (not your personal account). Go to Settings -> Personal access tokens. Generate a new token with a good descriptive name. Copy the generated token as it will never show again after disappearing. If you didn’t take note, don’t worry, just generate another one.

You can use a .pronto.yml file to provide defaults to pronto. We have used something around these lines (see pronto README.md for details):

.pronto.yml

YAML

1

2

3

4

5

6

7

github:

slug: user/repository # e.g.: abinoam/highline

access_token: <%=ENV['PRONTO_GITHUB_ACCESS_TOKEN']%>

api_endpoint: https://api.github.com/

web_endpoint: https://github.com/

max_warnings: 150

verbose: true

To make pronto communicate with GitHub we have to provide the token as PRONTO_GITHUB_ACCESS_TOKEN environment variable and use one of the github formatters:

Congratulations, you should be viewing pronto warnings directly at the GitHub commits.

Integrate with Codeship

At Codeship, you should export the PRONTO_GITHUB_ACCESS_TOKEN environment variable at Project Settings -> Environment menu. This will make it easier to reconfigure later without changing other test configurations.

Now you just need to add the pronto command to your test pipeline (Configure Test Pipelines). At this step I’ve had a hard time figuring out why pronto kept raising Rugged::OdbError: Object not found - no match for id .... Having a look at how Codeship prepares the build made me figure it out. The problem comes from the way the repo is fetched with --depth 50. So, it’s a shallow repository without the complete history. This makes pronto fail to traverse it. To fix this, we have to fetch with --unshallow option set populating the local branch against which we want pronto to be run. Easy like the snippet bellow.

Codeship test commands snippet

Shell

1

2

git fetch origin develop:develop--unshallow

pronto run-fgithub github_status-cdevelop

Now every time a commit is pushed to GitHub, Codeship will run a build. This build will run pronto code review tool which will post any warnings directly on GitHub.