From 6e58fd775e48dd2a09dc8e7fce490663b1fb5cd9 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Tue, 2 Jun 2026 09:58:37 -0700 Subject: [PATCH 1/3] Add Buildkite CI pipeline (Sorbet, Rubocop, tests) Adds a Buildkite pipeline mirroring the current GitHub Actions CI: Sorbet type-check, Rubocop, and the minitest suite across Ruby 3.3, 3.4, and 4.0. Each step runs in a Docker container built from Dockerfile.test (ripgrep installed for packwerk; Bundler pinned to 4.0.7 to match Gemfile.lock). The Gusto-internal gemstash mirror is left commented out so the image builds on public agents. Also simplifies the dependabot-tapioca workflow back to a plain push. Buildkite builds the RBI commit via its webhook integration regardless of the pushing credential, so the GITHUB_TOKEN recursion guard that previously left RBI commits without CI status no longer applies. --- .buildkite/docker-compose.yml | 23 +++++++++++++ .buildkite/pipeline.yml | 37 +++++++++++++++++++++ .github/workflows/dependabot-tapioca.yml | 10 +++--- Dockerfile.test | 41 ++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 .buildkite/docker-compose.yml create mode 100644 .buildkite/pipeline.yml create mode 100644 Dockerfile.test diff --git a/.buildkite/docker-compose.yml b/.buildkite/docker-compose.yml new file mode 100644 index 0000000..a9f4296 --- /dev/null +++ b/.buildkite/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3' +services: + app: + build: + context: ../ + dockerfile: Dockerfile.test + args: + # Overridden per-step via the RUBY_VERSION env var (see pipeline.yml's + # test matrix). Defaults to 3.4 for the Sorbet and Rubocop steps. + RUBY_VERSION: ${RUBY_VERSION:-3.4} + environment: + BUILDKITE: + BUILDKITE_AGENT_ACCESS_TOKEN: + BUILDKITE_BRANCH: + BUILDKITE_BUILD_ID: + BUILDKITE_BUILD_NUMBER: + BUILDKITE_BUILD_URL: + BUILDKITE_COMMIT: + BUILDKITE_JOB_ID: + BUILDKITE_PIPELINE_SLUG: + BUILDKITE_PULL_REQUEST: + BUILDKITE_PULL_REQUEST_BASE_BRANCH: + BUILDKITE_REPO: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 0000000..f98eb53 --- /dev/null +++ b/.buildkite/pipeline.yml @@ -0,0 +1,37 @@ +steps: + - name: ':sorbet: Sorbet' + command: bundle exec srb tc + plugins: + - docker-compose#v5.6.0: + run: app + config: .buildkite/docker-compose.yml + + - name: ':rubocop: Rubocop' + command: bundle exec rubocop + plugins: + - docker-compose#v5.6.0: + run: app + config: .buildkite/docker-compose.yml + + # Tests run against every supported Ruby (matches the gemspec's + # `required_ruby_version >= 3.3` and the old GitHub Actions matrix). The + # matrix value is exported as RUBY_VERSION so docker-compose builds the + # image on that Ruby (see the build arg in docker-compose.yml). + - name: ':minitest: Tests (Ruby {{matrix}})' + command: bundle exec rake test + env: + RUBY_VERSION: '{{matrix}}' + matrix: + - '3.3' + - '3.4' + - '4.0' + plugins: + - docker-compose#v5.6.0: + run: app + config: .buildkite/docker-compose.yml + +# NOTE: gem publishing is intentionally NOT handled here. It currently lives in +# .github/workflows/cd.yml. If you want releases to move to Buildkite too, add a +# `wait` + publish step modeled on danger-gusto's pipeline — that step needs the +# Gusto-internal `gemstash-publish` agent queue and the SSH token-generator +# plugin, so it only works once this pipeline runs on Gusto Buildkite agents. diff --git a/.github/workflows/dependabot-tapioca.yml b/.github/workflows/dependabot-tapioca.yml index 722a226..218a865 100644 --- a/.github/workflows/dependabot-tapioca.yml +++ b/.github/workflows/dependabot-tapioca.yml @@ -23,7 +23,7 @@ jobs: bundler-cache: true - name: Regenerate gem RBIs run: bundle exec tapioca gems - - name: Commit, push, and type-check updated RBIs + - name: Commit and push updated RBIs run: | if [[ -z "$(git status --porcelain sorbet/rbi)" ]]; then echo "No RBI changes to commit." @@ -33,7 +33,9 @@ jobs: git config user.email '41898282+github-actions[bot]@users.noreply.github.com' git add sorbet/rbi git commit -m "Regenerate gem RBIs [dependabot skip]" + # Buildkite builds this commit via its GitHub webhook integration + # regardless of the pushing credential, so Sorbet, Rubocop, and the + # tests all run against the RBI commit. (GitHub Actions would ignore + # a GITHUB_TOKEN push here — that recursion guard does not apply to + # Buildkite.) git push - # The push above uses GITHUB_TOKEN, which doesn't re-trigger CI. - # RBI changes only affect Sorbet, so type-check them here instead. - bundle exec srb tc diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000..738d244 --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,41 @@ +# Test image for the Buildkite pipeline. RUBY_VERSION is supplied as a build +# arg by .buildkite/docker-compose.yml (defaults to 3.4; the test matrix +# overrides it to 3.3 / 3.4 / 4.0). +ARG RUBY_VERSION=3.4 +FROM ruby:${RUBY_VERSION} + +# packwerk shells out to ripgrep to resolve files, so it must be on PATH. +RUN apt-get update && \ + apt-get install -y --no-install-recommends ripgrep && \ + rm -rf /var/lib/apt/lists/* + +# Set up the buildkite-agent user/group the docker-compose plugin runs as. +RUN groupadd -r buildkite-agent && \ + useradd -u 9999 -r -g buildkite-agent buildkite-agent && \ + mkdir -p /home/buildkite-agent + +ENV APP_HOME=/var/www +WORKDIR $APP_HOME + +# Pin Bundler to match Gemfile.lock's `BUNDLED WITH` so no version swap happens +# at runtime. `--default` replaces the base image's preinstalled Bundler. +ENV BUNDLER_VERSION=4.0.7 +RUN gem install bundler --version 4.0.7 --default + +# Gusto-internal gem mirror: uncomment ONLY when this pipeline runs on Gusto +# Buildkite agents that can reach gemstash. Leave commented for public agents, +# which install straight from rubygems.org. +# RUN bundle config --local "mirror.https://rubygems.org" "https://gemstash.zp-int.com" + +# Install dependencies first so the bundle layer caches across source changes. +# The gemspec hardcodes its version and globs files with Dir[...], so it loads +# fine with only the Gemfile and gemspec present. +COPY Gemfile* packwerk-extensions.gemspec $APP_HOME/ +RUN bundle install + +# Add the rest of the source now that dependencies are installed. +COPY . $APP_HOME + +RUN chown -R buildkite-agent:buildkite-agent $APP_HOME /home/buildkite-agent + +USER buildkite-agent From 4d812955857ddcace0773ae0f66eb23661b7a021 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 3 Jun 2026 10:02:58 -0700 Subject: [PATCH 2/3] Remove reference to private repo in pipeline comment --- .buildkite/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index f98eb53..3c663e9 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -32,6 +32,6 @@ steps: # NOTE: gem publishing is intentionally NOT handled here. It currently lives in # .github/workflows/cd.yml. If you want releases to move to Buildkite too, add a -# `wait` + publish step modeled on danger-gusto's pipeline — that step needs the -# Gusto-internal `gemstash-publish` agent queue and the SSH token-generator -# plugin, so it only works once this pipeline runs on Gusto Buildkite agents. +# `wait` + publish step — that step needs the Gusto-internal `gemstash-publish` +# agent queue and an SSH token-generator plugin, so it only works once this +# pipeline runs on Gusto Buildkite agents. From a6a81d0f512ce055703ea2167f336d602c4ee049 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 3 Jun 2026 10:04:55 -0700 Subject: [PATCH 3/3] Remove internal gem mirror references; use rubygems.org Public repo only uses public gems, so drop the commented-out internal mirror config and reword the publish note to not name internal infra. --- .buildkite/pipeline.yml | 7 +++---- Dockerfile.test | 5 ----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 3c663e9..094ff57 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -31,7 +31,6 @@ steps: config: .buildkite/docker-compose.yml # NOTE: gem publishing is intentionally NOT handled here. It currently lives in -# .github/workflows/cd.yml. If you want releases to move to Buildkite too, add a -# `wait` + publish step — that step needs the Gusto-internal `gemstash-publish` -# agent queue and an SSH token-generator plugin, so it only works once this -# pipeline runs on Gusto Buildkite agents. +# .github/workflows/cd.yml. Moving releases to Buildkite would require a +# `wait` + publish step with credentials available only on dedicated agents, +# so it is left out of this pipeline. diff --git a/Dockerfile.test b/Dockerfile.test index 738d244..c8e6bc2 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -22,11 +22,6 @@ WORKDIR $APP_HOME ENV BUNDLER_VERSION=4.0.7 RUN gem install bundler --version 4.0.7 --default -# Gusto-internal gem mirror: uncomment ONLY when this pipeline runs on Gusto -# Buildkite agents that can reach gemstash. Leave commented for public agents, -# which install straight from rubygems.org. -# RUN bundle config --local "mirror.https://rubygems.org" "https://gemstash.zp-int.com" - # Install dependencies first so the bundle layer caches across source changes. # The gemspec hardcodes its version and globs files with Dir[...], so it loads # fine with only the Gemfile and gemspec present.