Skip to content

Queued CI/CD

A shared CI/CD model used by Arda’s content and frontend repositories. Combines GitHub’s native merge queue, a PR-body changelog convention with post-merge assembly, and a path-scoped reviewer policy. The model lets multiple approved PRs land concurrently without rebase churn while keeping main consistent with what’s been built and deployed.

Adopt this model in a repository when two or more of the following apply:

  • Multiple authors commit frequently and want to merge in parallel.
  • The repository owns a release artifact (Pages site, npm package, docker image) that is tagged + deployed automatically.
  • The release notes are part of the artifact (a CHANGELOG.md file or equivalent).
  • The release version is computed mechanically from the change’s nature (semver) rather than chosen by the author.

documentation and arda-frontend-app both satisfy these.

Five workflow groups participate in every adopting repository:

  1. changelog-check — required status check. On pull_request it (a) rejects diffs that touch CHANGELOG.md and (b) validates that the PR body contains a ## CHANGELOG section with valid categories. On merge_group it auto-passes.
  2. review-required-gate — required status check. Passes when the PR is not labelled REVIEW-REQUIRED, or when the label is present and an approving review from a human (non-bot) account exists.
  3. Preview build + deploy — runs on pull_request. Builds the artifact with a preview-only base path and publishes to a per-PR preview environment so reviewers see live content.
  4. changelog-assembly — runs on push: branches: [main] from a merge commit. Reads the merged PR’s body, computes the next semver from the categories used, prepends a release block to CHANGELOG.md, validates with clq, commits with chore: assemble CHANGELOG x.y.z, creates the git tag, and creates the GitHub Release. Pushes via an installation token from a dedicated GitHub App so no human bypass is needed.
  5. Production build + deploy — runs on push: branches: [main] when the head commit is an assembly commit (title starts with chore: assemble CHANGELOG ). Builds with the production base path and publishes to the production environment.

Branch-protection ruleset gates:

  • required_approving_review_count: 0
  • require_code_owner_review: true (CODEOWNERS file decides per-path approval requirements)
  • required_status_checks: [changelog-check, review-required-gate]
  • merge_queue rule enabled with grouping_strategy: ALLGREEN
  • strict_required_status_checks_policy: false (the queue supplies up-to-date check results)
  • Bypass list contains only the App (no human bypass; emergency fixes still go through PR)

The diagram traces a PR end-to-end across four swimlanes: the author opens a PR, the Pre-Queue stage runs the required checks and merge-eligibility decisions and ends with a preview-site publish, the Merge queue re-runs the cheap gates and merges with the repo’s configured merge method, the Post-Merge lane shows the two successive push events (merge commit triggers changelog-assembly; assembly commit triggers production build + deploy), and the Org repo lane shows the cross-repo deploy (where applicable — see per-repo variance below).

PlantUML diagram

The release-engineering identity: arda-changelog-bot

Section titled “The release-engineering identity: arda-changelog-bot”

A GitHub App owned by the Arda-cards organisation. Acts as the sole bypass actor on each adopting repository’s branch-protection ruleset, so post-merge assembly commits push directly to main without granting any human bypass.

Permissions: Contents: write, Pull requests: read, Metadata: read. Webhook inactive (the App is an identity, not an event handler).

Credentials are exposed via two org-level Actions secrets, CHANGELOG_BOT_APP_ID and CHANGELOG_BOT_PRIVATE_KEY, scoped to the repositories that use them. Workflows mint short-lived (1-hour) installation tokens with actions/create-github-app-token@v2.

The private-key backup lives in 1Password vault Arda-SystemsOAM. For App rotation and operational details, see the repo-local knowledge-base/arda-changelog-bot.md notes in any adopting repository.

The model is intentionally uniform, but two settings can legitimately vary per repo: the merge method and the bypass list of the ruleset. Other variations are accidents of history and will normalise to the shared model over time.

  • Status: live (canonical implementation of this model).
  • Merge method: MERGE — author commit history is preserved on main.
  • CODEOWNERS: * @Arda-cards/engineering with an exception for /src/content/docs/roadmap/ (unowned, no review required). Roadmap edits can be merged by the author once checks pass.
  • Queue parameters: max_entries_to_build: 2, max_entries_to_merge: 3, check_response_timeout_minutes: 15.
  • Bypass list: arda-changelog-bot App only. No human bypass.
  • Production deploy: cross-repo dispatch to Arda-cards/Arda-cards.github.io, which publishes to the production site at https://arda-cards.github.io/. Preview site is the documentation repo’s own Pages at https://arda-cards.github.io/documentation/.
  • Status: partial — uses merge queue + PR-body changelogs + post-merge assembly today, but with a different bot identity (a personal-access token, CHANGELOG_ASSEMBLY_TOKEN) and a broader bypass list. Full alignment is tracked as a follow-up project under “Architecture Runway / Improvements” in Linear.
  • Merge method: SQUASH — by repo convention; not changed by the migration.
  • CODEOWNERS: present; details out of scope here.
  • Queue parameters: max_entries_to_build: 3, max_entries_to_merge: 5, check_response_timeout_minutes: 30.
  • Bypass list (current): RepositoryRole 5 (write), mode always. Will be replaced with the arda-changelog-bot App only when the migration ticket lands.
  • Production deploy: handled by the repo’s own deploy.yaml workflow (no cross-repo dispatch).
Settingdocumentationarda-frontend-app
merge_methodMERGESQUASH
max_entries_to_build23
max_entries_to_merge35
check_response_timeout_minutes1530
Production deploy pathCross-repo dispatchIn-repo workflow
Preview deploy URLarda-cards.github.io/documentation/(per-PR Vercel preview)
Bypass listApp onlyApp only (post-migration)
  • Use the repo’s PR template — the ## CHANGELOG section is pre-filled with category placeholders.
  • Pick the highest-priority category that applies (major > minor > patch).
  • Do not edit CHANGELOG.md. If you accidentally do, changelog-check will reject the PR; remove the edit (or add the manual-changelog label if you genuinely need a hand-edit).

Post a comment on the PR with an updated ## CHANGELOG block. Last one wins.

Add the REVIEW-REQUIRED label. review-required-gate fails until a human approves; once approved, the gate remains passing on subsequent pushes (approvals do not get dismissed by new commits — the repo trusts authors to flag material-scope changes).

Enable auto-merge on each PR. The queue groups passing entries into ALLGREEN batches; the batch merges together. If two PRs would have conflicted on CHANGELOG.md under the old model, they no longer can — PRs never touch CHANGELOG.md, so the queue can batch them.

Apply the manual-changelog label to the PR. changelog-check allows the edit, and the assembly workflow notices the hand-edit on merge and skips assembly for that commit.

Open a PR. Both gates (changelog-check, review-required-gate) must still pass; the only acceleration available is a fast-tracked engineering review. There is no human bypass.

  • knowledge-base/pr-body-changelog.md (repo-local) — detailed authoring rules.
  • knowledge-base/arda-changelog-bot.md (repo-local) — App identity, secrets, rotation.
  • Source design documents: docs-process-improvement project under projects/ — includes the original design rationale.