Skip to content

Add GitHub Actions deploy workflow alongside CircleCI - #9884

Open
camd wants to merge 2 commits into
masterfrom
camd/github-actions-deploy
Open

camd wants to merge 2 commits into
masterfrom
camd/github-actions-deploy

Conversation

@camd

@camd camd commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Second step of the CircleCI to GitHub Actions migration, stacked on #9868. This PR adds .github/workflows/deploy.yml, which builds the production image and pushes it to Docker Hub and GCP Artifact Registry exactly as the CircleCI deploy job does today. .circleci/config.yml is still untouched; once this is switched on both systems publish the same tags side by side until cutover.

Ref Docker Hub tags Artifact Registry tags
master latest, master-<sha> latest, master-<sha>
prototype prototype-<sha> prototype-<sha>
tag vX.Y.Z vX.Y.Z vX.Y.Z
workflow_dispatch from any other branch dispatch-<sha> (only if push input is true) same

Design

  • Separate workflow from ci.yml. Keeps id-token: write and the registry credentials out of the workflow that runs on fork PRs. Nothing in ci.yml changed.
  • Safe to merge before the credentials exist. Push-triggered runs are gated on a DEPLOY_ENABLED repository variable (if: github.event_name == 'workflow_dispatch' || vars.DEPLOY_ENABLED == 'true'). Until it is set to true the job is skipped on every push to master/prototype/tags instead of failing at login. It also doubles as a kill switch: unset it to stop GitHub publishing without a code change.
  • workflow_dispatch dry run. Always runs regardless of the gate. The push input defaults to false. A dry run still creates version.json, computes the tag list, builds the image, logs in to Docker Hub and completes the GCP OIDC exchange, so every credential is exercised before anything is published. A dispatch from a branch other than master/prototype can never write a real tag; it uses dispatch-<sha>.
  • Deploy does not wait for tests. CircleCI runs deploy in parallel with the test jobs, so a red master still publishes. Preserved for parity; gating on a green CI run is a separate product decision.
  • GCP auth without gcloud. google-github-actions/auth (Workload Identity Federation, token_format: access_token) plus docker/login-action against the registry host, replacing the CircleCI gcp-cli orb and gcloud auth configure-docker.
  • Image build. docker/build-push-action with the same BuildKit type=gha cache that test-docker-build in ci.yml populates, so a master push mostly reuses layers from the PR's build.
  • version.json uses the GitHub equivalents of the CircleCI variables: GITHUB_SHA, GITHUB_REF_NAME when the ref is a tag, GITHUB_REPOSITORY, and the run URL as build.

Manual steps

All of these are outside the repo and need someone with the right access. None of them exist yet: as of 2026-09-22 gh secret list and gh variable list for mozilla/treeherder are both empty. The full walk-through with the source of truth for each value and the gcloud commands lives in the "Phase 2" section of #9868. The short version:

Kind Name Notes
Secret DOCKER_USER
Secret DOCKER_PASS Mint a new Docker Hub access token, Read & Write
Variable DOCKERHUB_REPO
Variable GCP_GAR_REGISTRY
Variable GCP_PROJECT_ID_OF_GCP_GAR
Variable GCP_WIP_PROJECT_NUMBER
Variable GCP_WIP_ID
Variable GCP_WIP_PROVIDER_ID The new GitHub provider
Variable GCP_GAR_PUSHER_SERVICE_ACCOUNT_EMAIL
Variable DEPLOY_ENABLED Set to true last, after the dry run passes

