# Releasing ReXGlue SDK ## Branches `main` always sits at the most recent stable tag. `development` is the working canary; all feature work merges here first. `release/X.Y.Z` is short-lived: branched from dev tip when a release is cut, merged into both dev and main when the release is published, then deleted. ## Versioning The build version is computed automatically. Do not edit `CMakeLists.txt` to bump the version on a routine release. `CMakeLists.txt` carries only the API floor as `PROJECT VERSION MAJOR.MINOR.0`. The patch field there is a placeholder CMake requires; only major and minor mean anything. Edit the floor only when you are introducing a public API change. Version format follows [CMake's `CMAKE_VERSION`](https://cmake.org/cmake/help/latest/variable/CMAKE_VERSION.html) convention: `MAJOR.MINOR[.PATCH[.TWEAK]][-id]`. The full version is derived at configure time: - On a tagged commit: version is the tag verbatim (minus the leading `v`). Tags may be 2, 3, or 4 components (`v0.7`, `v0.7.5`, `v0.7.5.1`). Whatever you tag is what ships. - On a `release/*` branch: version is `MAJOR...-rc.g`. - On `development` or anywhere else: version is `MAJOR...-dev.g`. `` is `last-tag-patch + 1` when the floor minor matches the most recent tag's minor, or `0` when the floor is ahead. `` is the number of commits since that tag (the TWEAK slot). The `-id` trailer identifies the build channel (`dev` or `rc`) and the short commit SHA. Examples: | Scenario | Version | | --- | --- | | `git tag v0.7.5` pushed | `0.7.5` | | `git tag v0.7.5.1` pushed (hotfix tweak) | `0.7.5.1` | | `development`, 38 commits past `v0.7.4` | `0.7.5.38-dev.gb27f3f74` | | `release/0.7.5`, 15 commits past `v0.7.4` | `0.7.5.15-rc.gdeadbee` | | Floor bumped to `0.8`, 3 commits past `v0.7.5` | `0.8.0.3-dev.gdef5678` | A version with `-dev` or `-rc` is unstable. Only a version without an `-id` trailer is covered by the public API. ## Release flow ### Cutting the release Figure out the next release version. On a normal release it is `MAJOR..`. If the release introduces a public API change, bump the floor first (see "Bumping the floor" below) and the next release becomes `MAJOR..0`. Branch the release from dev tip and push it: ``` git fetch origin git checkout -b release/X.Y.Z origin/development git push -u origin release/X.Y.Z ``` Open a PR `release/X.Y.Z -> main`. ### While the release is open Feature work keeps merging into `development` as normal. Review fixes for the open release land on `release/X.Y.Z` directly. Do not cherry-pick review fixes into dev; they flow back when the release is published. ### Merging and tagging Merge the release branch into dev first, so review fixes flow back: ``` git checkout development git pull git merge --no-ff release/X.Y.Z -m "Merge release/X.Y.Z into development" git push origin development ``` Then merge into main. Use a real merge commit; do not squash, do not rebase: ``` git checkout main git pull git merge --no-ff release/X.Y.Z -m "Release vX.Y.Z" git push origin main ``` Tag the release branch tip (not `main` HEAD) and push. ``` git tag vX.Y.Z release/X.Y.Z git push origin vX.Y.Z ``` The tag push triggers `build-win-amd64`, `build-linux-amd64`, and `build-linux-aarch64`, which publish a GitHub release with the three platform zips. Delete the release branch (after tagging): ``` git push origin --delete release/X.Y.Z git branch -d release/X.Y.Z ``` ## Hotfixes A hotfix follows the same flow as a normal release with two differences. The release branch starts from `main` (the last stable tag) instead of dev tip, so it carries the fix and nothing else. The version is the next patch off the most recent tag, same rule as a normal release. ``` git fetch origin git checkout -b release/X.Y.Z origin/main ``` Apply the fix on the branch, open the PR into main, then merge into dev first and into main with a merge commit, exactly like a normal release. Tag and push. If a regular release branch is already open, close it without merging before cutting the hotfix; only one release branch may exist at a time. Re-cut the regular release from dev tip after the hotfix is released; its version will be the next patch off the hotfix tag. ## Bumping the floor Only when the public API is changing. Single commit on `development`: 1. Edit `CMakeLists.txt` line 6: change `PROJECT VERSION 0..0` to `PROJECT VERSION 0..0`. 2. Commit message: `chore: bump API floor to 0.`. 3. The next release branch is `release/0..0` and the tag is `v0..0`. ## Nightly builds Scheduled workflow that builds dev tip when its SHA has advanced since the last nightly. Each run produces a prerelease tagged `YYYYMMDD-` and prunes older ones beyond `NIGHTLY_RETENTION`. ## When something goes wrong CI fails on a tag push: do not delete the tag. Investigate, fix on `development`, cut the next patch release when ready. Do not retag. A bad release went out: cut a fix release. Do not delete the bad release. Conflicts merging `release/X.Y.Z` into `development`: resolve in favor of dev for feature changes, in favor of the release branch for release fixes. Do not cherry-pick. Two release branches accidentally open: close the older one without merging. Only one release branch at a time.