diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d77f9b..1405732 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: pull_request: push: branches: + - dev - master jobs: @@ -17,6 +18,9 @@ jobs: - name: Validate production metrics configuration run: scripts/test-compose-metrics-config.sh + - name: Validate CI branch coverage + run: scripts/test-ci-branches.sh + server: name: Server lint and unit tests runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9e48c8..4ccc6aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,19 +21,27 @@ Do not run separate installs or create lockfiles inside workspaces. ## Branches -Create branches from the latest `master`: +Create feature branches from the latest integration branch: ```sh git fetch origin -git switch -c your-branch origin/master +git switch -c your-branch origin/dev ``` If you use a fork, replace `origin` with the remote that tracks the canonical -repository. Pull requests should target `master`. +repository. Pull requests should target `dev`; `master` receives only a +reviewed promotion from `dev`. + +The branch flow is feature branch → `dev` → release-candidate validation → +reviewed promotion to `master`. CI runs on every pull request and on pushes to +both `dev` and `master`, so the merge commit on `dev` is the release candidate +that must be validated. Do not merge a feature branch directly to `master`. Keep each pull request limited to one coherent change. Before publishing, -inspect both the commit list and the complete diff against `master` to make sure -the branch does not include work inherited from another feature branch. +inspect both the commit list and the complete diff against `dev` to make sure +the branch does not include work inherited from another feature branch. Compare +a release promotion against both `origin/master` and the intended `origin/dev` +commit so its scope is explicit. ## Code Style @@ -109,3 +117,9 @@ explains what changed and why. Do not include credentials, production data, access tokens, or private logs. If you discover a vulnerability, follow [SECURITY.md](SECURITY.md) instead of opening a public issue. + +## Release Promotion + +Use the [release workflow](docs/release-workflow.md) before promoting `dev` to +`master`. It records the required CI, review, migration, deploy, and rollback +evidence; it does not authorize a production deployment by itself. diff --git a/docs/README.md b/docs/README.md index 69c5269..c2a6e51 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,8 @@ This directory contains the durable technical documentation for Let's Cube. — resumable migration, parity, privacy, and rollback contract - [Production operations](operations.md) — deployment, health checks, rollback, backups, restore, and capacity management +- [Release workflow](release-workflow.md) — feature-to-`dev` integration, + `dev`-to-`master` promotion evidence, and deployment handoff ## Feature contracts diff --git a/docs/development.md b/docs/development.md index 91d4bb2..d28960a 100644 --- a/docs/development.md +++ b/docs/development.md @@ -197,6 +197,6 @@ and `http://localhost:9000/health/socket`. ### Tooling changes break unexpectedly -The repository combines React 16, Material UI v4, Jest 26, ESLint 6, and modern -Vite. Run client unit tests and `yarn workspace letscube-client build` after -dependency or build-tool changes; success in only one path is not sufficient. +The client uses React 18, Material UI 6, Jest 30, ESLint 9, and Vite 8. Run +client unit tests and `yarn workspace letscube-client build` after dependency or +build-tool changes; success in only one path is not sufficient. diff --git a/docs/release-workflow.md b/docs/release-workflow.md new file mode 100644 index 0000000..a1304a6 --- /dev/null +++ b/docs/release-workflow.md @@ -0,0 +1,55 @@ +# Release Workflow + +`dev` is the integration branch. `master` is the reviewed release branch. +Production deployment remains a separately authorized operation described in +[Production operations](operations.md). + +## Branch Flow + +1. Open each focused feature pull request against `dev`. +2. Review and merge the feature into `dev`. +3. Treat the resulting `dev` merge commit as the release candidate. Its push + CI run must finish before promotion is considered. +4. Open a reviewed promotion from that exact `dev` commit to `master`. +5. After the promotion is merged and its `master` push CI passes, perform the + separately authorized deployment procedure. + +Do not bypass `dev` by merging feature work directly to `master`. A new commit +on `dev` after release-candidate validation requires a new validation run. + +## Promotion Evidence + +Before approving a `dev` to `master` promotion, record or link the following in +the promotion pull request: + +- the exact `dev` commit SHA and its successful CI run, including Cypress for + full-stack changes; +- the review that approved the promotion and any issue or milestone links; +- focused and broad checks relevant to the change, including checks not run; +- schema migration compatibility and data-backfill evidence when persistence + changes are included; and +- the intended deployment target plus the rollback path validated under + [Production operations](operations.md#failed-deployments-and-rollback). + +## Release Blockers + +A reviewer or release maintainer must block promotion when any required CI check +fails, the candidate SHA is unclear, review is incomplete, a migration cannot +run alongside the previous application image, deployment preflight or backup +restore evidence is missing, rollback has not been verified, or a security or +privacy concern is unresolved. Production deployment also stops without the +explicit operational authorization required by the operations guide. + +## Deployment Handoff + +After `master` CI is green, follow the operations guide in order: + +1. complete the [preflight](operations.md#preflight) checks; +2. deploy with the documented procedure; +3. perform the [verification and monitoring](operations.md#verification-and-monitoring) + checks; and +4. use the documented rollback procedure if readiness or verification fails. + +This checklist is release evidence, not a substitute for the production +authorization, secrets, backups, or host-level checks described in the +operations guide. diff --git a/scripts/test-ci-branches.sh b/scripts/test-ci-branches.sh new file mode 100755 index 0000000..00b8de9 --- /dev/null +++ b/scripts/test-ci-branches.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +WORKFLOW="$SCRIPT_DIR/../.github/workflows/ci.yml" + +for branch in dev master; do + if ! awk ' + /^ push:/ { in_push = 1; next } + in_push && /^ [^[:space:]]/ { exit } + in_push && $0 == " - " branch { found = 1 } + END { exit !found } + ' branch="$branch" "$WORKFLOW"; then + echo "CI must run on pushes to $branch." >&2 + exit 1 + fi +done + +echo "CI push branch coverage checks passed."