|
| 1 | +--- |
| 2 | +description: Draft a CHANGELOG.md entry from the current diff and recent commits, following the format pub.dev's pana analyser expects. Pass an optional version arg to target a specific entry. |
| 3 | +argument-hint: "[version]" |
| 4 | +allowed-tools: Bash, Read, Edit, Write |
| 5 | +--- |
| 6 | + |
| 7 | +# /changelog — draft a CHANGELOG entry from the diff |
| 8 | + |
| 9 | +Reusable across every Dart/Flutter package in the `df_packages` workspace. |
| 10 | +The output **must** satisfy pub.dev's analyser (pana) so the package keeps |
| 11 | +its full score on the "package has a CHANGELOG.md file" and "documents the |
| 12 | +current release" rules. |
| 13 | + |
| 14 | +**The CHANGELOG is for the pub.dev audience — downstream consumers of the |
| 15 | +package.** It is *not* a project diary. Only changes that affect how a |
| 16 | +consumer writes code against this package belong in it. |
| 17 | + |
| 18 | +## What counts as "critical" — these are the only things to include |
| 19 | + |
| 20 | +Include a bullet only when at least one of these is true: |
| 21 | + |
| 22 | +- **Public API change** — anything in `lib/` (excluding files under `lib/src/` |
| 23 | + that are not re-exported, and any `_*.dart` private file) was added, |
| 24 | + removed, renamed, or had its signature changed. |
| 25 | +- **Behavioural change visible to a caller** — same function still exists |
| 26 | + and has the same signature, but the values it returns, the conditions |
| 27 | + under which it throws, the order in which it does things, or the |
| 28 | + performance characteristics changed enough to affect callers. |
| 29 | +- **Bug fix that changes runtime behaviour** — fixes that callers would |
| 30 | + notice. Mention the symptom in 5–10 words. |
| 31 | +- **Dependency change visible to consumers** — bumping the SDK constraint, |
| 32 | + changing the minimum Flutter version, adding/removing a required |
| 33 | + dependency, raising the major version of an existing dep. |
| 34 | + |
| 35 | +## What to skip — never include these |
| 36 | + |
| 37 | +Even if they show up large in the diff, leave them out. They are not |
| 38 | +useful to a pub.dev reader looking at your package's changelog. |
| 39 | + |
| 40 | +- **CI / build / workflow changes** — anything under `.github/`, `.gitlab/`, |
| 41 | + or other tooling directories. The release pipeline is internal. |
| 42 | +- **Test changes** — additions, refactors, deletions of test files. |
| 43 | + Tests change all the time and don't affect consumers. |
| 44 | +- **Documentation of any kind** — `README.md`, `CLAUDE.md`, `.github/_README.md`, |
| 45 | + internal ADRs, slash commands, contributor guides, doc-comment edits inside |
| 46 | + source files, example-app README updates. Docs never belong in the |
| 47 | + CHANGELOG. The only doc-related exception: if a previously-undocumented |
| 48 | + public API got formal documentation that *callers* should now read, that |
| 49 | + is still not a changelog item — link it in the README instead. |
| 50 | +- **Lint / formatter / `analysis_options.yaml` changes** — tightening or |
| 51 | + loosening lints is invisible to consumers. |
| 52 | +- **Generated files** — `*.g.dart`, `_src.g.dart`, anything regenerated |
| 53 | + from a script. |
| 54 | +- **Internal renames** — renaming a private class, private function, or a |
| 55 | + file under `lib/src/` that isn't re-exported. If the public API didn't |
| 56 | + change, callers won't notice. |
| 57 | +- **Formatting-only commits** — `dart format` runs, whitespace, comment |
| 58 | + reflow. |
| 59 | +- **Example app changes** — `example/` is a demo, not the package. |
| 60 | +- **Refactors with no behavioural delta** — if the public surface and the |
| 61 | + observable behaviour are unchanged, it doesn't ship in the changelog. |
| 62 | + `refactor:` prefix is allowed only when downstream code may need to |
| 63 | + adjust (e.g. a class moved between barrel exports). |
| 64 | +- **`pubspec_overrides.yaml`, `pubspec.lock`, `.dart_tool/`** — environment |
| 65 | + artefacts. |
| 66 | + |
| 67 | +When in doubt, ask: "would a downstream user of this package notice if I |
| 68 | +left this bullet out?" If the answer is no, leave it out. |
| 69 | + |
| 70 | +## pana requirements — non-negotiable |
| 71 | + |
| 72 | +These are the rules pana enforces. Verify each one before you finish: |
| 73 | + |
| 74 | +1. **Filename:** `CHANGELOG.md` at the package root (sibling of `pubspec.yaml`). |
| 75 | +2. **Top-level heading:** the file starts with `# Changelog` (or some other |
| 76 | + `# `-level heading). Don't remove or rename it. |
| 77 | +3. **Version headings:** each release must be a markdown `##` heading whose |
| 78 | + text contains the version string. Any of these are accepted: |
| 79 | + - `## 1.2.3` |
| 80 | + - `## [1.2.3]` |
| 81 | + - `## v1.2.3` |
| 82 | + - `## [v1.2.3]` |
| 83 | + - With optional trailing date, e.g. `## 1.2.3 - 2026-05-22` |
| 84 | +4. **Version-match:** the version field in `pubspec.yaml` **must** appear |
| 85 | + verbatim as one of the `##` headings. If pubspec is `1.2.3+4`, the |
| 86 | + heading text must include `1.2.3+4` (not just `1.2.3`). pana strips a |
| 87 | + leading `v` and the `[`/`]` brackets before matching. |
| 88 | +5. **Ordering:** newest version on top. pana doesn't strictly require this, |
| 89 | + but every existing entry in this workspace follows it, so keep the |
| 90 | + convention. |
| 91 | +6. **At least one bullet:** an empty version section is allowed by pana but |
| 92 | + useless to readers — write at least one meaningful bullet, or stop and |
| 93 | + tell the user there's nothing to record. |
| 94 | + |
| 95 | +## What you should do |
| 96 | + |
| 97 | +1. **Figure out the target version.** |
| 98 | + - If `$ARGUMENTS` was provided, normalise it (strip any leading `v`, |
| 99 | + strip brackets). Use that exact string. |
| 100 | + - Otherwise, read `version:` from `pubspec.yaml` in the current working |
| 101 | + directory. This must be a **runtime** read at command-execution time, |
| 102 | + not a guess. |
| 103 | + |
| 104 | +2. **Gather the evidence.** Run, in parallel: |
| 105 | + - `git status --porcelain` — what's currently uncommitted. |
| 106 | + - `git diff HEAD` — full uncommitted diff (staged + unstaged). |
| 107 | + - `git log --oneline -n 20` — recent commits. |
| 108 | + - If a previous tag exists, also run `git log <last-tag>..HEAD --format=%s` |
| 109 | + to scope changes since the last release. |
| 110 | + |
| 111 | +3. **Filter the diff against the "critical" rules above** before composing |
| 112 | + any bullets. If a file falls entirely under the skip list, ignore every |
| 113 | + line of its diff. Don't write a bullet you'll then have to delete. |
| 114 | + |
| 115 | +4. **Read the existing `CHANGELOG.md`** so you can: |
| 116 | + - Match the heading style **already used in this file** exactly. |
| 117 | + Don't switch between `## 1.2.3` and `## [1.2.3]` mid-file. |
| 118 | + - Detect whether an entry for the target version already exists. If it |
| 119 | + does, *merge* new bullets into it rather than duplicating the heading. |
| 120 | + - Detect any `## [next]` / `## [unreleased]` placeholders and fold them |
| 121 | + into the new versioned section. |
| 122 | + |
| 123 | +5. **Synthesize bullets.** Group by intent, not by file. One bullet per |
| 124 | + user-visible change. Prefixes — only when they genuinely apply: |
| 125 | + - `breaking:` — public API or documented behaviour change that requires |
| 126 | + downstream code edits. Most important prefix; be conservative. |
| 127 | + - `feat:` — new public functionality. |
| 128 | + - `fix:` — corrects a bug. Mention the symptom in 5–10 words. |
| 129 | + - `perf:` — measurable performance improvement. |
| 130 | + - `refactor:` — only when downstream code might need to adjust (e.g. a |
| 131 | + re-exported class moved). Internal-only refactors are skipped, not |
| 132 | + listed. |
| 133 | + |
| 134 | + Notably absent from the list of acceptable prefixes: `test:`, `ci:`, |
| 135 | + `chore:`, `build:`, `docs:`. If you're tempted to use one of those, |
| 136 | + re-check the skip list — the change probably doesn't belong in the |
| 137 | + CHANGELOG at all. |
| 138 | + |
| 139 | +6. **Verify version-match before writing.** Re-read `pubspec.yaml`. The |
| 140 | + target-version string you're about to insert **must** equal the |
| 141 | + `version:` field (after normalising both for whitespace and the optional |
| 142 | + leading `v`). If they disagree, stop and tell the user — fixing the |
| 143 | + mismatch is their call, not yours. |
| 144 | + |
| 145 | +7. **Apply the change.** Use the `Edit` tool to insert the new section |
| 146 | + directly below the top-level `# Changelog` heading (newest at the top). |
| 147 | + If the target version's section already exists, merge bullets in |
| 148 | + meaningful order (group by prefix), deduplicating. |
| 149 | + |
| 150 | +8. **Final sanity check.** Read the file back and verify: |
| 151 | + - The first `##` heading contains the target version. |
| 152 | + - The target version matches `pubspec.yaml`'s `version:` field. |
| 153 | + - At least one bullet under the new heading. |
| 154 | + - No leftover placeholder sections. |
| 155 | + - No bullets that fall under the skip list slipped in. |
| 156 | + |
| 157 | +9. **Don't commit.** The user controls when to commit. |
| 158 | + |
| 159 | +## Behavioural notes |
| 160 | + |
| 161 | +- Don't invent changes. Every bullet must trace to either the diff or a |
| 162 | + recent commit subject *and* clear the "critical" bar above. |
| 163 | +- Don't pad with vague bullets like "general improvements" — if there's |
| 164 | + nothing critical to list, write one short paragraph in place of the |
| 165 | + version section explaining there are no consumer-visible changes, or |
| 166 | + stop and tell the user. |
| 167 | +- The legacy `- Released @ MM/YYYY (UTC)` line is being phased out — don't |
| 168 | + add it to new entries unless the surrounding file uses it consistently. |
| 169 | +- Be terse. One line per change. No paragraphs. |
| 170 | +- Strict semver: if you spot a breaking change but the patch version was |
| 171 | + bumped instead of the major, flag it for the user before writing the |
| 172 | + entry — don't silently soften the description. |
| 173 | + |
| 174 | +## Arguments |
| 175 | + |
| 176 | +- `$ARGUMENTS` — optional. The version string for the entry (e.g. `0.17.0`). |
| 177 | + If empty, fall back to the `version:` field in `pubspec.yaml`. |
0 commit comments