Skip to content

6. CI/CD

Step 6 of the deployment sequence. Once the instance is up, wire CI/CD so a merge to main (dev) or a v* tag (prod) runs the same helm upgrade you ran by hand in step 3.

The repo ships five GitHub Actions workflows (ADR-0006 phases 2 & 3; the front-door pair is ADR-0009):

WorkflowFileTriggerPurpose
CI.github/workflows/ci.ymlPR + push to mainserver pytest + ruff, template-tools pytest + ruff, template-schema-in-sync
Validate templates.github/workflows/validate-templates.ymlPR touching deploy/charts/orchestra/files/templates/**per-file template validation with inline annotations
Deploy.github/workflows/deploy.ymlpush to main → dev, tag v* → prodbuild/push images + helm upgrade
Submission — validate.github/workflows/template-submission-validate.ymlworkshop-template issue opened/editedparse the issue form, validate it, and comment the result
Submission — convert.github/workflows/template-submission-convert.ymlapprove label added to a workshop-template issuerender the submission to YAML and open the PR (via a GitHub App)

Each workflow invokes the same just recipes developers run locally (lint-server, test-server, lint-template-tools, test-template-tools, check-schema) plus the helm flags from just deploy-gcp.

These will not work until the settings below are configured. None of the values are committed — set them in repo settings.

1. Workload Identity Federation (no JSON key)

Section titled “1. Workload Identity Federation (no JSON key)”

deploy.yml authenticates with google-github-actions/auth via OIDC. Create a Workload Identity Pool + provider bound to this repo, and a deploy service account with permission to push to Artifact Registry and run helm upgrade against the GKE cluster (roles/container.developer, roles/artifactregistry.writer, and access to the orchestra-system namespace).

Then set these as secrets (repo-level, or per-environment):

  • WIF_PROVIDER — full provider resource name, e.g. projects/<number>/locations/global/workloadIdentityPools/github/providers/orchestra
  • WIF_SERVICE_ACCOUNT — deploy SA email, e.g. orchestra-deployer@<project>.iam.gserviceaccount.com
  • GCP_VALUES_SECRETS — full contents of the gitignored deploy/gcp-values-secrets.yaml (OAuth client id/secret). The workflow writes it to disk so the 3-values-file helm upgrade matches just deploy-gcp, then deletes it.

And these as environment variables (set differently for the dev and prod environments):

  • GCP_PROJECT
  • GCP_REGION (e.g. us-central1)
  • GKE_CLUSTER (e.g. orchestra-dev)
  • GKE_LOCATION (cluster zone/region)
  • ARTIFACT_REGISTRY (e.g. us-central1-docker.pkg.dev/orchestraplatform-dev/orchestra)

The workflow leaves each of these as a # TODO: set <VAR> placeholder pointing here.

Create two environments (Settings → Environments):

  • dev — targeted by pushes to main. No approval needed.
  • prod — targeted by v* tags. Add a Required reviewers protection rule so prod deploys wait for manual approval. Optionally restrict deployment branches/tags to v*.

Attach the WIF/GCP_VALUES_SECRETS secrets and the GCP_*/GKE_* variables to each environment so dev and prod can differ.

3. Branch protection (required status checks)

Section titled “3. Branch protection (required status checks)”

On the main branch ruleset, require a pull request before merging and require these status checks to pass (names come from the CI job name: fields — every one runs on every PR):

  • server (pytest + ruff)
  • template-tools (pytest + ruff)
  • operator (pytest)
  • template schema in sync
  • frontend (eslint + tsc + vitest)
  • helm lint + render
  • generated client in sync

Do not require orchestra-validate-templates — it is path-filtered (runs only when template files change), so a PR that doesn’t touch templates never reports it, and a required check that never reports blocks the merge forever. Only ever require checks that run on every PR.

  • Single maintainer / automated merges (the orchestraplatform.org setup): require the PR + status checks above, but do not require approvals. A sole maintainer can’t approve their own PRs, and required approvals also block a merge-on-green automation flow. The status-check gate still guarantees nothing red lands. CODEOWNERS then auto-requests review (informational), it doesn’t block.
  • Multiple maintainers: additionally turn on Require review from Code Owners (activates .github/CODEOWNERS) so merged = reviewed is enforced. Community template contributions run through the front door (ADR-0009), so scope this to the template paths by keeping code owners only on deploy/charts/orchestra/files/templates/** and template-tools/**.

Leave “require branches to be up to date before merging” off unless merge traffic is high enough to need it — it forces a rebase per merge and adds friction to automated merges.

.github/CODEOWNERS references two org teams that must exist and have write access, or the ownership rules silently do nothing:

  • @orchestraplatform/maintainers — default owner.
  • @orchestraplatform/template-reviewers — owns deploy/charts/orchestra/files/templates/** and template-tools/**.