@@ -19,12 +19,19 @@ There are two repos involved:
1919 The downstream repo remains the ** release gate** (full matrix, real ` copier update `
2020 against a long-lived project).
2121
22- Release rule: the downstream repo is the release gate.
22+ Release rule: the downstream repo is the release gate when it is reachable .
2323Push the template candidate, export it into ` jlevy/simple-modern-uv-template ` , and wait
2424for downstream CI to pass before creating a GitHub release for this template.
2525The commands below assume the downstream repo is cloned next to this repo as
2626` ../simple-modern-uv-template ` .
2727
28+ ** Releasing without downstream access** (for example, an agent session scoped to this
29+ repo only): this repo’s CI on the candidate commit is the gate — all jobs must be green
30+ — plus a local render verification (Step 5 run against a fresh render).
31+ Create the release on that basis, then complete the downstream export and tag recording
32+ (Steps 4–6 and 8) as post-release verification from an environment with access.
33+ If downstream then fails, fix forward with a patch release.
34+
2835## Step 1: Check Latest Versions
2936
3037From the template repo, check what’s current on PyPI:
@@ -226,6 +233,10 @@ Pick the version by what changed:
226233- ** Patch** (` v0.2.28 ` ): routine dependency and tool-version bumps, doc fixes, and
227234 changes that leave the render’s shape alone.
228235
236+ Review the changes and author the release notes as a file first (the gitignored ` tmp/ `
237+ directory is the convention; a file keeps the shell out of the way, since notes
238+ routinely contain backticks and ` $ ` ):
239+
229240``` shell
230241# From the template repo:
231242cd ../simple-modern-uv
@@ -236,28 +247,25 @@ NEW_TAG="v0.X.Y"
236247git log " ${LAST_TAG} ..HEAD" --oneline
237248git diff --stat " ${LAST_TAG} ..HEAD"
238249
250+ # Write tmp/release-notes-${NEW_TAG}.md, then:
239251gh release create " $NEW_TAG " \
240252 --repo jlevy/simple-modern-uv \
241253 --target " $TEMPLATE_COMMIT " \
242254 --title " $NEW_TAG " \
243- --notes " $( cat << EOF
244- ## What's Changed
245-
246- - **Updated dev dependencies**: ruff X.Y.Z, basedpyright X.Y.Z, etc.
247- - **Updated uv** to X.Y.Z in CI workflows
248- - **New/changed template questions** (if any): name each key, its choices, and its
249- default
250- - Any other changes
251-
252- **Downstream validation**: jlevy/simple-modern-uv-template CI passed for ${TEMPLATE_COMMIT: 0: 7}
253-
254- **Full Changelog**: https://github.com/jlevy/simple-modern-uv/compare/${LAST_TAG} ...${NEW_TAG}
255- EOF
256- ) "
255+ --notes-file " tmp/release-notes-${NEW_TAG} .md"
257256```
258257
259- This makes the release visible to users and provides clear release notes on what was
260- updated.
258+ Structure the notes per ` tbd guidelines release-notes-guidelines ` (or the same format
259+ the template’s own ` docs/publishing.md ` describes): a one-paragraph summary of the
260+ release’s theme, ` ### New Features ` / ` ### Improvements ` sections, an upgrading note for
261+ existing projects, new question keys with their defaults (per the answer-schema policy),
262+ a statement of what validation backed the release, and the
263+ ` compare/${LAST_TAG}...${NEW_TAG} ` link.
264+
265+ Afterwards, verify the release: the tag points at ` $TEMPLATE_COMMIT `
266+ (` gh release view "$NEW_TAG" --json tagName,targetCommitish,isDraft ` ) and a fresh
267+ ` copier copy gh:jlevy/simple-modern-uv ` records the new tag as ` _commit ` in
268+ ` .copier-answers.yml ` .
261269
262270## Step 8: Record the Release Tag Downstream
263271
0 commit comments