|
Pokered Save Editor 2
Pokemon Red & Blue save file editor - Qt 6 C++/QML
|
The project uses Semantic Versioning 2.0.0 (SemVer) as the people-facing number, with the git commit appended as build metadata so dev/CI builds stay traceable to an exact commit. This reconciles the two systems: SemVer is the simple, linear, human-readable number for people-to-people communication; the commit hash rides along (after a +, which is literally what SemVer reserves "build metadata" for) so nothing is lost for debugging.
MAJOR.MINOR.PATCH[-prerelease][+build]
Derived from the actual project, not picked arbitrarily. The codebase is large and mature (760 commits across 2019-2020 and the 2026 revival) with the hardest thing – byte-exact save read/write/roundtrip – done and tested, plus most editor screens built and polished. But it is not released, is in an active UI-polish phase, still has an end-to-end save/reopen verification pass and a documentation pass outstanding, and no packaging/installer yet. That profile is a feature-rich late alpha: clearly pre-1.0, but well past the early 0.1-0.3 range. 0.7.0-alpha says exactly that and leaves a clean runway – 0.8 as things stabilize, 0.9/-rc as a release nears, 1.0.0 at the first real release. (There were never real version numbers before now – CMake just said 1.0.0 and boot.cpp said v1.0.0, never synced – so this is the first formal baseline rather than a renumbering of history.)
The number is one line in VERSION; if the maturity is judged differently, it's a one-line change.
The repo-root VERSION holds the number on one line (comments with # allowed). It is the only place a human edits the version. (The changelog lives at notes/version/ — a subdirectory, so on case-insensitive Windows there is no VERSION/version/ collision with the repo-root file.)
Everything else is derived from it at build time. Do not hardcode a version anywhere else.
pse_version.h exposes: PSE_VERSION_MAJOR/MINOR/PATCH, PSE_VERSION_STRING (human, e.g. "0.7.0-alpha"), PSE_GIT_HASH, PSE_GIT_DIRTY, and PSE_VERSION_FULL (human + build metadata). The header is generated into the build tree and is not committed.
A tagged, clean release build has no +g... at all, so both forms read simply 0.7.0.
| File | Role |
|---|---|
| VERSION | The number (the only thing you edit) |
| projects/cmake/PSEVersion.cmake | Parse VERSION; git metadata; compose full string |
| projects/cmake/PSEVersionGen.cmake | Build-time script: refresh git metadata, regenerate header |
| projects/cmake/pse_version.h.in | Template for the generated C++ header |
| projects/CMakeLists.txt | Reads VERSION before project(); wires generation + RC option |
| projects/app/CMakeLists.txt | Adds the generated include dir + pse_version_gen dep; compiles the .rc |
| projects/app/pse_app.rc.in | Windows VERSIONINFO template |
| projects/app/src/boot/boot.cpp | Sets the runtime version from PSE_VERSION_FULL |
| projects/app/ui/app/screens/modal/About.qml | Displays the (cleaned) version |
The release path is set by the SemVer level (see reference/git-workflow.md → "Cutting a release"):
The tag is created by CI, not by hand. Pushing main triggers release.yml, whose version job derives v<VERSION> and whose release job (softprops) creates the tag vX.Y.Z on the release merge commit and publishes the GitHub Release. So do not run git tag manually — a hand-pushed tag makes the release run see the tag already exists and skip itself. (This is the project's recorded divergence from the hub git-flow runbook, which tags by hand; here the pipeline owns tagging. See reference/git-workflow.md → "Cutting a release.") The tag is still the accurate anchor mapping the SemVer number to one commit and letting git describe derive versions.
A build from a clean, tagged checkout shows the plain number with no +g... suffix.
The fairyfox compliance audit aggregates this per-standard slice — run on request, report done/partial/missing:
| Passes only when… | How to check |
|---|---|
| VERSION is a single SemVer line; nothing hardcodes a version elsewhere | cat VERSION; grep for stray version literals |
| The newest main release tag equals v<VERSION> | git tag --merged main \| sort -V \| tail -1 vs VERSION |
| Bumps rode in the same commit as the change that warranted them (PATCH default, MINOR rare, never auto-MAJOR) | git log -p -- VERSION |
These are complementary, not the same thing:
When you tag a release, it's worth noting the version in the changelog month file too, but the changelog stays per-commit and is maintained separately (by hand, on request).