원클릭으로
prep-release
Prepare SUEWS release with pre-flight checks and tag generation.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Prepare SUEWS release with pre-flight checks and tag generation.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Review SUEWS PRs. Drafts comments for approval before posting.
Use whenever the user wants to fix a SUEWS GitHub issue into a validated, PR-ready branch. Trigger for requests like "fix issue
Use whenever auditing, clarifying, rewriting, labelling, or batch-reviewing SUEWS GitHub issues so they become maintainer-ready. Trigger for requests like "audit this issue", "make this issue agent-ready", "rewrite issue
Use whenever auditing, prioritising, or batch-triaging SUEWS draft and stalled pull requests so each gets a clear disposition. Trigger for "triage PRs", "which draft PRs need attention", "what's the disposition of these PRs", "groom the PR backlog", "defer this PR with a reason", "which PRs are ready to advance to merge", or a scheduled PR-backlog sweep. Routes live PRs to prep-pr/split-pr/queue-pr; defers or escalates the rest; never merges or closes.
Documentation sanity check for SUEWS source files. Two checks under one roof - non-ASCII characters in sphinx-gallery tutorials/RST/docstrings (with context-aware RST/LaTeX/matplotlib replacement), and bibliography topic-tag convention plus metadata backfill on the refs bib files. Use when editing docs/source files or the refs-*.bib files, when a doc hook flags an issue, or when asked to "audit docs", "check docs", "fix non-ASCII", "check bib tags", "curate refs". Complements sync-docs (doc-code content consistency) and lint-code (code style).
Check code style against SUEWS conventions. Complements ruff/fprettify.
| name | prep-release |
| description | Prepare SUEWS release with pre-flight checks and tag generation. |
Guide through release process per the repo's dev-ref/RELEASE_MANUAL.md.
This workflow is workspace-independent - run from any worktree.
git checkout -b release/YYYY.M.D origin/mastergit log <last-release-tag>..HEAD -- src/supy/data_model/. If any commit is a structural change (see .claude/rules/python/schema-versioning.md for triggers), confirm that CURRENT_SCHEMA_VERSION was bumped, SCHEMA_VERSIONS has a matching entry, sample_config.yml carries the new version, and yaml_upgrade.py::_HANDLERS has a (previous_schema -> current_schema) handler (the handler registry is the single source of truth for compatibility; is_schema_compatible derives from it). Stop and fix if any are missing — this was the gap closed in gh#1304.build-suews artefact or make dev — NOT PyPI, which has nothing yet) and run the multi-version benchmark: require a reproducible fingerprint and no energy-balance regression vs the previous release. This gates the release — do NOT proceed to deposit (PR merge, tag, PyPI, GitHub Release, Zenodo) on an unreviewed regression. See ## Benchmark gate.:pr: syntax), toctree
6a. Docs sanity check - Regenerate docs/source/inputs/tables/schema.json (suews schema export -o ...) and scan for stray .dev schema labels per .claude/rules/docs/release-docs-sanity.md. The banner-free stable build is produced post-tag by release-docs-anchor.yml (step 11a)..github/releases/YYYY.M.D.md (Markdown)docs-sync.yml has refreshed the rtd branch, run the release-docs-anchor.yml workflow with release_tag=YYYY.M.D (gh workflow run release-docs-anchor.yml -f release_tag=YYYY.M.D). It builds a banner-free anchor and moves the tag onto it so RTD stable shows a clean version (replaces the manual tag-move in dev-ref/RELEASE_MANUAL.md). See .claude/rules/docs/release-docs-sanity.md.benchmark/results/index.json and version the Zenodo reproducibility stack (the gate already ran the numbers; this publishes them under the final version). See ## Benchmark gate.Details: references/release-steps.md
The release issue (labelled 2-meta:release) tracks the overall release. Steps 0-3 and 5-7 are automated by the prep-release workflow and the PR; the benchmark gate (step 4) is a hard prerequisite that must pass before depositing. Steps 8-13 are manual and must not be closed by the PR merge.
When preparing a release:
The parent release issue stays open until all sub-issues are closed. The PR should only close the "Submit PR" sub-issue, not the parent.
CHANGELOG entries use status tags ([experimental], [stable], [internal]) on [feature] and [change] items. These tags control what appears in public-facing release documentation:
[stable] and untagged entries -> included in release notes (RST and GitHub Release MD)[experimental] entries -> excluded from release notes; remain only in the CHANGELOG[internal] entries -> excluded from release notes[bugfix], [maintenance], [doc] entries -> always included (no status tag needed)When writing version history RST and GitHub Release notes, filter the CHANGELOG to include only stable/untagged features and changes alongside all bugfixes, maintenance, and documentation entries. Do not expose experimental features in public release documentation.
Release when ready. Scoring is guidance only.
RELEASE NOW (any one):
RECOMMENDED (score ≥5):
WAIT (any one):
Dev tags (YYYY.M.D.dev) are CI-verified commits. Release from a known-good dev tag to skip redundant local testing.
# List recent dev tags with CI status (run from any worktree)
git fetch --tags origin
git tag -l "*.dev" --sort=-v:refname | head -5
gh run list --branch master --limit 10
Selection criteria:
[PASS/FAIL] No incomplete prior releases (all merged release PRs have tags)
[PASS/FAIL] Dev tag selected: YYYY.M.D.dev
[PASS/FAIL] CI status: All workflows passed
[PASS/FAIL] On master lineage
[PASS/FAIL] Release branch created
[PASS/FAIL] Schema version sync (sample_config.yml matches CURRENT_SCHEMA_VERSION; run /verify-build)
[PASS/FAIL] Schema version bump covers every structural data_model change since last tag (see .claude/rules/python/schema-versioning.md)
[PASS/FAIL] BENCHMARK GATE (prerequisite, before depositing): candidate build reproducible (byte-identical fingerprint) + per-release schema-valid config + NO energy-balance regression vs previous release (or regression reviewed and accepted)
[PASS/FAIL] Knowledge pack rebuilt against HEAD (run `suews knowledge build --output src/supy/knowledge/pack/current --repo-root .` if data_model/ or cmd/ touched since last release; see gh#1406)
[PASS/FAIL] Docs updated (CHANGELOG, version-history RST)
[PASS/FAIL] Docs sanity check (.claude/rules/docs/release-docs-sanity.md): schema.json regenerated to the released label; no stray .dev schema labels in user-facing docs (scan excludes legitimate dev-cycle narration)
[PASS/FAIL] GitHub Release notes created (.github/releases/)
[PASS/FAIL] Release issue updated, sub-issues created for manual steps
[PASS/FAIL] PR submitted and CI passed
[PASS/FAIL] PR merged to master
[PASS/FAIL] Git tag created on merge commit
[PASS/FAIL] GitHub Release published (triggers Zenodo DOI)
[PASS/FAIL] Stable docs published: release-docs-anchor.yml run for the tag; RTD stable shows clean version (no Development Version banner)
[PASS/FAIL] Benchmark result recorded: released version added to page + benchmark/results/index.json; Zenodo reproducibility stack versioned
[PASS/FAIL] umep-reqs PR created (UMEP-dev/umep-reqs)
Ready: YES/NO
The most common release failure is merging the release PR (step 6) and then forgetting steps 7-8 (tag and verify). Without the tag:
Recovery: Complete the release by tagging the merge commit on master:
git fetch origin master
MERGE_SHA=$(gh pr list --state merged --search "Release YYYY.M.D" \
--json mergeCommit --jq '.[0].mergeCommit.oid')
git tag -a "YYYY.M.D" "$MERGE_SHA" -m "Release YYYY.M.D"
git push origin "YYYY.M.D"
Before starting a new release, check for incomplete releases:
# Compare merged release PRs to existing tags
gh pr list --state merged --search "Release" --limit 5 --json title,mergeCommit
git tag -l "[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname | head -5
If a previous release PR was merged but never tagged, complete that release first. Starting a new release on top of an incomplete one creates confusion in the CHANGELOG and version history.
# === Run from any worktree ===
# 1. Select dev tag
git fetch --tags origin
DEV_TAG="2026.1.25.dev"
gh run list --commit $(git rev-parse $DEV_TAG) --json conclusion,name
# 2. Create release branch
VERSION="$(date +%Y.%-m.%-d)"
git fetch origin master
git checkout -b release/$VERSION origin/master
# 3. Update docs (use :pr:`XXX` in RST, #XXX in Markdown)
# - CHANGELOG.md
# - docs/source/version-history/v$VERSION.rst
# - .github/releases/$VERSION.md (GitHub Release notes)
git add CHANGELOG.md docs/source/version-history/ .github/releases/
git commit -m "docs: update changelog and version history for $VERSION"
# 4. Submit PR
git push -u origin release/$VERSION
gh pr create --title "Release $VERSION" --body "Release documentation for $VERSION"
# 5. After PR merges, tag the merge commit
git fetch origin master
gh pr list --state merged --search "Release $VERSION" --json mergeCommit --jq '.[0].mergeCommit.oid'
# Use the merge commit SHA to tag
git tag -a "$VERSION" <merge-commit-sha> -m "Release title"
git push origin "$VERSION"
# Abort (if needed)
git tag -d "$VERSION" && git push origin ":refs/tags/$VERSION"
Each tag triggers one PyPI upload per platform via GitHub Actions:
YYYY.M.D - cp312-abi3 wheel (installs on cp312..cp3xx)The runtime pin is numpy>=1.22, so the same wheel works in QGIS 3 LTR
(NumPy 1.26.4), QGIS 4 (NumPy 2.x), and any modern Python environment.
The UMEP (rc1) variant was retired in 2026-04 once the Rust bridge
removed all NumPy C-ABI dependencies.
The release is benchmarked against the multi-version regression suite (KCL/London, Ward 2016) as a prerequisite, before any depositing (PR merge, tag, PyPI, GitHub Release, Zenodo). A regression must be caught and reviewed before shipping, not recorded afterwards. The harness lives in benchmark/; full method in benchmark/REPRODUCE.md.
The gate runs against the release candidate, NOT PyPI (the version is not published yet):
build-suews CI artefact (preferred — it is the same wheel that ships) or make dev in a clean venv. Do NOT pip install "supy==<version>" — that version does not exist on PyPI until step 11. For older releases, pin a compatible pandas (pre-2026 releases need pandas<3); keep numpy at the wheel's ABI. Save freeze.txt.SUEWSSimulation(canonical).config.model_dump() to inputs/config_<version>.yml); record config_schema_on_load + config_hash. suews-convert is NOT a YAML schema migrator. Never reuse a foreign-schema config silently.ZENODO_TOKEN secret/env; never print or commit it), then run_benchmark.py over the fixed period twice; require a byte-identical fingerprint. Log a build/run failure with the exact error rather than inventing a number.After the release is published (step 11), record the result (step 12): run assemble_index.py -> benchmark/results/index.json, update site/benchmark/ (suite row + per-site detail) so the final version appears, and add it as a new version in the restricted Zenodo reproducibility stack (and the data record if obs/forcing changed). Commit derived stats + the per-release config only; never commit obs/forcing (gitignored).
Governance gate: the fully-automated CI version needs the real observations on a restricted production Zenodo record plus a ZENODO_TOKEN GitHub secret and data-owner (Grimmond-group) sign-off. Until that lands, run the gate manually against the restricted sandbox record; only derived statistics are ever published.
benchmark/REPRODUCE.md - Benchmark method + exact commandsreferences/release-steps.md - Full step-by-step guidereferences/assessment-criteria.md - Decision scoringdev-ref/RELEASE_MANUAL.md - Complete manual (in repository root)