# Pulse v6 Prerelease Runbook This runbook captures the branch-specific operational path that was used while `main` continued to serve v5 releases during the v6 prerelease period. Canonical customer-channel and promotion rules now live in `docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md`. Current release-branch authority lives in `docs/release-control/control_plane.json`. If this historical runbook and the release-control policy disagree, the release-control policy wins. ## Branch Model (Current) - `main`: v5 stable (current public/stable line) - `pulse/v6-release`: active v6 prerelease and stable release line until an explicit post-GA branch cutover is governed Do not move `main` to v6 during prerelease. ## Enforced Workflow Policy Release workflows now enforce branch/tag lineage rules: - `Pulse Release Pipeline` (`create-release.yml`) - Resolves stable versus prerelease branch requirements from `docs/release-control/control_plane.json`. - For the current v6 profile, both stable and prerelease releases dispatch from `pulse/v6-release`. - `publish-docker.yml`, `promote-floating-tags.yml`, `publish-helm-chart.yml`, and `update-demo-server.yml` - Validate the release tag commit is reachable from the governed branch for that version instead of assuming `main`. - `update-demo-server.yml` - Routes stable tags to the stable demo environment and prerelease tags to the separate v6 preview demo environment. - The selected tag must still be reachable from the governed branch for that version. This prevents accidental cross-line releases from non-governed branches even if the stable branch changes later. ## Important Scope Note The Pulse release workflow in this repo (`.github/workflows/create-release.yml`) builds from the checked-out `Pulse` ref and runs `./scripts/build-release.sh`, which builds `./cmd/pulse`. It does not automatically check out or build `pulse-enterprise`. ## Versioning Rules - v5 stable examples: `5.1.14` - v6 prerelease examples: `6.0.0-rc.1`, `6.0.0-rc.2` - v6 GA example: `6.0.0` The workflow auto-marks `-rc.N`/`-alpha.N`/`-beta.N` as prerelease. ## Preconditions for Each RC 1. `pulse/v6-release` is pushed and green in CI. 2. `VERSION` file in `pulse/v6-release` exactly matches the release input version. 3. Release notes are prepared. 4. `PULSE_LICENSE_PUBLIC_KEY` secret is present in GitHub Actions. ## RC Release Steps 1. Update version on `pulse/v6-release`: ```bash git checkout pulse/v6-release git pull --ff-only echo "6.0.0-rc.1" > VERSION git add VERSION git commit -m "chore(release): bump version to 6.0.0-rc.1" git push origin pulse/v6-release ``` 2. Optional preflight dry run: - Run workflow: `Release Dry Run` - Ref: `pulse/v6-release` - Inputs: - `version`: `6.0.0-rc.1` - optional `note` 3. Create draft prerelease: - Run workflow: `Pulse Release Pipeline` - Ref: `pulse/v6-release` - Inputs: - `version`: `6.0.0-rc.1` - `release_notes`: markdown text - `draft_only`: `true` 4. Validate draft outputs: - Confirm assets exist and checksums match. - Confirm GitHub release is marked prerelease. - Smoke install on a test host/container. 5. Publish prerelease: - Re-run `Pulse Release Pipeline` on `pulse/v6-release` - Same `version` and notes - `draft_only`: `false` - Existing unpublished draft releases for the same tag are updated in place and their tag is retargeted to the current governed `pulse/v6-release` head automatically. Do not delete the tag manually just to retry publish. - The release workflow dispatches `update-demo-server.yml` against the `preview-v6` demo target automatically. - Keep the public stable demo on v5/stable; prereleases must land only on the separate preview demo runtime. 6. Canary rollout: - Upgrade a small user subset first. - Collect regressions, fix on `pulse/v6-release`, then cut `rc.2`/`rc.3` as needed. ## Keep v5 Stable During v6 RC - Continue v5 patch releases from `main` as normal. - Do not merge `pulse/v6-release` into `main` during prerelease. - Keep v5 and v6 changelogs/release notes separate. ## GA Cutover (Only After RC Confidence) Do this only when v6 is proven stable in production-like usage. 1. Create v5 long-tail branch from current `main`: ```bash git checkout main git pull --ff-only git checkout -b pulse/v5-maintenance git push -u origin pulse/v5-maintenance ``` 2. Keep the governed v6 release line on `pulse/v6-release` for GA: ```bash git checkout pulse/v6-release git pull --ff-only ``` 3. Release `6.0.0` from `pulse/v6-release` using `Pulse Release Pipeline`. Before the real GA publish, run `./scripts/trigger-release-dry-run.sh 6.0.0` from `pulse/v6-release`. That helper validates the default-branch workflow-dispatch contract before calling GitHub so stale `main` workflow inputs fail locally instead of returning an opaque 422 from `gh workflow run`. The governed `Release Dry Run` must still carry: - `version`: `6.0.0` - `promoted_from_tag`: exact prerelease tag being promoted - `rollback_version`: prior stable - `ga_date`: exact published v6 GA date - `v5_eos_date`: exact published v5 end-of-support date - optional `hotfix_exception` and `hotfix_reason` After the run passes, materialize the governed dated rehearsal record with `python3 scripts/release_control/record_rc_to_ga_rehearsal.py --run-id `. If `--output` is omitted, that recorder writes to `docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-.md`. Attach that record, the `rc-to-ga-rehearsal-summary` artifact, and the run URL to the release ticket, and confirm the artifact carries the canonical promotion metadata envelope for that candidate: candidate stable tag, promotion channel, promoted prerelease tag, rollback target, exact rollback command, planned GA date, and planned v5 end-of-support date. 4. Publish the exact v6 GA date and v5 end-of-support date in the GA release notice using `docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md` as the canonical policy. 5. Continue critical v5 fixes from `pulse/v5-maintenance` only. - The support window lasts 90 calendar days from v6 GA. - Only critical security issues, critical correctness/data-loss issues, installer or updater failures, licensing or billing blockers, and safe migration blockers are eligible during that window. - After that window, v5 is unsupported. 6. Treat any future move of stable v6 releases away from `pulse/v6-release` as a separate post-GA governance change; do not assume an automatic cutover to `main`. ## Rollback Strategy If an RC is bad: 1. Do not promote to GA. 2. Keep fixing on `pulse/v6-release`. 3. Cut next RC. 4. Keep v5 users on `main` stable releases. If GA has a severe regression: 1. Patch quickly on `pulse/v6-release` (v6.0.1), or 2. Advise affected users to hold at prior stable while fix ships. 3. Continue v5 emergency fixes from `pulse/v5-maintenance` only if the published maintenance-only window is still active or I explicitly announce an exception. ## Minimal Per-Release Checklist 1. Version file matches workflow input. 2. CI green on release ref. 3. Draft release validated. 4. Checksums and assets verified. 5. Canary cohort upgraded successfully. 6. Rollback note prepared before publish.