CI workflow (rubocop/rubocop)
The CI workflow from rubocop/rubocop, explained and optimized by Latchkey.
CI health: B - good
Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the CI workflow from the rubocop/rubocop repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: CI
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
permissions: # added using https://github.com/step-security/secure-workflows
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
spec-ubuntu:
name: Spec - ubuntu ${{ matrix.ruby }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0', 'head']
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Check requiring libraries successfully
# See https://github.com/rubocop/rubocop/pull/4523#issuecomment-309136113
run: ruby -I lib -r bundler/setup -r rubocop -e 'exit 0'
- name: spec
env:
CI_RUBY_VERSION: ${{ matrix.ruby }}
STRICT_WARNINGS: 1
run: bundle exec rake spec
spec-jruby:
name: Spec - JRuby
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
ruby-version: 'jruby' # Latest stable JRuby version
bundler-cache: true
- name: spec
run: bundle exec rake spec
spec-windows:
needs: spec-ubuntu # Don't spend CI resources on slow Windows specs if CI won't pass anyway.
name: Spec - windows ${{ matrix.ruby }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
ruby:
- '2.7' # Oldest supported version
- 'ruby' # Latest stable CRuby version
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Check requiring libraries successfully
# See https://github.com/rubocop/rubocop/pull/4523#issuecomment-309136113
run: ruby -I lib -r bundler/setup -r rubocop -e 'exit 0'
- name: spec
env:
CI_RUBY_VERSION: ${{ matrix.ruby }}
run: bundle exec rake spec
ascii_spec:
name: Ascii Spec - ${{ matrix.os }} ${{ matrix.ruby }}
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, windows]
ruby:
- '2.7' # Oldest supported version
- 'ruby' # Latest stable CRuby version
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: ascii_spec
env:
CI_RUBY_VERSION: ${{ matrix.ruby }}
run: bundle exec rake ascii_spec
documentation_check:
name: Documentation Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
ruby-version: ruby # Latest stable CRuby version
bundler-cache: true
- name: Check documentation syntax
run: bundle exec rake documentation_syntax_check
prism:
runs-on: ubuntu-latest
name: Prism
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
with:
# Specify the minimum Ruby version 2.7 required for Prism to run.
ruby-version: 2.7
bundler-cache: true
- name: spec
env:
PARSER_ENGINE: parser_prism
run: bundle exec rake prism_spec
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: CI on: push: branches: - master pull_request: workflow_dispatch: permissions: # added using https://github.com/step-security/secure-workflows contents: read concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: spec-ubuntu: timeout-minutes: 30 name: Spec - ubuntu ${{ matrix.ruby }} runs-on: latchkey-small strategy: fail-fast: false matrix: ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0', 'head'] steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Check requiring libraries successfully # See https://github.com/rubocop/rubocop/pull/4523#issuecomment-309136113 run: ruby -I lib -r bundler/setup -r rubocop -e 'exit 0' - name: spec env: CI_RUBY_VERSION: ${{ matrix.ruby }} STRICT_WARNINGS: 1 run: bundle exec rake spec spec-jruby: timeout-minutes: 30 name: Spec - JRuby runs-on: latchkey-small steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: ruby-version: 'jruby' # Latest stable JRuby version bundler-cache: true - name: spec run: bundle exec rake spec spec-windows: timeout-minutes: 30 needs: spec-ubuntu # Don't spend CI resources on slow Windows specs if CI won't pass anyway. name: Spec - windows ${{ matrix.ruby }} runs-on: windows-latest strategy: fail-fast: false matrix: ruby: - '2.7' # Oldest supported version - 'ruby' # Latest stable CRuby version steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Check requiring libraries successfully # See https://github.com/rubocop/rubocop/pull/4523#issuecomment-309136113 run: ruby -I lib -r bundler/setup -r rubocop -e 'exit 0' - name: spec env: CI_RUBY_VERSION: ${{ matrix.ruby }} run: bundle exec rake spec ascii_spec: timeout-minutes: 30 name: Ascii Spec - ${{ matrix.os }} ${{ matrix.ruby }} runs-on: ${{ matrix.os }}-latest strategy: fail-fast: false matrix: os: [ubuntu, windows] ruby: - '2.7' # Oldest supported version - 'ruby' # Latest stable CRuby version steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: ascii_spec env: CI_RUBY_VERSION: ${{ matrix.ruby }} run: bundle exec rake ascii_spec documentation_check: timeout-minutes: 30 name: Documentation Check runs-on: latchkey-small steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: ruby-version: ruby # Latest stable CRuby version bundler-cache: true - name: Check documentation syntax run: bundle exec rake documentation_syntax_check prism: timeout-minutes: 30 runs-on: latchkey-small name: Prism steps: - uses: actions/checkout@v7 - uses: ruby/setup-ruby@v1 with: # Specify the minimum Ruby version 2.7 required for Prism to run. ruby-version: 2.7 bundler-cache: true - name: spec env: PARSER_ENGINE: parser_prism run: bundle exec rake prism_spec
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 6 jobs (17 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.