Repository navigation
ci: adopt a staging branch as integration gate for all PRs with auto-release on main merge #44
Copy link
Copy link
Open
Labels
area:ciWorkflows, dependabot, toolingWorkflows, dependabot, toolingdependenciesDependency updates (used by Dependabot)Dependency updates (used by Dependabot)status:blockedBlocked by an external dependency (TS, upstream)Blocked by an external dependency (TS, upstream)
Description
Problem
Today, every PR — whether Dependabot or a developer contribution — is merged directly onto main. This creates friction:
- Every merge triggers a CI run on main, even for WIP or draft contributions
- Release cadence is decoupled from development — no consolidated view of what is about to ship
- No integration step to catch cross-package conflicts before shipping
- Developers must coordinate merges to avoid stepping on each other on main
Solution
Adopt a staging branch model for all contributions (flat):
feat/xyz PR ─┐
fix/abc PR ─┼──► staging ──► main (release)
dep PRs ─┘
All PRs (dev + Dependabot) target staging directly. main is never the target of a PR.
- Staging is an accumulation and integration branch — never a working branch
- Each dev opens one PR per feature/fix, targeting staging
- Staging is merged into main when the team decides the train is ready
Changes required
.github/dependabot.yml:
target-branch: staging.github/workflows/release-on-merge.yml — new file:
- Trigger: push on main
- Steps: checkout (full history), pnpm install, changesets/version + changesets/publish
- OIDC/Trusted Publishing: permissions: { id-token: write } + NPM_CONFIG_PROVENANCE: true
- Skip the merge commit itself (detect via github.event.head_commit.message)
Branch setup (manual, not in repo):
- Create staging from main
- Add branch protection on staging: PRs required, CI required, no force-push
- Update branch protection on main: direct pushes disabled, only staging PR can merge
- All existing contributors notified: PRs now target staging, not main
What stays the same
- Major-version Dependabot PRs still require manual review before merge onto staging
- group-by: dependency-name (from ci: deduplicate Dependabot PRs in monorepo via group-by #43) still applies
- apps/web with private: true is never published
- changesets/action v1.9.0 is still the production-safe version
Merge strategy on staging (Decision needed)
| Option | Behavior |
|---|---|
| Squash and merge | One commit per PR lands on staging |
| Merge commit | Full history preserved on staging |
Recommendation: Squash and merge — keeps staging history clean and linear.
Hotfix path
If a hotfix must bypass the staging gate:
- Branch from main, fix, open PR to staging with label "hotfix"
- Fast-track CODEOWNERS review
- Merge staging -> main immediately
Normal features always go through staging.
Acceptance Criteria
- staging branch created from main
- Branch protection on staging: PR required, CI required, no force-push
- Branch protection on main updated: direct pushes disabled, PR from staging required
- .github/dependabot.yml updated: target-branch: staging + group-by: dependency-name
- .github/workflows/release-on-merge.yml created and functional
- One full train cycle tested: PR -> staging -> main -> npm publish
- CONTRIBUTING.md updated to reflect new branching model
- OIDC / Trusted Publishing configured (drop NPM_TOKEN)
- changesets/action pinned to v1.9.0 in the workflow
- Merge strategy on staging decided (squash or merge commit)
Related
- ci: deduplicate Dependabot PRs in monorepo via group-by #43: ci: deduplicate Dependabot PRs in monorepo via group-by (prerequisite)
- Learning: docs/internal/learnings/github/dependabot-pnpm-monorepo-2026.md
- Learning: docs/internal/learnings/changesets/changesets-2026.md
Risks
- Medium: Process change for all contributors — requires communication and CONTRIBUTING.md update.
- Low: Staging can drift from main if left unmerged too long. Mitigate with a scheduled sync or reminder.
- Low: CI reliability on staging — if CI is flaky, the train stalls.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:ciWorkflows, dependabot, toolingWorkflows, dependabot, toolingdependenciesDependency updates (used by Dependabot)Dependency updates (used by Dependabot)status:blockedBlocked by an external dependency (TS, upstream)Blocked by an external dependency (TS, upstream)
Activity
[-]ci: adopt a staging branch for Dependabot accumulation with auto-release on main merge[/-][+]ci: adopt a staging branch as integration gate for all PRs with auto-release on main merge[/+]martyy-code commentedon Jul 13, 2026
Triage: blocked
This issue is currently blocked by: #43 — the staging branch model requires Dependabot to target
stagingviatarget-branchin.github/dependabot.yml. Until #43 lands (addinggroup-by: dependency-name), making that same config change fortarget-branchis premature — the duplicate PR problem would compound on staging.Verification: The issue body explicitly states #43 as a prerequisite ("group-by: dependency-name from #43 still applies"). Both issues touch the same
.github/dependabot.ymlfile. Additionally, the staging branch does not yet exist in the repo and must be created manually.Next steps: Once #43 is resolved and the staging branch is created, this issue can be unblocked. The core work (workflow, OIDC, CONTRIBUTING.md update) is all doable now — just waiting on the structural prerequisites.
See also: #43 for the dependency-order context.
We'll revisit once #43 is merged. No action needed from you at this time.
Triage by @martyy-code.