GitHub Actions

GitHub recently introduced their own CI solution called GitHub Actions. I got access to the beta and decided to test it with Rails, Postgres and Rspec. It’s totally free for public repositories and you receive 2000 free minutes per month for private repositories!

TL;DR: the code.

Step 1

Create .github/workflows/ci.yml in the root directory of your repository.

Step 2

Use the ubuntu-latest image to install the necessary libraries and postgresql as database. This action will be executed on a pull request. See here for more options.

# .github/workflows/ci.yml

name: CI
on: [pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

Step 3

Checkout the repository from GitHub with an external action:

# .github/workflows/ci.yml

    ...

    steps:
      - uses: actions/[email protected]

Step 4

Setup Ruby 2.5.5 with an external action:

# .github/workflows/ci.yml
      
      ...

      - uses: actions/[email protected]
        with:
          ruby-version: 2.5.5

Step 5

Install the dependent libraries for Postgres:

# .github/workflows/ci.yml

      ...

      - name: Install dependent libraries
        run: sudo apt-get install libpq-dev

Step 6

Install Bundler and bundle install:

# .github/workflows/ci.yml

      ...

      - name: Bundle install
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3

Step 7

Create config/database.yml.github-actions with the following content:

test:
  adapter: postgresql
  host: localhost
  encoding: unicode
  database: github-actions
  pool: 20
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>

Step 8

Setup the database by copying database.yml.github-actions to database.yml and load the schema:

# .github/workflows/ci.yml

      ...

      - name: Setup Database
        run: |
          cp config/database.yml.github-actions config/database.yml
          bundle exec rake db:create
          bundle exec rake db:schema:load
        env:
          RAILS_ENV: test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres

Step 9

And finally run the tests:

# .github/workflows/ci.yml

      ...

      - name: Run RSpec
        run: COVERAGE=true bundle exec rspec  --require rails_helper
        env:
          RAILS_ENV: test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres

Step 10

Create a new pull request and tests will start running automatically. If all tests succeed: merge pull request!

GitHub Actions PR

Putting it al together

# .github/workflows/ci.yml

name: CI
on: [pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/[email protected]

      - uses: actions/[email protected]
        with:
          ruby-version: 2.5.5

      - name: Install dependent libraries
        run: sudo apt-get install libpq-dev

      - name: Bundle install
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3

      - name: Setup Database
        run: |
          cp config/database.yml.github-actions config/database.yml
          bundle exec rake db:create
          bundle exec rake db:schema:load
        env:
          RAILS_ENV: test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres

      - name: Run RSpec
        run: COVERAGE=true bundle exec rspec  --require rails_helper
        env:
          RAILS_ENV: test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
# config/database.yml.github-actions

test:
  adapter: postgresql
  host: localhost
  encoding: unicode
  database: github-actions
  pool: 20
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>