|
1 | 1 | --- |
2 | 2 | name: release-changelog |
3 | | -description: Use when editing, auditing, or preparing Newton CHANGELOG.md for a release, especially to make upgrade-impact information actionable for developers. |
| 3 | +description: Use when auditing Newton changelog fragments, building a dated release changelog, or synchronizing a release build back to main. |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | # Newton Release Changelog |
7 | 7 |
|
8 | | -Maintain `CHANGELOG.md` as the detailed upgrade source of truth. Release notes |
9 | | -and release announcements carry the high-level summary; the changelog should |
10 | | -preserve specific breaking changes, removals, deprecations, behavior/default |
11 | | -changes, dependency constraints, and migration guidance. |
12 | | - |
13 | | -## Workflow |
14 | | - |
15 | | -1. Protect released history first. Diff `CHANGELOG.md` from the latest stable |
16 | | - tag and inspect every hunk under a dated version header. Move late PR entries |
17 | | - accidentally added to a released section into the current `[Unreleased]` |
18 | | - section. Change released history only with explicit maintainer approval. |
19 | | -2. Identify the release ref and comparison base. For final releases, use the |
20 | | - final tag or release branch. For RC prep, use the latest RC tag as temporary |
21 | | - ground truth and verify against the previous released tag. |
22 | | -3. Read the current `CHANGELOG.md` section being edited, the release audit if |
23 | | - one exists, and PRs behind unclear entries. Do not rely only on commit |
24 | | - subjects for migration guidance. |
25 | | -4. Check completeness from the previous GA or micro release through the release |
26 | | - ref, including RC fixes. Compare the range with the release audit and add |
27 | | - missed user-visible changes. |
28 | | -5. Preserve information. Rephrase, split, merge, and regroup entries only when |
29 | | - the facts remain intact. Ask before deleting information, omitting a |
30 | | - questionable entry, or downgrading a user-visible change to silence. |
31 | | -6. Use the existing Keep-a-Changelog categories (`Added`, `Changed`, |
32 | | - `Deprecated`, `Removed`, `Fixed`). Keep migration and retesting guidance in |
33 | | - the affected entries; release notes carry the summary. |
34 | | -7. Within each category, group entries by the current release's user-facing |
35 | | - feature areas or migration themes when this improves readability. |
36 | | -8. Remove exact and semantic duplicates within the release, not only identical |
37 | | - wording. If a feature and a fix for that feature both landed during the same |
38 | | - release cycle, consolidate the entries around the final user-visible |
39 | | - behavior instead of recording it once as `Added` and again as `Fixed`. |
40 | | -9. Audit category boundaries before finalizing. Keep `Added` for new public |
41 | | - APIs, options, features, examples, and docs; move existing-API behavior |
42 | | - changes, new warnings, default changes, and importer/solver semantics into |
| 8 | +Pending user-facing changes live in Towncrier fragments under `changelog/`. |
| 9 | +`CHANGELOG.md` is generated only on a release branch. Shipped sections are |
| 10 | +immutable; the assembled section for the pending release remains a rolling |
| 11 | +document until tagging. Follow `changelog/README.md` as the command and format |
| 12 | +authority. |
| 13 | + |
| 14 | +## Audit pending changes |
| 15 | + |
| 16 | +1. Identify the release ref and comparison base. Audit `release-X.Y` once it |
| 17 | + exists; otherwise audit the intended main ref. |
| 18 | +2. Protect released history. Diff `CHANGELOG.md` from the latest stable tag and |
| 19 | + require explicit maintainer approval for edits to dated sections. |
| 20 | +3. Render a non-mutating preview, which also validates Towncrier's renderable |
| 21 | + fragment filenames: |
| 22 | + ```bash |
| 23 | + uvx --from towncrier==25.8.0 towncrier build --draft \ |
| 24 | + --version X.Y.Z --date YYYY-MM-DD |
| 25 | + ``` |
| 26 | +4. Compare the preview with the release audit and commit range from the previous |
| 27 | + release. Inspect `.skip` reasons separately. |
| 28 | +5. Preserve information. Rephrase, split, merge, or recategorize fragments only |
| 29 | + when the facts remain intact. Ask before deleting information or downgrading |
| 30 | + a user-visible change. |
| 31 | +6. Use only `Added`, `Changed`, `Deprecated`, `Removed`, and `Fixed`, in that |
| 32 | + order. Keep migration and retesting guidance in affected entries. |
| 33 | +7. Remove exact and semantic duplicates. When a feature and its fix both land |
| 34 | + in one cycle, describe the final user-visible behavior once. |
| 35 | +8. Keep `Added` for new public APIs, options, features, examples, and docs. Put |
| 36 | + existing-API behavior, warning, default, importer, and solver changes in |
43 | 37 | `Changed`, even when they expand support. |
44 | | -10. Add same-repository PR references as compact `(#NNNN)` references |
45 | | - selectively, not mechanically. Prioritize high-importance entries: |
46 | | - breaking/default-changing behavior, public API additions that affect |
47 | | - migration, deprecations, removals, and major support fixes. Do not add PR |
48 | | - refs to every routine docs, example, cleanup, or minor fix entry. |
49 | | -11. Before adding a PR reference, verify that the PR actually introduced the |
50 | | - change being cited. Prefer local history such as `git log --oneline` and |
51 | | - `git show --name-only <commit>`; skip ambiguous references rather than |
52 | | - guessing. |
53 | | -12. For each breaking, removed, deprecated, or default-changing entry, include |
54 | | - migration guidance or a clear action: replacement symbol, opt-out flag, |
55 | | - compatibility setting, or what to re-test. |
56 | | -13. Avoid directing users to private/internal APIs as migration targets. If a |
57 | | - public alias is deprecated because storage is becoming internal, say to avoid |
58 | | - depending on that data directly rather than pointing at underscore-prefixed |
59 | | - members. |
60 | | -14. Separate internal cleanup from public API removals. If an internal symbol is |
61 | | - mentioned for completeness, label it as internal and do not imply users must |
62 | | - migrate unless it was public. |
63 | | -15. Verify restored APIs against the final/RC tag before classifying removals. |
64 | | - For example, if a public symbol was removed during development but restored |
65 | | - before the release tag, do not list it as removed. |
66 | | -16. When moving entries between release sections, make sure the information is |
67 | | - not duplicated under an older released version and the historical section |
68 | | - still reflects what actually shipped there. |
69 | | -17. Perform a second editorial pass after regrouping. Re-read the source entries |
70 | | - and the final diff to catch user-relevant behavior, limitations, opt-in |
71 | | - conditions, changed defaults, compatibility details, or migration actions |
72 | | - lost during condensation. |
73 | | - |
74 | | -## Post-release reconciliation |
75 | | - |
76 | | -Merge a release branch's finalized changelog back to `main` through a dedicated |
77 | | -feature branch and changelog-only PR: |
78 | | - |
79 | | -1. Fetch the canonical remote and create the feature branch from the latest |
80 | | - `upstream/main`, not from the release branch. |
81 | | -2. Use the final tag as the source of truth. |
82 | | -3. Keep `## [Unreleased]` first and preserve all post-cut entries not shipped |
83 | | - in the release. Do not replace the whole file with the release-branch copy. |
84 | | -4. Insert the finalized release section immediately below `[Unreleased]` and |
85 | | - keep shipped entries only in that dated section. Resolve semantic overlap so |
86 | | - the same user-facing change is not recorded twice. |
87 | | -5. Verify that only `CHANGELOG.md` changes, the dated section matches the final |
88 | | - tag, and older released sections remain unchanged. |
| 38 | +9. Give every breaking, removed, deprecated, or default-changing entry a |
| 39 | + concrete action. Never direct users to `newton._src`. |
| 40 | +10. A numeric fragment identifier is a GitHub issue number. Towncrier renders |
| 41 | + its issue link automatically; do not rewrite it as a pull request number. |
89 | 42 |
|
90 | | -## Checks |
| 43 | +## Assemble the release during RC stabilization |
| 44 | + |
| 45 | +After the initial release scope has been audited on `release-X.Y`, assemble the |
| 46 | +current fragments early enough for maintainer review: |
| 47 | + |
| 48 | +```bash |
| 49 | +uvx --from towncrier==25.8.0 towncrier build --draft \ |
| 50 | + --version X.Y.Z --date YYYY-MM-DD |
| 51 | +uvx --from towncrier==25.8.0 towncrier build --yes \ |
| 52 | + --version X.Y.Z --date YYYY-MM-DD |
| 53 | +git rm --ignore-unmatch "changelog/*.skip" |
| 54 | +git add -A CHANGELOG.md changelog |
| 55 | +``` |
| 56 | + |
| 57 | +Review and approve the draft before running the mutating command. Towncrier |
| 58 | +inserts the dated section below `[Unreleased]` and deletes rendered fragments. |
| 59 | +It ignores `.skip` files, so remove those explicitly. Review the staged diff in |
| 60 | +a changelog-only pull request labeled `release-management`. |
| 61 | + |
| 62 | +After assembly, apply the audit rules above to the dated section: verify |
| 63 | +completeness, grouping, deduplication, wording, categories, and migration |
| 64 | +guidance. Keep editorial cleanup in the changelog-management commits that will |
| 65 | +later be synchronized to `main`. |
91 | 66 |
|
92 | | -Run targeted searches before finishing: |
| 67 | +The first Towncrier release requires one migration audit. The insertion marker |
| 68 | +sits above the legacy `[Unreleased]` entries so they remain under the first |
| 69 | +generated release title. Merge duplicate category headings without dropping or |
| 70 | +duplicating an entry. Later releases need no special handling. |
| 71 | + |
| 72 | +Treat the assembled section as a rolling document. For every later cherry-pick |
| 73 | +before tagging: |
| 74 | + |
| 75 | +1. Validate the new fragments and render them with `towncrier build --draft`. |
| 76 | +2. Fold the previewed entries into the existing dated section without creating |
| 77 | + a second release heading. |
| 78 | +3. Delete exactly the consumed `.md` and `.skip` fragments, then stage |
| 79 | + `CHANGELOG.md` and `changelog/`. |
| 80 | +4. Rerun the changelog cleanup and `release-audit` checks, and merge the update |
| 81 | + as another changelog-only `release-management` pull request. |
| 82 | + |
| 83 | +Final GA preparation verifies the completed section and confirms that no |
| 84 | +release-branch fragments remain. Do not postpone the full cleanup until GA. |
| 85 | + |
| 86 | +## Synchronize to main |
| 87 | + |
| 88 | +After tagging: |
| 89 | + |
| 90 | +1. Create a changelog-only branch from current `main`. |
| 91 | +2. Cherry-pick, in order, every changelog-management commit from `release-X.Y`: |
| 92 | + the initial Towncrier build, editorial cleanup, and all later cherry-pick |
| 93 | + additions. |
| 94 | +3. Confirm fragments deleted by those commits disappear while fragments added to |
| 95 | + `main` after the branch cut remain under `changelog/`. |
| 96 | +4. Confirm the dated section matches the release tag and older history is |
| 97 | + unchanged. |
| 98 | +5. Open a changelog-only pull request labeled `release-management`. |
| 99 | + |
| 100 | +Do not replace the whole file with the release-branch copy. The commits' |
| 101 | +path-level deletions are what preserve main-only fragments. |
| 102 | + |
| 103 | +## Checks |
93 | 104 |
|
94 | 105 | ```bash |
95 | | -git diff v<latest-release> -- CHANGELOG.md |
96 | | -git log --oneline <previous-release>..<release-ref> |
97 | | -rg -n "removed|removal|deprecated|will be removed|in favor of|use .* instead|renam|replac|default|breaking" CHANGELOG.md |
98 | | -git diff -- CHANGELOG.md |
| 106 | +uvx --from towncrier==25.8.0 towncrier build --draft \ |
| 107 | + --version X.Y.Z --date YYYY-MM-DD |
| 108 | +git diff v<latest-release> -- CHANGELOG.md changelog |
| 109 | +git diff --cached --name-status -- CHANGELOG.md changelog |
| 110 | +rg -ni "removed|deprecated|in favor of|use .* instead|renam|replac|default|breaking" \ |
| 111 | + CHANGELOG.md changelog |
99 | 112 | ``` |
100 | 113 |
|
101 | | -Confirm that no new hunk lands in a released section, then check for missing or |
102 | | -duplicate entries, accidental deletions, stale removal targets, and missing |
103 | | -migration guidance or PR references. |
| 114 | +Confirm that `[Unreleased]` is empty after the first migration, no dated history |
| 115 | +changed, released entries appear exactly once, and post-cut main fragments |
| 116 | +survive synchronization. |
0 commit comments