Plus, in GCP: add a GitHub OIDC provider (https://token.actions.githubusercontent.com, attribute condition assertion.repository == 'mozilla/treeherder') to the existing Workload Identity Pool and grant roles/iam.workloadIdentityUser on the pusher service account to that repository principal set.

Optional: a GitHub environment named deploy holding the Docker Hub secrets; the workflow has a commented-out environment: deploy line for it.

Verification plan

GitHub only accepts workflow_dispatch for a workflow that exists on the default branch (gh workflow run deploy.yml --ref camd/github-actions-deploy returns 404: workflow deploy.yml not found on the default branch), so nothing here can be exercised from this branch. The order is therefore:

  1. Merge this PR (after Add GitHub Actions CI workflow alongside CircleCI #9868). With DEPLOY_ENABLED unset, the deploy job shows as skipped on every push to master; nothing else changes.
  2. Admin sets the secrets, variables and GCP provider above, all except DEPLOY_ENABLED.
  3. Dry run: gh workflow run deploy.yml --repo mozilla/treeherder --ref master with push left false. Expected: version.json printed, tag list printed, image built, both logins green, nothing pushed. If any step fails, fix the value and re-run; nothing has been published.
  4. Switch on: gh variable set DEPLOY_ENABLED --repo mozilla/treeherder --body true.
  5. Push to prototype. CircleCI and GitHub both publish prototype-<sha> to both registries; confirm the digests match with docker buildx imagetools inspect. Double-publishing an identical tag is harmless.
  6. Next master merge. Confirm latest and master-<sha> in both registries and that the Kubernetes rollout behaves normally.
  7. First release tag in the window, if any.

Rollback at any point: unset DEPLOY_ENABLED. CircleCI is still the system of record until the cutover PR.

Notes for reviewers

  • actions/checkout, docker/setup-buildx-action and docker/build-push-action are pinned to the same majors as ci.yml so Dependabot bumps both files together. docker/login-action and google-github-actions/auth are new here and use their current majors.
  • No concurrency group on purpose: two quick pushes to master should both publish their master-<sha> tag.
  • Cutover (delete .circleci/, README badge, required status checks, rename builds to docs-and-linters) is the third PR.

@netlify

netlify Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for treeherder ready!

Name Link
🔨 Latest commit a089079
🔍 Latest deploy log https://app.netlify.com/projects/treeherder/deploys/6ace57cdfa11a56a39d1b98a
😎 Deploy Preview https://deploy-preview-9884--treeherder.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@camd
camd force-pushed the camd/github-actions-deploy branch from 59069de to 6b9ad4d Compare September 22, 2026 16:30
@codecov-commenter

codecov-commenter commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.17%. Comparing base (2f76ca7) to head (a089079).

Additional details and impacted files
@@                   Coverage Diff                    @@
##           camd/github-actions-ci    #9884    +/-   ##
========================================================
  Coverage                   70.17%   70.17%            
========================================================
  Files                         644      644            
  Lines                       39572    39572            
  Branches                     3469     3541    +72     
========================================================
  Hits                        27770    27770            
+ Misses                      11656    11415   -241     
- Partials                      146      387   +241     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@camd
camd force-pushed the camd/github-actions-ci branch from 79392b3 to bb89eb1 Compare October 1, 2026 16:11
@camd
camd force-pushed the camd/github-actions-deploy branch from 6b9ad4d to b28223c Compare October 1, 2026 16:11
@camd
camd force-pushed the camd/github-actions-ci branch from bb89eb1 to 27c350a Compare October 3, 2026 15:57
@camd
camd force-pushed the camd/github-actions-deploy branch from b28223c to 1268462 Compare October 3, 2026 15:57
@camd
camd force-pushed the camd/github-actions-ci branch from 27c350a to 03b59dc Compare October 6, 2026 17:23
@camd
camd force-pushed the camd/github-actions-deploy branch from 1268462 to d368902 Compare October 6, 2026 17:23
@camd
camd force-pushed the camd/github-actions-ci branch from 03b59dc to f9d4a03 Compare October 8, 2026 23:55
@camd
camd force-pushed the camd/github-actions-deploy branch from d368902 to 867f4c2 Compare October 8, 2026 23:55
@camd
camd force-pushed the camd/github-actions-ci branch from f9d4a03 to 510d6ed Compare October 11, 2026 17:57
@camd
camd force-pushed the camd/github-actions-deploy branch from 867f4c2 to dfe9878 Compare October 11, 2026 17:57
First step of migrating CI from CircleCI to GitHub Actions. This adds a
`ci.yml` workflow that mirrors every CircleCI job except `deploy`:

- javascript-tests, javascript-integration-tests, javascript-lint
- builds (docs + linters via tox)
- python-tests-{general,perf,frontend,telemetry} (tox docker envs)
- test-docker-build (BuildKit build of docker/Dockerfile, no push)

Job names match the CircleCI job names so required status checks can be
swapped one-for-one at cutover. A composite `setup-pnpm` action replaces
the CircleCI `setup-pnpm` command. Dependabot now also tracks action
versions.

CircleCI keeps running unchanged; it is removed in a later PR once the
two systems have run side by side and the deploy workflow is in place.
@camd
camd force-pushed the camd/github-actions-ci branch from 510d6ed to 2f76ca7 Compare October 13, 2026 16:09
Adds .github/workflows/deploy.yml, which builds the production image and
pushes it to Docker Hub and GCP Artifact Registry on pushes to master,
prototype and tags, mirroring the CircleCI deploy job.

Push-triggered runs are gated on a DEPLOY_ENABLED repository variable so
the workflow can land before the registry secrets and variables exist
without failing on every push. A workflow_dispatch trigger with a push
input (default false) always runs and allows a dry run that exercises
version.json, the build, the Docker Hub login and the GCP OIDC exchange
without publishing anything.

CircleCI is left untouched so both systems publish side by side until
cutover.
@camd
camd force-pushed the camd/github-actions-deploy branch from dfe9878 to a089079 Compare October 13, 2026 16:09
Base automatically changed from camd/github-actions-ci to master October 19, 2026 13:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants