diff --git a/docs/08-ci-cd-pipeline.md b/docs/08-ci-cd-pipeline.md index 4efe618..a0cc967 100644 --- a/docs/08-ci-cd-pipeline.md +++ b/docs/08-ci-cd-pipeline.md @@ -34,10 +34,11 @@ The jobs differ per repo. What each one actually runs: | Lint, Test | Every push and every PR | | `publish` | **Only** when the ref is a tag matching `v*` — `if: startsWith(github.ref, 'refs/tags/v')` | -> **A merge to `main` does not produce an image.** It runs lint and tests only. -> The image on `ghcr.io` changes when, and only when, someone pushes a `v*` tag. -> This is the single most common source of confusion: `main` can be many commits -> ahead of the newest published image, and that is by design. +> **No merge produces an image — not into `develop`, not into `main`.** A merge +> runs lint and tests only. The image on `ghcr.io` changes when, and only when, +> someone pushes a `v*` tag. This is the single most common source of confusion: +> both branches can sit many commits ahead of the newest published image, and +> that is by design. ### Known gaps @@ -156,27 +157,39 @@ docker build -t ghcr.io/forail-platform/forail-frontend:2026.05.0 . ## Release Process -1. Ensure GitHub Actions is green on `main` for every repo being released +Work is integrated on `develop`; `main` holds released code only, and the tag +that publishes an image is always cut **on `main`**. See the git-flow section in +[10 — Contributing Guide](10-contributing-guide.md). + +1. Ensure GitHub Actions is green on `develop` for every repo being released 2. Bump `VERSION` in the repos that ship a version, and the Helm chart's `version` / `appVersion` so it pins the images you are about to publish 3. Write the release notes (`forail-deploy/docs/RELEASE_NOTES_v.md`) and the docs-site release page -4. Tag each changed repo and push the tag — this is what builds and publishes: - `git tag -a v2026.05.0 -m "Forail 2026.05.0" && git push github v2026.05.0` -5. Install the published chart and images into a clean cluster and run the full +4. Validate a release candidate first — see below +5. Merge `develop` into `main` (`git merge --no-ff develop`) and push it +6. Tag each changed repo **on `main`** and push the tag — this is what builds + and publishes: `git tag -a v2026.05.0 -m "Forail 2026.05.0" && git push github v2026.05.0` +7. Install the published chart and images into a clean cluster and run the full regression before announcing anything -6. Create the GitHub Release +8. Push `main` and the tags to `origin` as well, so the GitLab mirror keeps up +9. Create the GitHub Release ### Validate before you release -Cut an rc tag first (`v2026.05.0-rc1`). It publishes a real image through the -same job, so the release candidate can be installed into a clean cluster and put -through the full Cypress suite. Only then cut the real tag. Rc images stay on -`ghcr.io` — harmless, but do not point a chart at one. +Cut an rc tag first (`v2026.05.0-rc1`) from the commit you intend to release. It +publishes a real image through the same `publish` job, so the candidate can be +installed into a clean cluster and put through the full Cypress suite. Only then +merge to `main` and cut the real tag. + +An rc tag is the one case where tagging off `develop` is fine — it is a +throwaway build, not a release. Rc images stay on `ghcr.io`; harmless, but never +point a chart at one. ### Watch out - **Never release without passing tests.** - **Tag format must have `v` prefix:** `v2026.05.0`, not `2026.05.0`. -- **Merging to `main` publishes nothing** — only a `v*` tag does. +- **Merging publishes nothing** — into `develop` or `main`, only a `v*` tag does. +- **Tag on `main`**, not on `develop` — the sole exception is a throwaway rc tag. - **Image visibility** — when a new package is first pushed to `ghcr.io`, GitHub creates it as **private** by default. You must manually flip it to public via the Packages settings (`https://github.com/orgs/forail-platform/packages`). diff --git a/docs/10-contributing-guide.md b/docs/10-contributing-guide.md index 8ec3cd4..f67b9ea 100644 --- a/docs/10-contributing-guide.md +++ b/docs/10-contributing-guide.md @@ -48,15 +48,33 @@ test/inventory-api-tests # Tests chore/update-dependencies # Maintenance ``` +### The two long-lived branches + +Every Forail repo has exactly two permanent branches: + +| Branch | What it is | +| --------- | -------------------------------------------------------------------------- | +| `develop` | **The integration branch.** All day-to-day work lands here. | +| `main` | **Released code only.** It changes when a release is cut, and at no other time. | + +Everything else is temporary and gets deleted once it is merged. + +``` +feature/x ──┐ +fix/y ──────┼──► develop ──(release)──► main ──► tag v2026.08.0 ──► CI publishes images +chore/z ────┘ ▲ + └── hotfix/critical-thing (from main, back into develop too) +``` + ### Standard flow -**`main` is the integration branch.** There is no `devel` branch in any Forail -repo — branch from `main` and target `main` in the PR. +**Branch from `develop`, and target `develop` in the PR.** Do not open PRs +against `main` — the only thing that merges into `main` is a release. ```bash -# 1. Create branch from main -git checkout main -git pull github main +# 1. Create branch from develop +git checkout develop +git pull github develop git checkout -b feature/my-feature # 2. Make changes, test, commit @@ -65,17 +83,55 @@ vagrant ssh -c "cd /awx_devel && forail-test" git add forail/main/models/my_model.py git commit -m "feat(models): add Policy model for governance" -# 3. Push and create PR +# 3. Push and create PR against develop git push github feature/my-feature -gh pr create --base main +gh pr create --base develop ``` ### Updating the branch ```bash -git checkout main && git pull github main +git checkout develop && git pull github develop git checkout feature/my-feature -git rebase main +git rebase develop +``` + +### Cutting a release + +```bash +# develop is green and validated (see the rc procedure in 08-ci-cd-pipeline.md) +git checkout main && git pull github main +git merge --no-ff develop +git push github main + +# The tag is what publishes the images -- always tag on main, never on develop +git tag -a v2026.08.0 -m "Forail 2026.08.0" +git push github v2026.08.0 +git push origin main v2026.08.0 # keep the GitLab mirror level +``` + +### Hotfixes + +A fix that cannot wait for the next release branches from `main`, merges back +into `main`, and **must also be merged into `develop`** — otherwise the next +release quietly reverts it. + +```bash +git checkout -b hotfix/token-leak main +# ... fix, test, PR into main, tag ... +git checkout develop && git merge --no-ff hotfix/token-leak +``` + +### Deleting merged branches + +Delete a feature branch as soon as its PR is merged, locally and on both +remotes. A repo should normally show only `main`, `develop`, and whatever is +actively in flight. + +```bash +git branch -d feature/my-feature +git push github --delete feature/my-feature +git push origin --delete feature/my-feature ``` ### Remotes @@ -153,7 +209,7 @@ cd forail/ui_next && npx tsc --noEmit - [ ] All tests pass - [ ] No lint errors - [ ] Commit messages follow conventions -- [ ] Branch is rebased on latest `main` +- [ ] Branch is rebased on latest `develop` - [ ] Changes are minimal and focused ### PR guidelines @@ -161,7 +217,7 @@ cd forail/ui_next && npx tsc --noEmit - **Keep PRs small** — ideally under 500 lines. Large PRs are harder to review. - **One concern per PR** — don't mix a bug fix with refactoring. - **Include tests** — new features need tests, bug fixes need a regression test. -- **Target `main`** — all PRs merge into `main`. +- **Target `develop`** — all PRs merge into `develop`. `main` receives releases only. ### Review Checklist