mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Explain release/* as the active cycle, main as the published line, and tags as ship markers so contributors know where to aim PRs. Co-authored-by: Ulofe Uduokhai <179733406+c4usal@users.noreply.github.com>
83 lines
3.0 KiB
Markdown
83 lines
3.0 KiB
Markdown
---
|
||
title: "Branching & Release Model"
|
||
lastUpdated: 2026-07-22
|
||
---
|
||
|
||
# Branching & Release Model
|
||
|
||
OmniRoute uses a **parallel-cycle** release model: a dedicated `release/vX.Y.Z`
|
||
branch for the active cycle, `main` for the published line, and an immutable
|
||
`vX.Y.Z` tag when that cycle ships. Seeing commits land on `release/*` *and* on
|
||
`main` is expected — not a mix-up.
|
||
|
||
Maintainer detail lives in `CLAUDE.md` (Hard Rule #21) and
|
||
[RELEASE_CHECKLIST.md](./RELEASE_CHECKLIST.md). This page is the public
|
||
contributor-facing summary.
|
||
|
||
## At a glance
|
||
|
||
| Ref | Role |
|
||
| --- | --- |
|
||
| `release/vX.Y.Z` | **Active cycle** — day-to-day development and PR merges for that version |
|
||
| `main` | **Published line** — receives the cycle via squash-merge when the release ships |
|
||
| `vX.Y.Z` (tag) | **Ship marker** — immutable “what shipped” pointer cut at release time |
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A["feat/fix branch"] --> B["PR → release/vX.Y.Z"]
|
||
B --> C["release/vX.Y.Z tip"]
|
||
C --> D["Release PR squash-merges → main"]
|
||
D --> E["Tag vX.Y.Z"]
|
||
C --> F["Next cycle: release/vX+1 cut from frozen tip"]
|
||
```
|
||
|
||
## Where should my PR target?
|
||
|
||
**Target the active `release/vX.Y.Z` branch — not `main`.**
|
||
|
||
1. Find the highest open `release/v*` branch (example at the time of writing:
|
||
`release/v3.8.49`).
|
||
2. Branch from that tip (`git fetch` + checkout / rebase onto it).
|
||
3. Open the PR with **base = that `release/vX.Y.Z`**.
|
||
|
||
`main` is not the day-to-day integration branch. PRs opened against `main`
|
||
usually need retargeting before merge.
|
||
|
||
## Release freeze (parallel cycles)
|
||
|
||
When a release is being reconciled, a marker issue labeled `release-freeze` is
|
||
opened. That **does not stop development**:
|
||
|
||
- The frozen `release/vX.Y.Z` belongs to the release captain for that ship.
|
||
- The next cycle’s `release/vX+1` is cut from the frozen tip so contributors keep
|
||
landing work.
|
||
- Open PRs that still target the frozen branch should be **retargeted** to the
|
||
active (highest) `release/v*` branch.
|
||
|
||
Check for an open freeze before assuming the branch you want is mergeable:
|
||
|
||
```bash
|
||
gh issue list --repo diegosouzapw/OmniRoute --label release-freeze --state open
|
||
```
|
||
|
||
Merge mechanics (owner `queue` label → Mergify) are documented in
|
||
[MERGE_TRAIN.md](./MERGE_TRAIN.md).
|
||
|
||
## Why both a branch and a tag?
|
||
|
||
| Artifact | Lifetime | Purpose |
|
||
| -------- | -------- | ------- |
|
||
| `release/vX.Y.Z` | In-flight cycle | Collects reviewed PRs, stays CI-green, is the PR base |
|
||
| Tag `vX.Y.Z` | Forever | Marks the exact bits that shipped to npm / GitHub Releases |
|
||
|
||
The branch is the workshop; the tag is the sealed package. After squash-merge to
|
||
`main`, the next cycle continues on `release/vX+1` without waiting for the prior
|
||
release PR to finish.
|
||
|
||
## Related docs
|
||
|
||
- [CONTRIBUTING.md](../../CONTRIBUTING.md) — setup, tests, PR checklist
|
||
- [RELEASE_CHECKLIST.md](./RELEASE_CHECKLIST.md) — pre-ship validation
|
||
- [MERGE_TRAIN.md](./MERGE_TRAIN.md) — merge queue and fallback train
|
||
- [RELEASE_GREEN.md](./RELEASE_GREEN.md) — keeping the release tip green
|