adorsys / adorsys/status-list-server
ci: enforce main←stage←develop promotion pipeline with tagged releases
- Langage dominant
- Rust
- Étoiles
- 22
- Forks
- 5
- Merge moyen
- 2 j 11 h
- PR mergées (30 j)
- 47
Description
## Context
We currently have no enforced promotion path. Any branch can PR into any branch, and releases are cut by hand. This introduces a three-tier pipeline where each branch has exactly one legal upstream source, and where staging and production deploys are driven by pushes to their respective branches. feature/* → develop → stage → main
`develop` runs CI only. `stage` deploys to staging and cuts a prerelease tag. `main` deploys to production and cuts a release tag. GitHub has **no native rule** that restricts the head branch of a pull request rulesets only target the branch being written to. The promotion path is therefore enforced by a required status check that inspects `github.head_ref`.
## Tasks
### Branches
- [ ] Create `stage` and `develop` off current `main`
- [ ] Set `develop` as the default branch (PRs open against it by default)
### Workflows
- [ ] Add `.github/workflows/branch-gate.yml` — job named `gate`, triggers on
`pull_request` targeting `main` and `stage`, fails unless head is `stage`
(or `hotfix/*`) for `main`, and `develop` for `stage`. Rejects PRs from forks.
No `paths:` filter — a skipped job reports success and would not block.
- [ ] Add `.github/workflows/release-stage.yml` — on push to `stage`, environment
`staging`, deploy, then `gh release create v$VER-rc.$RUN --prerelease --generate-notes`
- [ ] Add `.github/workflows/release-prod.yml` — on push to `main`, environment
`production`, deploy, then `gh release create v$VER --latest --generate-notes`
- [ ] Both release workflows: `permissions: contents: write`,
`concurrency: { group: -deploy, cancel-in-progress: false }`
### Access control
- [ ] Create team `@org/release-admins`, grant **write** on this repo
(org-admin alone does not make a valid code owner)
- [ ] Add `.github/CODEOWNERS` **on the `main` branch** GitHub reads CODEOWNERS
from the PR base branch only, a copy on develop has no effect:
* @org/release-admins
/.github/CODEOWNERS @org/release-admins
### Rulesets
- [ ] `main`: require PR · 3 approvals · require code-owner review · dismiss stale
approvals · require approval of most recent reviewable push · require
conversation resolution · required checks `gate`, `build`, `test` ·
block force pushes · restrict deletions · **bypass list empty**
- [ ] `stage`: require PR · 2 approvals · dismiss stale approvals ·
required checks `gate`, `build`, `test` · block force pushes
- [ ] `develop`: require PR · 1 approval · required checks `build`, `test` ·
block force pushes
- [ ] Do **not** enable "require linear history" — promotions use merge commits
- [ ] Delete or convert any legacy Settings → Branches protections; they stack with
rulesets and the most restrictive wins, producing unexplainable merge blocks
### Environments
- [ ] Create `staging` and `production` environments with required reviewers
- [ ] Move deploy credentials to environment-scoped secrets
### Repo settings
- [ ] Enable **both** squash merge and merge commits. Squash is for `feature → develop`;
the two promotions must use merge commits or `stage` and `main` diverge
permanently and every promotion PR shows phantom conflicts
- [ ] Squash commit message = "PR title and description" (this is what
`--generate-notes` reads)
## Decisions needed before merge
- **Version bump location.** Either bump `Cargo.toml` on `develop` and promote the
bump through the chain (no back-merge needed), or bump on `main` via release-please
and owe a `main → develop` back-merge after every release. Pick one and document it.
## Acceptance criteria
- [ ] A PR from `feature/x` into `main` shows `gate` as failed and the merge button
is disabled for a user with write access
- [ ] A PR from `develop` into `main` shows `gate` as failed
- [ ] A PR from `stage` into `main` with 3 non-admin approvals still shows
"Review required" until a `release-admins` member approves
- [ ] A repo admin cannot merge a PR into `main` that has 2 approvals
- [ ] `git push --force origin main` is rejected
- [ ] Merging `develop → stage` produces a GitHub release marked *pre-release*
with an `-rc.N` suffix, and the staging deploy runs
- [ ] Merging `stage → main` produces a release marked *Latest* with no suffix,
and the production deploy runs
- [ ] Pushing a new commit to an approved `stage → main` PR clears all approvals
## Out of scope
- Migrating existing open PRs to the new base branches
- Automated changelog beyond `--generate-notes`
- Rollback tooling
Guide de contribution
Ouvrir le guide de contribution
Évaluation
Cette issue n'a pas encore été évaluée.