mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 19:46:16 -08:00
Backfills the 0.23.0 release notes the .changes/ pipeline missed: it landed after most of the release was already merged, leaving 4 notes for 79 commits. Adds 22 curated notes (26 total: 14 features, 11 fixes, 1 perf). Curated rather than exhaustive — the GitHub release body renders these above GitHub's own list of every merged PR, so related PRs are folded into one note per user-facing story: shared player controls (8 PRs), embedded MPV frame-copy (4), manual EPG mapping (3), plus five more pairs. Tooling-only scopes get no note. No screenshot slugs: none of the five manifest shots depicts a 0.23 headline feature, and the capture run asserts TMDB enrichment stays disabled. Two tooling fixes found while writing them: - parseArgs now ignores a bare `--`. npm needs it to forward arguments past the script name; pnpm hands it to the script verbatim, so `pnpm run release:notes:github -- --version 0.24.0` died on the very separator typed to make forwarding work. Unknown flags and missing values still fail as before. Covered by new subprocess CLI tests wired into the release-tools target. - .changes/README.md claimed every non-consume mode was a safe dry run; --format changelog and --format blog write their target file. No app or lib code, no version bump, no --consume, no CHANGELOG.md or website changes — those stay owned by release-cut.
121 lines
5.0 KiB
Markdown
121 lines
5.0 KiB
Markdown
# Release notes (`.changes/`)
|
|
|
|
Every PR with a user-visible change drops one file here describing that change
|
|
in plain language. At release time
|
|
`tools/release/build-release-notes.mjs` turns the accumulated files into the
|
|
GitHub release body, the `CHANGELOG.md` section, and a blog-post scaffold for
|
|
the website — then deletes them.
|
|
|
|
The point is to write the note **while the context is still fresh**, instead of
|
|
reconstructing three months of work from commit titles at release time.
|
|
|
|
## File
|
|
|
|
Name it `<area>-<short-slug>.md`, e.g. `.changes/playback-up-next-rail.md`.
|
|
|
|
```markdown
|
|
---
|
|
type: feature
|
|
area: playback
|
|
issues: [1187]
|
|
screenshot: up-next-rail
|
|
---
|
|
|
|
Series now show an "Up Next" rail beside the player on wide windows: the rest
|
|
of the current season, watch progress, and click-to-play inline.
|
|
```
|
|
|
|
| Field | Required | Value |
|
|
| ------------ | -------- | ----------------------------------------------------------- |
|
|
| `type` | yes | `breaking`, `feature`, `fix`, `perf`, or `internal` |
|
|
| `area` | yes | lowercase slug, same as the conventional-commit scope |
|
|
| `issues` | no | issue numbers this closes — `[1187]` or `1187` |
|
|
| `screenshot` | no | slug from `tools/release/screenshots.manifest.json` |
|
|
|
|
There is **no version field**. The release version is chosen deliberately at
|
|
release time, not derived from these files.
|
|
|
|
You never write a PR number: the generator resolves it from the commit that
|
|
added the file.
|
|
|
|
## Writing the body
|
|
|
|
One to three sentences, present tense, **written for a user, not a reviewer**.
|
|
The body is capped at 400 characters — depth belongs in the blog post.
|
|
|
|
- ❌ "Refactor `WebVideoControlsAdapter` to hoist volume state into the session"
|
|
- ✅ "The player now remembers volume between episodes"
|
|
|
|
- ❌ "Fix off-by-one in `resolveEnrichmentSeasonNumber`"
|
|
- ✅ "Series whose title carries a season marker no longer show the wrong season"
|
|
|
|
`type: internal` is for changes with no user-visible effect that are still worth
|
|
recording (dependency bumps with behaviour risk, packaging moves). They stay out
|
|
of the release body and blog post, and land collapsed in `CHANGELOG.md`.
|
|
|
|
## When a note is not needed
|
|
|
|
Skip the note — and apply the `no-release-note` label — for test-only changes,
|
|
docs, CI/workflow plumbing, and pure refactors with no behaviour change.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
pnpm run release:notes:validate
|
|
pnpm run release:notes:github
|
|
pnpm run release:notes:changelog
|
|
pnpm run release:notes:blog
|
|
node tools/release/build-release-notes.mjs --consume
|
|
```
|
|
|
|
The release version comes from the root `package.json` — bump it first, then
|
|
generate. `--version 0.24.0` overrides it to preview a release before the bump:
|
|
|
|
```bash
|
|
pnpm run release:notes:github --version 0.24.0
|
|
```
|
|
|
|
A bare `--` separator is accepted and ignored, so the npm habit of
|
|
`pnpm run release:notes:github -- --version 0.24.0` works too: pnpm forwards
|
|
that separator to the script rather than consuming it the way npm does.
|
|
|
|
`--validate` and `--format github` only read and print. `--format changelog`
|
|
and `--format blog` write their target file (rerunning `changelog` for the same
|
|
version replaces that section rather than duplicating it). Only `--consume`
|
|
deletes anything.
|
|
|
|
The release sequence is: bump the version → `release:notes:changelog` →
|
|
`release:notes:blog` → `--consume` → commit → tag → push. The tag build then
|
|
extracts the new `CHANGELOG.md` section into the GitHub release body
|
|
(`tools/release/extract-changelog-section.mjs`) and **fails the release** if
|
|
the section is missing — a tag cut without the changelog step cannot silently
|
|
ship PR-title-only notes.
|
|
|
|
The website publishes **one post per minor version** (`v0-18` … `v0-22`), and
|
|
release screenshots live under the matching `blog/v0-24/` directory. A patch
|
|
release therefore edits the existing post rather than generating a new one, so
|
|
`--format blog` refuses to overwrite unless you pass `--force`.
|
|
|
|
## Screenshots
|
|
|
|
`pnpm run release:screenshots` captures every manifest shot in dark and light
|
|
against the built app plus the Xtream mock server — never a real account.
|
|
The run is fail-closed: it proves the real `~/.iptvnator/databases` directory
|
|
(including the SQLite WAL sidecars, checked after Electron exits) was not
|
|
touched, launches the app with an allowlisted environment, records and blocks
|
|
all non-localhost traffic, scans every frame for external resources and
|
|
credential-shaped text, and asserts TMDB enrichment stays disabled. Frames are
|
|
staged outside the repository and published only once every shot and every
|
|
guard has passed.
|
|
|
|
Adding a shot for a new feature = one entry in
|
|
`tools/release/screenshots.manifest.json` (plus, if navigation is new, one
|
|
named action in `tools/release/capture-navigation.ts`).
|
|
|
|
```bash
|
|
pnpm nx run electron-backend:build-e2e # once, before capturing
|
|
pnpm run release:screenshots # all shots, both themes
|
|
pnpm run release:screenshots -- --only dashboard --theme dark
|
|
pnpm run release:screenshots -- --release v0-24
|
|
```
|