How to run Rubocop for Rails in GitHub Actions?

Learn how to set up Rubocop, a popular code linter for Ruby, in GitHub Actions to automatically keep your Rails project's codebase clean and consistent with best practices and style guidelines.

How to run Rubocop for Rails in GitHub Actions?
How to run Rubocop for Rails in GitHub Actions?

Rubocop is a popular code linter for Ruby, and it can be used to help keep your codebase clean and consistent.

GitHub Actions is a platform for automating software workflows, and it can be used to run Rubocop on your Rails project automatically. This is a great way to ensure that your code adheres to best practices and style guidelines. This blog post will explore how to set up Rubocop in GitHub Actions.

Setting up Rubocop

We need first to set up Rubocop in our rails code. So in Gemfile add two gems in the development group:

# Gemfile
group :development do
  gem 'rubocop', require: false
  gem 'rubocop-rails', require: false
  # Want to add rubocop to graphql api code?
  gem 'rubocop-graphql', require: false
  # Want to add rucocop to RSpec code?
  gem 'rubocop-rspec', require: false
end

Run bundle install to add the gems you need.

To generate the default configuration file for Rubocop, run the command bundle exec rubocop --auto-gen-config

This command will create a .rubocop_todo.yml file in your project's root directory. This file contains a list of all the cops (checks) that Rubocop can perform.

You can customize the generated configuration file to suit your project's needs. For example, you can change the severity of certain checks or disable them completely.

Now add the other cops to rubocop:

# .rubocop.yml
inherit_from: .rubocop_todo.yml
require:
  - rubocop-rails
  - rubocop-rspec
  - rubocop-graphql
AllCops:
  NewCops: enable
RSpec/FilePath:
  Enabled: false

This code is from a configuration file for the RuboCop linter, which is used to analyze and enforce style guidelines for Ruby code. The first line, inherit_from: .rubocop_todo.yml, indicates that the configuration in this file should be inherited from another configuration file, .rubocop_todo.yml.

The require section indicates which external RuboCop extensions should be loaded and used during linting. In this case, the extensions rubocop-rails, rubocop-rspec, and rubocop-graphql will be loaded and used.

The AllCops section defines settings that will be applied to all cops (the individual rules that RuboCop uses to check code). In this case, the setting "NewCops: enable" is defined, which tells RuboCop to enable any new cops that are added to the version of RuboCop being used.

The settings under the RSpec/FilePath sections define specific settings for those two individual cops. In this case, that cop is disabled by setting their respective Enabled settings to false.

Once you have customized the configuration file, you can run Rubocop on your code using the command bundle exec rubocop.

Writing the GitHub Workflow:

The next step is to write the workflow file for the action. This file should be named .github/workflows/rubocop.yml, and should contain the code for the action.

# .github/workflows/rubocop.yml
name: Rubocop

on:
  pull_request:
  # push:
  #   branches:
  #     - 'main'

jobs:
  build:
    name: CI Rubocop
    runs-on: ubuntu-latest
    env:
      api-dir: ./

    services:
      postgres:
        image: postgres
        ports: ["5432:5432"]
        env:
          POSTGRES_HOST_AUTH_METHOD: trust
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      
      redis:
        image: redis:alpine
        ports: ["6379:6379"]

    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2.0
          bundler-cache: true
      - name: Install PostgreSQL
        run: sudo apt-get -yqq install libpq-dev
      - name: Run bundle install
        working-directory: ${{env.api-dir}}
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3
      - name: Setup Database
        working-directory: ${{env.api-dir}}
        env:
          RAILS_ENV: test
          PGHOST: localhost
          PGUSER: postgres
        run: bin/rails db:create db:schema:load
      - name: Check Rubocop Styles
        working-directory: ${{env.api-dir}}
        env:
          RAILS_ENV: test
          PGHOST: localhost
          PGUSER: postgres
          RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
        run: bundle exec rubocop

This code is a GitHub Actions workflow that runs Rubocop on a pull request. It sets up a Ruby environment, installs PostgreSQL, runs bundle install, sets up the database, and then checks the code for style issues using Rubocop.

Go to GitHub repository settings; in the section “Security”, go to “Secrets and variables,” and in the dropdown, select “Actions”. Here enter a new secret RAILS_MASTER_KEY with the master.key of your rails app. GitHub will save that key encrypted and use it to set up the machine in actions.

Now commit and push the code to GitHub and as this action runs on a pull request, create a new pull request. and you will see GitHub action automatically stating. You can change the code on each push to the main, which is commented on in the above code.

In Repository settings and the section “Code and automation,” select “Branches”. I have added the rule that no one can push to the main branch and need a pull request. And pull requests cannot be merged unless all actions are passed. This type of rule confirms better coding practiced code in the main branch.


Happy Coding!

Contact me at sulman@hey.com.