| name | app-release |
| description | Prepare and ship Gothic Lock Breaker releases — semver bump, CHANGELOG, README badge, SEO dates, verification, and deploy. Use when the user asks to prepare, cut, ship, or tag a release; bump version; or update CHANGELOG for deploy. |
Gothic Lock Breaker — app release
Read AGENTS.md boundaries first. One commit per release; merge PR to main triggers deploy. Direct push to main is blocked by branch protection.
When to bump
| Level | Use when |
|---|
| patch (x.y.Z) | Bug fixes, copy tweaks, analytics tuning, lint-only |
| minor (x.Y.0) | New features, perf wins, build/CI changes, new locales keys |
| major (X.0.0) | Breaking URL hash format, solver semantics, or saved-lock compatibility |
Source of truth: src/version.js → export const VERSION.
Release checklist
Copy and track:
- [ ] Review git diff since last tag — group into Added / Changed / Fixed / Removed
- [ ] Pick semver (patch / minor / major)
- [ ] src/version.js — VERSION
- [ ] CHANGELOG.md — new ## [X.Y.Z] - YYYY-MM-DD at top (Keep a Changelog sections)
- [ ] README.md — Current release: vX.Y.Z
- [ ] README.md — version badge (shields.io line)
- [ ] llms.txt + sitemap.xml — Last updated / lastmod date = changelog date (if SEO-relevant)
- [ ] make lint && make test (includes check-version and check-seo)
- [ ] Optional: make build && make preview — smoke fonts, locales, hash, cold onboarding
- [ ] Commit on release branch + open PR to `main` (only if user asked)
- [ ] Wait for ALL PR checks green, then merge with branch delete, then wait for deploy run — see "Merge procedure"
main is protected — all changes via PR, ci status check required. make check-version does not check the README badge — update it manually.
CHANGELOG entry
Format (match existing CHANGELOG.md):
## [1.15.0] - 2026-06-11
### Added
- …
### Changed
- …
### Removed
- …
- User-facing outcomes, not file lists
- Omit empty sections
- Date = UTC calendar day of the release commit
SEO dates
When the release touches SEO, positioning, press URLs, JSON-LD, or llms.txt content:
llms.txt — ## Last updated block must include the changelog date string
sitemap.xml — every <lastmod> must include that same date
node scripts/check-seo.js enforces parity with the latest CHANGELOG heading date.
Verify
make lint && make test
check-version and check-seo run inside npm test.
Commit message
Release vX.Y.Z — one-line summary of the headline change.
Example: Release v1.15.0 — Vite build, GitHub Actions deploy, first-load perf, Biome.
Do not commit unless the user explicitly asks. When they do, one commit on a release branch with all release files + any pending feature work for that release. Open a PR to main.
Merge procedure (agent must follow in order)
Never merge on a hunch. Run these steps; do not skip the wait.
- Wait for every PR check to pass — not just
ci. Block on the live result:
gh pr checks <pr-number> --watch
This watches all PR workflows (ci and lighthouse). It exits non-zero if any check fails — if so, stop, fix, push, and re-watch. Do not merge a red or pending PR.
- Merge only once all checks are green, and delete the PR branch in the same step:
gh pr merge <pr-number> --merge --delete-branch
Branch protection blocks the merge if ci is not green, and rejects force/direct pushes to main. --delete-branch removes the remote PR branch after the merge.
- Wait for the post-merge
Deploy workflow (which includes the release job) to finish:
gh run watch "$(gh run list --workflow=deploy.yml --branch=main --limit=1 --json databaseId --jq '.[0].databaseId')" --exit-status
--exit-status fails if any job (ci, build, deploy, release) fails. Only after this run is green is the release actually shipped and tagged.
Deploy (runs after PR merge to main)
- GitHub Settings → Pages → Build and deployment → source GitHub Actions (not branch root)
- Merging the PR triggers
.github/workflows/deploy.yml: CI → vite build → Pages artifact → release job
- After the merge step above reports green, spot-check gothiclockbreaker.com
Branch protection requires the ci status check to pass before merge; force pushes and direct pushes to main are blocked.
Tag + GitHub Release (automated — do not do by hand)
The release job in .github/workflows/deploy.yml runs on every push to main:
- Reads
VERSION from src/version.js → tag vX.Y.Z.
- Skips if that tag already exists on the remote (idempotent — re-runs and unrelated merges are no-ops).
- Otherwise creates the tag at the merge commit and a GitHub Release whose body is the matching
CHANGELOG.md section, extracted by scripts/changelog-notes.js.
Implications for this checklist:
- Never create tags or run
gh release create manually — the workflow owns it.
- A release only happens if
src/version.js was bumped and a matching ## [X.Y.Z] CHANGELOG entry exists. Both are already in the checklist; the Release section now depends on them.
- The CHANGELOG entry is the public release notes — write it for players, not as a file list.
Do not
- Commit
dist/, node_modules/, secrets
- Split version bump and changelog across multiple release commits
- Bump version without a dated CHANGELOG entry
- Add FAQPage JSON-LD (
check-seo.js rejects it)