Skip to content

Commit a11e1c2

Browse files
committed
Update changelog for upcoming release
1 parent 072bce0 commit a11e1c2

2 files changed

Lines changed: 391 additions & 3 deletions

File tree

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
---
2+
name: draft-release-notes
3+
description: Draft the Unreleased section of CHANGELOG.md by running .github/scripts/draft-change-log-entries.sh, classifying each PR from its real diff, and producing clean user-facing entries. Use when asked to prepare, update, or clean up the Unreleased section of CHANGELOG.md.
4+
---
5+
6+
# Draft Release Notes Skill
7+
8+
This skill turns the raw output of `.github/scripts/draft-change-log-entries.sh`
9+
into a curated `## Unreleased` section in `CHANGELOG.md`.
10+
11+
The rules below are baked in from previous drafting passes on this repo. Follow
12+
them directly rather than re-deriving them.
13+
14+
## When to Use
15+
16+
- Asked to draft, refresh, or clean up the `## Unreleased` section of
17+
`CHANGELOG.md`.
18+
- Asked to categorize a batch of recent PRs into release-note sections.
19+
- Asked to decide whether a specific PR is a breaking change, deprecation,
20+
enhancement, or bug fix.
21+
22+
## Prerequisites
23+
24+
- `gh` CLI authenticated (needed for label-based extraction inside the script
25+
and for inspecting individual PR diffs).
26+
- `git` available with local branches up to date.
27+
- You are operating on the repository root.
28+
29+
## Section Order
30+
31+
Use exactly this order. Omit any section that ends up empty.
32+
33+
1. `### ⚠️ Breaking changes to non-stable APIs`
34+
2. `### 🚫 Deprecations`
35+
3. `### 🌟 New javaagent instrumentation`
36+
4. `### 🌟 New library instrumentation`
37+
5. `### 📈 Enhancements`
38+
6. `### 🛠️ Bug fixes`
39+
7. `### 🧰 Tooling` (only if it carries user-facing tooling changes)
40+
41+
## Workflow
42+
43+
### 1. Generate the raw draft
44+
45+
```bash
46+
.github/scripts/draft-change-log-entries.sh | tee out
47+
```
48+
49+
The script:
50+
51+
- Computes the commit range since the last release tag.
52+
- Pulls PRs labeled `breaking change` and `deprecation` via `gh`.
53+
- Flags commits whose diff adds or removes `@Deprecated` on `src/main` files.
54+
- Groups remaining commits by whether they touch `src/main/`.
55+
56+
Keep the `out` file around for the whole pass; you will re-read it per PR.
57+
Delete it at the end.
58+
59+
If the script fails (usually `gh` not authenticated), fix that before
60+
continuing. Do not hand-roll the list.
61+
62+
### 2. Read the current CHANGELOG
63+
64+
Read the top of `CHANGELOG.md` and identify the `## Unreleased` block. Only
65+
this block may be modified. Never touch prior versioned releases.
66+
67+
If the block is completely empty, start from an empty set of entries. If it
68+
already has content, treat each existing bullet as a provisional classification
69+
to re-verify against the draft output.
70+
71+
### 3. Classify each PR from its real diff
72+
73+
For every PR number in the draft output, decide its section from the diff,
74+
not from the PR title. Use these signals:
75+
76+
- `gh pr view <NNNN> --json title,files --jq '{title, files: [.files[].path]}'`
77+
- `gh pr diff <NNNN> --patch` (use this when the local squash commit is empty
78+
or when you need to read actual code changes)
79+
- `git log --grep '#NNNN'` and `git show <sha>` for local history
80+
81+
Then apply the rules in the next section.
82+
83+
### 4. Apply the classification rules
84+
85+
#### Breaking changes to non-stable APIs
86+
87+
Put under this section when the PR removes or changes a public method,
88+
interface, class, or signature in a non-stable (`-alpha`) module or in an
89+
`internal` / experimental extension API.
90+
91+
- The `#### Possible breaking changes (diff removes @Deprecated)` block in the
92+
draft output is the strongest signal.
93+
- Also inspect PRs that touch `javaagent-extension-api` and any
94+
`*/internal/**` package — removing a `default` method from an internal
95+
experimental interface is a breaking change to a non-stable API even if the
96+
class is marked `internal`.
97+
- Example from a prior pass: PR #17812 removed
98+
`ExperimentalInstrumentationModule.isIndyReady()` from the internal
99+
experimental extension API. That belonged in Breaking changes even though
100+
its per-module overrides looked like cleanup.
101+
102+
Entries here describe what was removed/changed and where, not the motivation.
103+
104+
#### Deprecations
105+
106+
Put under this section when the PR deprecates user-facing API or config
107+
without removing it.
108+
109+
- The `#### Possible deprecations (diff adds @Deprecated)` block in the draft
110+
output is the strongest signal for Java API deprecations.
111+
- Configuration property renames always belong here, not in Enhancements.
112+
Name the **old** and **new** user-facing property and/or declarative YAML
113+
key. Use the flat system property name in the user-facing text, because that
114+
is what most users configure.
115+
- When the same PR renames both a builder method and a property, describe
116+
both in one bullet.
117+
118+
See `.github/agents/knowledge/api-deprecation-policy.md` and
119+
`.github/agents/knowledge/config-property-stability.md` for the authoritative
120+
policy. The one-line summary:
121+
122+
- Stable property/API: may be deprecated in any minor; may only be removed in
123+
a major.
124+
- Experimental property (name contains `experimental` or YAML key ends with
125+
`/development`): may be deprecated and removed in a later release.
126+
127+
#### New javaagent instrumentation / New library instrumentation
128+
129+
Only use when the PR adds a brand-new instrumentation module under
130+
`instrumentation/<name>/javaagent/**` or `instrumentation/<name>/library/**`.
131+
Renaming or extracting an existing module does not count.
132+
133+
Confirm via the PR's file list:
134+
135+
- New module: a new `instrumentation/<name>/javaagent/build.gradle.kts` (or
136+
`library/build.gradle.kts`) together with new source files and a
137+
`settings.gradle.kts` entry.
138+
- Rename: a module path change with no brand-new coverage of a library.
139+
140+
If no PRs fit, delete both empty section headers from the Unreleased block
141+
before finalizing.
142+
143+
#### Enhancements
144+
145+
User-visible feature additions, new attributes, new config flags, new
146+
stable-semconv support, or observable behavior changes gated on a new or
147+
existing flag.
148+
149+
Examples that belong here: adding a new attribute on a span, adding a stable
150+
`db.system.name` emission, adding a new config toggle under `v3_preview`,
151+
adding schema URL on an instrumenter, optimizing an observable hot path.
152+
153+
#### Bug fixes
154+
155+
Observable bug fixes: wrong attribute values, missing spans, NPEs, memory
156+
leaks, crashes, latest-dep compatibility fixes that users would notice.
157+
158+
Prefer describing the user-visible symptom or the concrete remediation (for
159+
example "Prevent duplicate OpenTelemetry Logback appenders in Spring starter"
160+
rather than "fix duplicate appender registration").
161+
162+
#### Omit entirely
163+
164+
Do **not** create entries for:
165+
166+
- Pure refactoring or code cleanup.
167+
- Style-only changes (naming conventions, `final` changes, null comparisons).
168+
- Test-only changes, cross-testing, moving tests out of default packages.
169+
- Muzzle-only CI fixes with no runtime behavior change.
170+
- Renames of internal fields, internal packages, or internal helpers.
171+
- Gradle / build-script internal tweaks that do not change published artifacts
172+
or published behavior.
173+
- `renovate[bot]` dependency bumps (the script already filters them; keep
174+
them filtered).
175+
176+
If in doubt, re-read the PR diff. Entries in Unreleased must describe an
177+
observable change that a user could notice.
178+
179+
### 5. Wording rules
180+
181+
- One sentence per bullet. Imperative or descriptive, consistent with prior
182+
releases.
183+
- Name concrete user-facing surfaces: flag names, property names, class names,
184+
attribute names. Prefer flag values over internal mechanisms. For semconv
185+
opt-ins, cite the actual flag like
186+
`otel.semconv-stability.opt-in=messaging`, not "via SemconvStability".
187+
- Use backticks for config keys, property names, attributes, and class/method
188+
names.
189+
- Do not describe implementation details ("refactored", "moved", "simplified")
190+
unless that is the user-visible change itself.
191+
- Do not credit authors.
192+
193+
### 6. Link format
194+
195+
Each entry ends with the PR link on its own line, two-space indented:
196+
197+
```markdown
198+
- Short user-facing description
199+
([#NNNN](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/NNNN))
200+
```
201+
202+
If multiple PRs share one logical change, group them on one trailing line:
203+
204+
```markdown
205+
- Short user-facing description
206+
([#AAAA](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/AAAA),
207+
[#BBBB](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/BBBB))
208+
```
209+
210+
Some Deprecations bullets intentionally have no PR link (they summarize
211+
multiple earlier renames). Leave those as-is if they already exist.
212+
213+
### 7. Sort order inside each section
214+
215+
Within each populated section, sort PR-linked entries by ascending PR number.
216+
Unlinked bullets (if any) stay at the top of their section in their current
217+
order.
218+
219+
After reordering, do a readback of the whole `## Unreleased` block and
220+
visually confirm monotonic PR numbers in each section.
221+
222+
### 8. Handling tricky cases
223+
224+
- **Empty local squash commit**: if `git show` for a PR is empty, use
225+
`gh pr diff <NNNN> --patch` to get the real diff.
226+
- **PR that touches both user-facing behavior and internal cleanup**:
227+
classify on the user-facing part. Ignore the cleanup aspect.
228+
- **PR that renames a config property**: always Deprecations, never
229+
Enhancements. Name both old and new property. Remove any stray Enhancements
230+
bullet that duplicates it.
231+
- **PR that looks like an Enhancement but only changes internal wiring**:
232+
omit.
233+
- **Property rename bullets with no PR link**: keep in Deprecations at the top
234+
of that subsection if already present; do not invent PR links for them.
235+
236+
### 9. Finalize
237+
238+
1. Delete any Unreleased sub-section that ended up empty.
239+
2. Re-read the full `## Unreleased` block end-to-end and sanity-check:
240+
- Section order matches the canonical order above.
241+
- Each populated section is PR-number-sorted.
242+
- No cleanup/refactor-only bullets slipped in.
243+
- Config renames appear exactly once, under Deprecations.
244+
- Every bullet names a concrete user-facing surface.
245+
3. Run `git diff CHANGELOG.md` to confirm only `## Unreleased` changed.
246+
4. Delete the temporary `out` file.
247+
5. Summarize counts per section for the user (for example "Breaking: 1,
248+
Deprecations: 9, Enhancements: 18, Bug fixes: 31").
249+
250+
## Reference Knowledge
251+
252+
- `.github/agents/knowledge/api-deprecation-policy.md` — deprecate-then-remove
253+
timing, stable vs alpha rules, required Javadoc/CHANGELOG coverage.
254+
- `.github/agents/knowledge/config-property-stability.md` — stable vs
255+
experimental property policy, deprecation communication, naming
256+
conventions.
257+
- `.github/scripts/draft-change-log-entries.sh` — the source of the raw
258+
draft. Read it if you need to understand exactly what the sub-sections
259+
mean.

0 commit comments

Comments
 (0)