How do I generate release notes?

Table of Contents

This recipe is what the Sprint closure phase calls into. The companion sprint-opening flow is How do I open a new sprint?.

Question

I'm closing a sprint. How do I assemble release notes from the merged PRs and the sprint's stories, then cut a draft GitHub release?

Answer

The whole pipeline runs through compass release-notes — five verbs, run in order, from a task branch off main (never directly on main).

  1. Prepare a fresh branch. Run on a branch (e.g. feature/release-notes-sprint-<N>) rather than main:

    git fetch origin main
    git checkout -b feature/release-notes-sprint-<N> origin/main
    
  2. Create: collect merged-PR data since the last release tag and render the release notes org file in one step:

    ./compass.sh release-notes create --sprint <N>
    

    Internally this runs collect_release_pr_data.py (auto-detects the previous v* tag via git tag --sort-v:refname=; pass --since-tag v0.0.<N-1> explicitly if a tag for the sprint being closed already exists — otherwise PR collection picks up its own tag as "latest" and undercounts) then generate_release_notes.py (parses sprint.org and every story.org, extracts story descriptions, groups them into sections via TAG_TO_SECTION, derives Highlights from the retrospective, renders doc_release_notes.org.mustache). gh must be authenticated.

    Read the closing sprint's sprint.org too — the * Stories table and per-story states (DONE / STARTED / BLOCKED / ABANDONED) are not fully captured by PRs alone; the sprint backlog tells you what should have shipped, PRs tell you what did ship, the release notes reconcile both.

  3. Fill in the blurbs. release_notes.org has two (( ... )) placeholders (opening paragraph, "Next sprint" line) — replace both. Keep the opening paragraph 4–6 sentences, honest: if the sprint missed its mission or overran, say so (sprints 18, 19, and 21 are the model).

    Under each sprint chart, add a short commentary paragraph reading this sprint's data — peaks, outliers, and what they correspond to — not just the generic legend text.

  4. Charts: render the sprint's gnuplot health charts:

    ./compass.sh release-notes charts --sprint <N>
    
  5. Export: batch-export release_notes.org to GitHub-flavoured Markdown — this is the file that ships verbatim as the GitHub release body:

    ./compass.sh release-notes export --sprint <N>
    
  6. Capture the readme screenshot. Take a fresh screenshot of the running Qt client (e.g. via the QA Validation Runner panel's screenshot button, or a desktop screenshot tool) and save it as assets/images/ore_studio-v0.0.<N>.png. Do not wire it into readme.org here — the readme should show the last released version, so it only gets pointed at this screenshot once sprint N itself closes and N+1 opens; see How do I bump the project version? step 5d.
  7. Commit: stage, commit, and push release_notes.org=/.md=, the four chart PNGs, the new screenshot, and the readme update. There is no separate "upload images" step for the charts — the markdown embeds them via raw.githubusercontent.com/.../main/... URLs, so they only render correctly once merged to main:

    ./compass.sh release-notes commit --sprint <N>
    
  8. Open the PR via PR Manager. Merge once green — this is what makes the chart images resolve on main.
  9. Draft: tag main and open a draft GitHub release. A codename is invented per release (house convention: v0.0.20, "Capopolo") — --codename is required:

    ./compass.sh release-notes draft --sprint <N> --codename <Codename>
    

    Idempotent: safe to re-run if the tag or release already exists (e.g. tagged ahead of time, or fixing the title/body after the fact) — reuses/updates in place, including the title, without losing the tag/PR/notes work already done. The release stays in draft so a human can add screenshots/binaries and publish.

Template skeleton

# **ORE Studio Sprint N – Release Notes**
*Month Year*

One-paragraph summary of the sprint's focus and outcomes.
---

## ✅ **Highlights**

- ...

## 🛠️ **Key Improvements**

### **Theme A**
- ...

### **Theme B**
- ...

## ⚠️ **Known Issues & Postponed**

- ...

## 📊 **Time Summary**

**Total effort**: Xh Ym
**Code**: A% | **Infra**: B% | **Agile/Analysis/Doc**: C%

---

*Next sprint: one sentence summarising the upcoming mission.*

Script

./compass.sh release-notes (compass_release_notes.py) is the entry point for all five verbs. It wraps build/scripts/collect_release_pr_data.py and build/scripts/generate_release_notes.py (create), delegates to compass sprint charts (charts), batch-runs ores-build-release-notes.el via Emacs (export), and shells to git=/=gh directly for commit and draft.

Tested by

Manual. The script is exercised every sprint closure.

See also

Emacs 29.3 (Org mode 9.6.15)