Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Local CI × GitHub Actions

Avatar for gogutan gogutan
October 15, 2026

Local CI × GitHub Actions

Hybrid CI That Plays to the Strengths of Both
Kaigi on Rails 2026 Day1

Avatar for gogutan

gogutan

October 15, 2026

More Decks by gogutan

Other Decks in Technology

Transcript

  1. Local CI × GitHub Actions Hybrid CI That Plays to

    the Strengths of Both @gogutan Kaigi on Rails 2026
  2. About me @gogutan Tech Lead @ Catal Inc. Hobbies: English,

    competitive programming (AtCoder), watching baseball, mahjong
  3. Catallog Learning management system for children studying English Students log

    their daily study on tablets and see their growth https://catal.jp/
  4. Another talk from our team Emiko Ando (@siroemk) Day 1,

    15:50–16:05 @ Lime Hall Modeling Catallog with our school staff, starting from Google Sheets
  5. Our CI took about 10 minutes • A Rails app

    with ~150 models, built by 8 engineers
  6. Our CI took about 10 minutes • A Rails app

    with ~150 models, built by 8 engineers • CI on GitHub Actions: ~10 min for every review request
  7. Our CI took about 10 minutes • A Rails app

    with ~150 models, built by 8 engineers • CI on GitHub Actions: ~10 min for every review request • AI costs are rising → we want to cut other SaaS costs
  8. Why not run CI on your own machine? • “Dev

    laptops are super fast these days. They're chronically underutilized. And you already own them.” — basecamp/gh-signoff https://github.com/basecamp/gh-signoff
  9. Not a replacement, but a hybrid • Even a modest

    laptop is fast enough fi • Local CI + GitHub Actions, each where it ts
  10. Not a replacement, but a hybrid • Even a modest

    laptop is fast enough • Local CI + GitHub Actions, each where it ts fi • After ~6 months: GitHub Actions runs halved (406 → 197/mo)
  11. Today • 1. Setting up Local CI • 2. Making

    it fast • 3. Using GitHub Actions alongside • 4. Should we unify on bin/ci?
  12. bin/ci and con g/ci.rb • Generated by rails new (Rails

    8.1) fi • bin/ci just loads config/ci.rb
  13. gh signo • Runs only when all steps pass f

    • Adds one green check, signoff, to the commit
  14. Make signo the only required check ff Using rulesets? gh

    signoff install sets this up for you
  15. But you could still sign o by hand # without

    running bin/ci… ff • $ gh signoff
  16. One signo for the whole CI • “A single signoff

    is all you need for most projects.” — basecamp/gh-signoff https://github.com/basecamp/gh-signoff ff • Easier to combine with GitHub Actions (later)
  17. ② + parallel_rspec • RSpec has no built-in parallelism •

    parallel_tests: 8 processes, 8 test databases
  18. 3 cases Local CI can't cover • 1. Merging to

    main: the last line of defense (it also triggers our staging build)
  19. 3 cases Local CI can't cover • 1. Merging to

    main: the last line of defense (it also triggers our staging build) • 2. Dependabot PRs: about 60 a month
  20. 3 cases Local CI can't cover • 1. Merging to

    main: the last line of defense (it also triggers our staging build) • 2. Dependabot PRs: about 60 a month • 3. Manual runs: when your machine is busy
  21. Keep the jobs, limit when they run • Push to

    main • Dependabot PRs • Manual runs
  22. cloud-ci-signo • Waits for the 5 jobs with needs f

    • Then sets signoff through the API
  23. Gotcha: skipped jobs count as success • “A job that

    is skipped will report its status as "Success". It will not prevent a pull request from merging, even if it is a required check.” — GitHub Docs fl fl https://docs.github.com/en/actions/how-tos/write-work ows/choose-when-work ows-run/control-jobs-with-conditions
  24. Don't name the job signo • Name it differently f

    • Set signoff explicitly, only on success
  25. Run bin/ci on GitHub Actions • The Rails docs say

    bin/ci can run in the cloud too • “…can be run either locally or in the cloud.” — Rails API docs https://api.rubyonrails.org/classes/ ActiveSupport/ContinuousIntegration.html • So we tried it
  26. Still, we keep them separate • Needs cloud-speci c tuning

    fi • Larger runners aren't covered by free minutes
  27. Still, we keep them separate • Needs cloud-speci c tuning

    • Larger runners aren't covered by free minutes fi • One job: harder to see what failed, no per-job re-runs
  28. Still, we keep them separate • Needs cloud-speci c tuning

    • Larger runners aren't covered by free minutes • One job: harder to see what failed, no per-job re-runs fi • → Not worth forcing them into one
  29. Summary • Local CI + gh signoff: 10m 39s →

    about 2 min • GitHub Actions covers the rest, all ending in one signoff
  30. Summary • Local CI + gh signoff: 10m 39s →

    about 2 min • GitHub Actions covers the rest, all ending in one signoff • Unifying on bin/ci is possible, but not worth forcing
  31. Provide sharp knives • “Ruby includes a lot of sharp

    knives in its drawer of features. Not by accident, but by design.” — The Rails Doctrine https://rubyonrails.org/doctrine#provide-sharp-knives
  32. Local CI is a sharp knife • Everyone gets the

    power to turn things green • No big problems so far
  33. Local CI is a sharp knife • Everyone gets the

    power to turn things green • No big problems so far • No more waiting 10 minutes after opening a PR