GitHub Actions with more than 2 cores
Rails provides parallel testing out of the box but GitHub Actions only gives you 2 cores as standard. With Rails 8 planning to ship with GitHub CI files it's worthwhile learning how to use more cores when required. Especially as your app (and test suite) grow the time benefits of increasing your parallelization compound.
Requirements: in order to use larger runners you will need to be using paid GitHub teams or an enterprise plan. It's also worth noting that the free minutes you get do not apply to larger runners.
Create a GitHub-hosted runner
Visit your organization settings - github.com/organizations/{YOUR_ORGANIZATION}/settings/actions/runners}
and select New runner, followed by new GitHub-hosted runner.
Give your runner a name - it should be something simple as you will reference it in your GitHub workflows. You can leave everything else as default, but select the Runner size that meets your requiements. You can test how many cores work best for your suite and choose appropriately.
Use your new GitHub-hosted runner
Update your workflows to change the runs-on
parameter. This defaults to ubuntu-latest
which is the runner with 2 cores.
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: your_runner_name
services:
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Install packages
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable postgresql-client libpq-dev libvips
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Run Tests
env:
RAILS_ENV: test
DATABASE_URL: postgres://postgres:postgres@localhost:5432
run: bin/rails db:setup test test:system
For the other features of the default CI - namely Brakeman and Rubocop - you're worth leaving it on the default runner. They will not benefit from parallelization and you'll pay more for no reason.
Be sure to check the pricing for these runners but note that you are only charged for the time they are used - not when they are inactive.