Releases
OpenGameBuilder ships through GitHub Actions. There are exactly three release workflows you need to know about:
| Workflow | Trigger | What it does |
|---|---|---|
| 🛰️ CD Staging | Every push to main, or manual dispatch from main |
Build, test, deploy to staging, smoke test |
| 🚀 CD Production | Manually dispatched from main, with a separate source ref input |
Validate, build, test, deploy to production, smoke test, tag, release, follow-up PR |
| 🩹 Prepare Patch | Manually dispatched | Create patch/vX.Y.(Z+1) branch and a version-bump PR off the latest tag |
Host infrastructure is separate: 🌐 CD Edge updates the selected host's
explicit edge profile, not an application release. Staging and production may
use separate hosts and SSH keys. Configure their EDGE_PROFILE variables before
deploying; see hosting setup. Shared-host staging keeps
the production-health guard; isolated staging has no production dependency.
The single source of truth for the version is <VersionPrefix> in
Directory.Build.props. See versioning.md.
Each deployment records releases/<release-id>/release-manifest.txt with the resolved source commit,
the immutable API image digest reference, and the SHA-256 of the published web
archive. After validation the package job publishes the portable frontend once;
after environment approval, deployment verifies it and builds the API image once
without environment-specific frontend publishing. These identities are more
precise than the version or mutable commit-named convenience tag. Inspect the
manifest and workflow artifact when identifying an installed release. The host's
current and previous files identify the active and rollback pair; see
hosting setup. The
browser smoke check follows the activated page, observes its /api/about call,
and compares the running API's source revision with the selected protected
commit. The hosting guide records deployment and recovery evidence.
For CD Production, the Actions branch picker must be main: it selects
the workflow definition and the run ref checked by the production environment.
The separate ref input selects application source: protected main for a
standard release or protected patch/vX.Y.Z for a patch. The resolver fixes that
source to a commit; tags, arbitrary SHAs, and unprotected branches are rejected.
The workflow rejects non-main dispatches before source resolution. See
deployment authority.
Curated release notes
CHANGELOG.md is the curated account of notable changes.
Keep an Unreleased section for observable application, contributor, and operator
changes. Include breaking behavior and migration or configuration steps where
needed; leave out mechanical dependency and formatting noise. Published releases
before this changelog remain documented in GitHub Releases.
Before dispatching a production release, review the entry against the selected
source and version in Directory.Build.props, then replace Unreleased with that
version and its planned release date in the release-source PR. A patch entry
belongs on its patch branch and returns to main through the existing merge-back.
A changelog heading records prepared notes, not proof that deployment succeeded;
GitHub Releases records publication.
The current workflow still generates GitHub Release notes from PRs; it does not read the changelog. After successful publication, the release maintainer copies the selected version's curated entry into the release body, retaining generated PR links as supplemental references or credits. Correct the entry here first when updating the published summary so there is one maintained account. This manual notes step does not change deployment validation, tag timing, version ownership, or the requirement for release authorization.
Standard release (X.Y.0)
mainalready has<VersionPrefix>X.Y.0</VersionPrefix>(set by the post-release bump PR from the previous release).- Go to Actions → 🚀 CD Production → Run workflow. Select
mainin the branch picker and leave the separaterefinput asmain. - The
productionenvironment requires reviewer approval — approve when ready. - On success the workflow tags
vX.Y.0, creates the GitHub Release, and openschore: bump version to X.(Y+1).0againstmain. Merge that PR.
Patch release (X.Y.Z, Z > 0)
- Go to Actions → 🩹 Prepare Patch → Run workflow. This creates
patch/vX.Y.(Z+1)from the latest release tag and opens a PR that bumps the<VersionPrefix>on that branch. Merge the prepare PR. - Add the fix to
patch/vX.Y.(Z+1)via normal PRs targeted at that branch. - Go to Actions → 🚀 CD Production → Run workflow. Leave the branch picker
on
main(so the workflow file runs from main) and setreftopatch/vX.Y.(Z+1). - Approve the production environment when prompted.
- On success the workflow tags
vX.Y.(Z+1), creates the GitHub Release, and openschore: merge vX.Y.(Z+1) into main. Review and merge that PR.
The workflow definition and shared validation action come from the dispatched
main workflow commit; application files and release/deployment scripts come
from the resolved protected source commit. Ensure patch branches contain
compatible deployment and release code, including the /api/about source
revision used by the browser smoke test. A patch release still uses main in
the workflow branch picker.
What the production workflow validates
It detects whether the selected source is a standard or patch release from the
version number itself (Z == 0 → standard, Z > 0 → patch) and checks:
- Version in
Directory.Build.propsis plainX.Y.Z - For standard: ref is
main, version is greater than the latest stable release - For patch: ref is
patch/v<version>, the version is the next patch in line, and that line is the latest deployed line - Any existing
vX.Y.Ztag points at the same commit (idempotent reruns)
What happens on failure
The tag, GitHub Release, and follow-up PR are only created after a
successful production deploy and smoke test. If activation or smoke testing
fails, the deployment job attempts recovery in its rollback step. An upgrade
restores the previous web/API pair; a failed first deployment returns to the
defined undeployed state. Inspect that step's result and the host's current,
previous, pending, and candidate predecessor records before rerunning; see
the recovery procedure.
If deployment and smoke testing succeed but tag creation, GitHub Release creation, or the follow-up PR fails, production is already running the new pair. Do not roll it back solely because publication failed. Read the active manifest and workflow run to confirm the exact source SHA and image digest. After fixing the publishing error, rerun from the same protected source branch while it still resolves to that SHA; the release scripts accept the matching existing tag and release. If that branch has moved, use the recorded commit and resolve the publication state with the maintainer before dispatching another deployment.
If the post-deploy steps fail after the tag exists (e.g. release creation hiccup), rerun the workflow from the same source branch and commit. Validation accepts an already-published standard or patch release only when its tag still points at that commit and it remains the latest stable release. A different tag target, a skipped patch number, or an older release line is rejected.
If the patch merge-back encounters a conflict in Directory.Build.props or any
other file, the follow-up step stops without pushing a merge branch. Resolve the
merge locally and open the merge-back PR manually; preserve both sides' non-version
changes and keep main's current VersionPrefix if it is already at least
X.(Y+1).0. Do not choose the entire props file from one side. The production
release may already be published even though this follow-up PR is still missing.
Don't do these
- Don't push
v*tags manually. - Don't release patch versions from
main. - Don't release standard versions from a
patch/*branch. - Don't bypass the follow-up PR without good reason —
mainis expected to hold the next standard release version at all times.