diff --git a/docs/adr/0012-current-state-semver-10x-north-star-calver-gitflow.md b/docs/adr/0012-current-state-semver-10x-north-star-calver-gitflow.md index 764d107ca..d1793773b 100644 --- a/docs/adr/0012-current-state-semver-10x-north-star-calver-gitflow.md +++ b/docs/adr/0012-current-state-semver-10x-north-star-calver-gitflow.md @@ -47,6 +47,7 @@ Recorded as direction, not as fact. Nothing below is implemented. - **CalVer `YYYY.MINOR.PATCH`** — production lines become `release/YYYY`, retired years become `support/YYYY`, breaking changes batch to the yearly cut. ADR-0004's rationale stands; only its timing changes. - **Full GitFlow**, including a long-lived **`develop`** as the integration trunk and preview lane, with `main` holding released code only. `release/v*` for stabilisation, `hotfix/v*` off `main`, `feature/*` off `develop`. +- **Nightly previews instead of per-commit.** With the preview lane on `develop`, it publishes once a night rather than on every commit. Cadence only — the version stays `…-preview.{height}` and `version.json` is untouched. See [branching-and-release.md → Nightly preview cadence](../branching-and-release.md#nightly-preview-cadence). - **Routine `[Experimental("FALLOUT0xx")]` gating** of all breaking surface before it lands — the discipline ADR-0008 assumed when it retired the `experimental` branch. The mechanism is current; the practice is not (one usage, `FALLOUT001` on `IPublish`). ### 3. Documentation rule diff --git a/docs/branching-and-release.md b/docs/branching-and-release.md index a88d60c4f..36ebe90b3 100644 --- a/docs/branching-and-release.md +++ b/docs/branching-and-release.md @@ -211,11 +211,57 @@ gitGraph |---|---|---| | Integration trunk | `main` | `develop` | | Preview lane publishes from | `main` | `develop` | +| Preview cadence | per-commit | **nightly** | | `main` holds | trunk + previews | **released code only**, tagged at each GA | | Stabilisation | `release/v*` cut from `main` | `release/v*` cut from `develop` | | Urgent fixes | `hotfix/*` off a support line | `hotfix/*` off `main`, back-merged to `develop` | | Feature branches | off `main` | off `develop` | +## Nightly preview cadence + +The preview lane moves to `develop`, and the cadence moves with it: **one build per night, not one per commit.** + +Trigger today, in `publish-packages-preview.yml`: + +```yaml +on: + push: + branches: [main] + paths-ignore: ['docs/**', '.assets/**', '**/*.md'] +``` + +Trigger under the North Star: + +```yaml +on: + schedule: + - cron: '0 3 * * *' # 03:00 UTC + workflow_dispatch: +``` + +### What does not change + +The version shape stays `-preview.{height}`. A nightly needs no date in the version, so `version.json` is untouched and nbgv keeps producing monotonic heights. [ADR-0004](adr/0004-calendar-versioning-and-dual-pace-channels.md) rejected date-based version *cores*; that rejection still holds and a nightly does not reopen it. + +`.g` still names the exact commit that was built, so a nightly package is still traceable to a single revision. + +### Why + +The preview lane publishes 22 packages per run. Per-commit means most of those runs differ trivially from the one before. Nightly caps the volume at one run a day, which cuts published versions, CI wall-clock, and the amount of work the prune job has to undo. + +### What it costs + +- **Latency.** A fix merged at 09:00 is not consumable until the next night. `workflow_dispatch` is the escape hatch when someone needs a build now. +- **Coarser attribution.** A regression is attributed to a night rather than to a commit. The commit hash in the version still identifies what was built, so bisecting stays possible, just over a wider span. + +### Two mechanical traps + +> [!IMPORTANT] +> **`schedule` only fires from the default branch.** GitHub ignores `schedule` triggers on non-default branches. A nightly that is meant to build `develop` therefore needs either `develop` to *be* the default branch, or an explicit `ref: develop` on the checkout step. Under full GitFlow, `develop` as default branch is the consistent choice, and it also makes new pull requests target `develop` by default. + +> [!IMPORTANT] +> **A night with no commits produces a version that already exists.** `{height}` only advances when a commit lands, so a quiet day yields the same version as the night before, and the push is rejected as a duplicate. The nightly needs a guard that skips the run when no new commit has landed since the last published preview, otherwise every quiet night reports a red build. + ## Calendar versioning Production lines become `release/YYYY`, retired years become `support/YYYY`, and breaking changes batch to the yearly cut. See [versioning.md → North Star](versioning.md#north-star) and [ADR-0004](adr/0004-calendar-versioning-and-dual-pace-channels.md). diff --git a/docs/versioning.md b/docs/versioning.md index 2363ce670..584629b17 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -167,6 +167,10 @@ The full rationale is [ADR-0004](adr/0004-calendar-versioning-and-dual-pace-chan Today the attribute exists and is used once. The intent is that **every breaking surface is gated behind it before landing**, so breaking work can accumulate on the integration trunk without a separate branch — the discipline ADR-0008 assumed when it retired the `experimental` lane. +## Nightly previews do not change the version scheme + +The branching North Star also moves the preview lane from per-commit to **nightly** (see [branching-and-release.md → Nightly preview cadence](branching-and-release.md#nightly-preview-cadence)). That is a cadence change only. The version stays `…-preview.{height}`, `{height}` stays monotonic, and no date enters the version. Two consequences worth knowing before it is adopted are recorded there: `schedule` fires only from the default branch, and a night with no commits reproduces the previous version. + ## Where the versioning North Star meets the branching one CalVer pairs with the GitFlow North Star in [branching-and-release.md](branching-and-release.md). Under full GitFlow the preview lane publishes from `develop` rather than `main`, which means `version.json`'s `{height}` core and `publicReleaseRefSpec`'s exclusion both move to `develop`. That is a direct conflict with [ADR-0008](adr/0008-collapse-experimental-into-main.md) ("`main` is the sole prerelease lane") and will need a superseding ADR when we adopt it — the two North Stars have to land together or not at all.