release-notes: fix --all timeout and migrate all pages to the metadata block#4174
Merged
Conversation
…a block The `update-release-notes` workflow timed out after 15 minutes on its first `--all` run after the unified docs-automation system landed (08ac410). Two problems caused it, both fixed here. ~~ Fast-path: compute PR effort only after the skip check ~~ `_write_page` called `get_prs_from_diff`, which computed per-PR "effort" (commit count + working days) for every PR by fetching `refs/pull/N/head` — about 1s of network per PR. That ran for EVERY page BEFORE the `_is_content_unchanged` check, so an all-unchanged `--all` still paid the full cost: the 4.148 page alone (162 PRs) took ~150s, and across 66 pages the run blew past the agent's 15-minute cap. Split the effort loop out of `get_prs_from_diff` (now a cheap git-log parse) into a new `add_pr_effort()`, and call it from `_write_page` only AFTER the unchanged check passes. Pages that skip now pay zero effort cost. Measured: the 4.148 page went from ~170s to ~0.12s when skipped, and a fully-migrated `--all` now completes in ~30s instead of timing out. ~~ One-time migration: regenerate + re-polish every page ~~ Only 7 of 65 pages carried the machine-readable `RAW PR DATA` metadata block (prs/diff/status/supersede) that the skip check compares; the other 58 were legacy hand-curated pages with no block, so they could never be skipped. This commit runs the full `--all` regeneration so every page now carries the block, then re-polishes all 61 pages from their own raw PR data following TEMPLATE.md — Highlights, grouped New Features (Skia milestone bumps first), Bug Fixes, Platform Support, Community Contributors, and Links. Backport-bot authors (github-actions[bot]) were dropped from the contributor tables. With every page migrated, future workflow runs skip all unchanged pages in seconds and only re-polish the 0-2 pages that actually changed. Also renames `4.148.0-unreleased.md` to `4.148.0.md` (now that `release/4.148.0-rc.1` exists) and adds `4.150.0.md` and `1.54.1.1.md`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
📦 Try the packages from this PRWarning Do not run these scripts without first reviewing the code in this PR. Step 1 — Download the packages bash / macOS / Linux: curl -fsSL https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.sh | bash -s -- 4174PowerShell / Windows: iex "& { $(irm https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.ps1) } 4174"Step 2 — Add the local NuGet source dotnet nuget add source ~/.skiasharp/hives/pr-4174/packages --name skiasharp-pr-4174More options
Or download manually from Azure Pipelines — look for the Remove the source when you're done: dotnet nuget remove source skiasharp-pr-4174 |
…ttribution)
A full Opus 4.8 review pass over all 61 regenerated pages (one reviewer per
batch, cross-checking each page against TEMPLATE.md and its own raw PR data)
found and fixed real quality problems the first polish pass introduced:
* Hallucinated content on 0-PR pages — several historical pages with no PR
data (1.49.0, 1.53.2, 1.54.0, 1.58.0, 1.58.1.1, 1.60.2, 1.60.3) had
invented Skia milestones, APIs, code samples, and bug fixes citing issue
numbers absent from the raw data. Replaced with honest servicing notes.
* Fabricated PR references — e.g. 2.88.0 cited #1733 (belongs to 3.0.0) and
2.88.5/2.88.8 invented features/contributors not in their raw data.
* Bot credits in prose — github-actions[bot]/dependabot[bot]/@github/@Copilot
backport credits were stripped from Highlights, feature bullets, and
Bug Fixes on 2.88.9, 3.116.1, 3.119.1, 3.119.2, 2.88.0 (the no-bots rule
only the visible prose had leaked, the tables were already clean).
* Misc accuracy — duplicate PR listings (1.68.1 #929), a miscategorized
breaking change (2.80.0 enum restore is additive), wrong platform emoji
(Tizen 🤖→📦), a typo (macioS), and an overstated "community drove
everything" claim (3.119.2).
One verified handle correction landed too: 2.80.3 @jerome.laban →
@jeromelaban (confirmed via gh). Raw PR-data blocks were preserved verbatim
throughout; only the polished prose below each block changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
📖 Documentation Preview The documentation for this PR has been deployed and is available at: 🔗 View Staging Site This preview will be updated automatically when you push new commits to this PR. This comment is automatically updated by the documentation staging workflow. |
Previously generate-release-notes.py derived contributor handles from the
local-part of the commit author email (email.split("@")[0]). For GitHub
noreply emails that happens to work, but for everyone else it produced broken
or — worse — wrong @mentions:
jerome.laban@unoplatform.com -> @jerome.laban (dead link)
sebastien.pouliot@gmail.com -> @sebastien.pouliot (dead link)
...@... -> @jon / @martin (pings unrelated real users)
A GitHub login does not exist anywhere in git history, so the local-part is
just a guess. In a community project that means we were failing to credit
contributors and, in the @jon/@martin cases, notifying the wrong people.
Resolve logins authoritatively instead:
1. Prefer the login embedded in a GitHub noreply email (offline, exact, and
preserves repo conventions like @Copilot and the *[bot] suffixes).
2. For every remaining PR, resolve the author login via the GitHub GraphQL
API in batches of 50, cached in scripts/pr-authors.json so future runs
stay warm and offline. Unresolvable authors fall back to a plain name
with no @ and no link rather than a wrong mention.
- _login_from_email now returns the noreply login or None (no more guessing).
- New resolver: load/save_author_cache, _graphql_pr_authors (uses check=False
because `gh api graphql` exits non-zero when any aliased PR in a batch is
missing yet still returns valid data for the rest), resolve_pr_authors.
- get_prs_from_diff also captures the author display name for the fallback.
- format_pr_list renders "by @login" when known, else "by name".
- _write_page/cmd_branch/cmd_all gain --force to regenerate unchanged pages.
scripts/pr-authors.json is committed with 921 resolved authors (0 unresolved)
so the very first CI run needs no API calls for historical PRs.
All existing release pages are regenerated with corrected raw blocks, and the
already-reviewed prose is migrated in place: only the broken handle tokens and
their profile URLs are rewritten (longest-token-first, boundary-safe so
@jerome never clobbers @jeromelaban and @github-actions is left untouched).
No prose wording from the prior review pass is otherwise changed.
Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
versions.json (version-comparison/supersession config) and pr-authors.json
(the GitHub-login cache) are both data files for the documentation-generation
systems. Their only consumers are:
- the release-notes generator (.agents/skills/release-notes/.../generate-release-notes.py)
- the api-diff/docs Cake infra (scripts/infra/docs/docs.cake)
Both already anchor on the repo root, and docs.cake itself lives under
scripts/infra/docs/, so colocate the data with the code that produces the docs
instead of leaving it in the generic top-level scripts/ directory.
- git mv scripts/versions.json -> scripts/infra/docs/versions.json
- git mv scripts/pr-authors.json -> scripts/infra/docs/pr-authors.json
- Update the two code paths (VERSIONS_JSON_PATH and _AUTHOR_CACHE_PATH in the
generator; the ROOT_PATH-relative path in docs.cake).
- Update the prose/links that reference the old locations: writing-docs.md,
api-diff.yml, SKILL.md, and inline docstrings/comments.
Verified with a full `--all` run: the generator loads both files from the new
paths, all 68 existing pages are skipped unchanged, and TOC/index regenerate
identically. No release-note content changes.
Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Deliberately remove the generated 4.148.0 and 4.150.0 release pages, their TOC.yml/index.md navigation entries, and the 134 corresponding author-cache entries (921 -> 787) from scripts/infra/docs/pr-authors.json. This exercises the full create/update path end to end after merge: the update-release-notes workflow's `--all` run should recreate both pages from the release/4.148.0-rc.1 and release/4.150.0-preview.1 branches, re-resolve their PR authors via the GitHub GraphQL API (the cache is now cold for those PRs), repopulate the cache, and re-link both versions in TOC.yml and index.md. The removed PRs are unique to the 4.148/4.150 diff ranges, so no other (skipped) page depends on those cache entries. Co-authored-by: Matthew Leibowitz <mattleibow@live.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The api_diff cache job listed scripts/versions.json explicitly, but that file moved to scripts/infra/docs/versions.json in 6b3189c and is already covered by the sibling scripts/infra/docs/** glob on the same line. Remove the dead path so the config has no reference to a file that no longer exists. repo-deps.py validate still passes (0 uncovered); versions.json and the relocated pr-authors.json are both hashed via scripts/infra/docs/** into the api_diff cache key. Co-authored-by: Matthew Leibowitz <mattleibow@live.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
…lup (R1/R2/R3) The versions.json supersession migration (#4171/#4174) correctly made "which version supersedes which" deterministic via versions.json, but its move from per-push branch runs to a bulk `--all` pass silently regressed three documented behaviours. Pages were migrated in #4174 without the script emitting the data those pages used to contain, so the features were dropped on the next regeneration instead of failing loudly. Three regressions, each restored from a deterministic source (not heuristics): R1 — in-flight naming. 4.148 and 4.150 were written as terminal `{version}.md` and the cleanup pass then deleted the real `{version}-unreleased.md`. Root cause: `--all` picks the rc.1/preview.1 branch as canonical for the version. Fixed with a terminal-vs-in-flight rule in `_page_filename` (suffix-less `release/X.Y.Z` branch exists, or `status: superseded` in versions.json => `{version}.md`; otherwise `{version}-unreleased.md`) plus an ownership filter in `cmd_all` so the line head (main / `release/X.Y.x`) owns the `-unreleased` page and the matching rc/preview branch is deferred instead of colliding. R2 — in-flight `.x` rollup was a servicing-delta instead of the full cumulative rollup. `determine_diff_range` now honors the versions.json `compare_to` first (4.148.0 -> 3.119.4) and only does a servicing delta once the `.0` has actually shipped a stable tag. R3 — the trailing `## Preview N (date)` sections were lost. The original 3.119.2.md (#3763) and TEMPLATE.md have them and SKILL rules 9/10 mandate them, but #4174 deleted them on regen because the script never emitted preview data. `collect_preview_milestones` now enumerates them from the published prerelease git tags within the page's diff range (deduped to the latest build per milestone, dated, with chained compare links). A page rolls up a skipped predecessor minor's previews too, so the 4.148 page lists the 4.147 previews that match its rolled-up PRs. Two separate deterministic sources, no magic: versions.json answers "which version supersedes which"; published tags answer "which previews shipped and when". Documented in code comments (R1/R2/R3) and a new SKILL.md "Page naming & preview rollup" section so this can't silently regress on the next migration. Validated with an offline `--all` dry-run: correct `-unreleased` filenames, 4.148 rolls up 4.147 p1/p2/p3 + rc1, no bare 4.148.0.md/4.150.0.md, 3.119.x unchanged, and the 3.119.2 compare links reproduce the original page exactly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
…lup (R1/R2/R3) (#4179) release-notes: restore in-flight -unreleased naming + per-preview rollup (R1/R2/R3) (#4179) The versions.json supersession migration (#4171/#4174) correctly made "which version supersedes which" deterministic via versions.json, but its move from per-push branch runs to a bulk `--all` pass silently regressed three documented behaviours. #4174 migrated the pages without the script emitting the data those pages used to contain, so the features were dropped on the next regeneration instead of failing loudly. Three regressions, each restored from a deterministic source (not heuristics): R1 — in-flight naming. 4.148 and 4.150 were written as terminal `{version}.md` and the cleanup pass then deleted the real `{version}-unreleased.md`. Root cause: `--all` picks the rc.1/preview.1 branch as canonical for the version. Fixed with a terminal-vs-in-flight rule in `_page_filename` (a suffix-less `release/X.Y.Z` branch exists, or `status: superseded` in versions.json => `{version}.md`; otherwise `{version}-unreleased.md`) plus an ownership filter in `cmd_all` so the line head (main / `release/X.Y.x`) owns the `-unreleased` page and the matching rc/preview branch is deferred instead of colliding. R2 — in-flight `.x` rollup was a servicing delta instead of the full cumulative rollup. `determine_diff_range` now honors the versions.json `compare_to` first (4.148.0 -> 3.119.4) and only does a servicing delta once the `.0` has actually shipped a stable tag. R3 — the trailing `## Preview N (date)` sections were lost. The original 3.119.2.md (#3763) and TEMPLATE.md have them and SKILL rules 9/10 mandate them, but #4174 deleted them on regen because the script never emitted preview data. `collect_preview_milestones` now enumerates them from the published prerelease git tags within the page's diff range (deduped to the latest build per milestone, dated, with chained compare links). A page rolls up a skipped predecessor minor's previews too, so the 4.148 page lists the 4.147 previews that match its rolled-up PRs. Two separate deterministic sources, no magic: versions.json answers "which version supersedes which"; published tags answer "which previews shipped and when". Documented in code comments (R1/R2/R3) and a new SKILL.md "Page naming & preview rollup" section so this can't silently regress on the next migration. Validated with an offline `--all` dry-run: correct `-unreleased` filenames, 4.148 rolls up 4.147 p1/p2/p3 + rc1, no bare 4.148.0.md/4.150.0.md, 3.119.x unchanged, and the 3.119.2 compare links reproduce the original page exactly. Co-authored-by: Matthew Leibowitz <mattleibow@live.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
A version's "released" and "unreleased" states are orthogonal: a version
can be on NuGet as a shipped prerelease (e.g. 4.150.0-preview.1) AND have
newer, not-yet-released commits on its head branch (main). The original
two-file model gave each of those its own page — a full-rollup released
`{version}.md` and a small-delta `{version}-unreleased.md` — and they
coexisted while the version was in flight.
A five-PR refactor stack (#4174, #4177, #4179) collapsed this into a
single page per version:
* #4174 added `--all` + `cleanup_stale_unreleased`, which deleted
`{v}-unreleased.md` whenever `{v}.md` existed — killing the
coexisting in-flight delta page.
* #4179 (R2) forced `main`/`.x` heads to honor `versions.json`
`compare_to`, turning the small "what may ship next" delta into a
full rollup.
* #4179 (R1) remapped prerelease branches to `-unreleased` and
deferred them, collapsing released + unreleased onto one file.
Restore the original delta semantics while keeping the genuinely-good
additions from the stack (versions.json supersession + compare_to on the
RELEASED rollup pages, preview-milestone rollup, contributor credit,
local skia links, `--all` idempotency):
* `_page_filename`: versioned branch (incl. -rc/-preview) -> released
`{version}.md`; `main`/`.x` head -> `{version}-unreleased.md`.
* `determine_diff_range` (main + servicing `.x`): drop the versions.json
`compare_to` override on heads so the unreleased page is again the
small delta from the last release to head, not a rollup. `compare_to`
still drives the released rollup pages produced by versioned branches.
* `cmd_all`: process main + servicing + ALL canonical versioned branches;
no deferral (distinct filenames never collide).
* `cleanup_stale_unreleased`: delete `{v}-unreleased.md` only once the
line advances to a strictly-higher version in the same minor — keeps
the in-flight released+unreleased pair, still prunes obsolete deltas
(e.g. 3.119.4-unreleased once 3.119.5 appears).
* `_write_page`: an unreleased head with an empty delta emits no page
(and prunes any stale one) — nothing to ship next.
Net effect on the 4.x line: 4.148.0.md / 4.150.0.md are full released
rollups (with preview milestones + supersede banners), 4.150.0-unreleased.md
is the small `release/4.150.0-preview.1..main` delta, and 4.148.0 has no
unreleased page because release/4.148.x has zero commits past the rc.
Verified by running the script for real (`--all`): it emitted exactly
those pages and listed only the changed ones under "Files to polish".
Keep the page model where it belongs — in the SCRIPT. The script owns ALL
file creation, naming, diff ranges, supersession, and cleanup; the AI/skill
only polishes the prose of the files the script lists. The detailed model
now lives in the script's module + function docstrings, and SKILL.md is
trimmed to a clear "division of responsibility" instead of duplicating
(and drifting from) the naming rules.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
A version's "released" and "unreleased" states are orthogonal: a version
can be on NuGet as a shipped prerelease (e.g. 4.150.0-preview.1) AND have
newer, not-yet-released commits on its head branch (main). The original
two-file model gave each of those its own page — a full-rollup released
`{version}.md` and a small-delta `{version}-unreleased.md` — and they
coexisted while the version was in flight.
A five-PR refactor stack (#4174, #4177, #4179) collapsed this into a
single page per version:
* #4174 added `--all` + `cleanup_stale_unreleased`, which deleted
`{v}-unreleased.md` whenever `{v}.md` existed — killing the
coexisting in-flight delta page.
* #4179 (R2) forced `main`/`.x` heads to honor `versions.json`
`compare_to`, turning the small "what may ship next" delta into a
full rollup.
* #4179 (R1) remapped prerelease branches to `-unreleased` and
deferred them, collapsing released + unreleased onto one file.
Restore the original delta semantics while keeping the genuinely-good
additions from the stack (versions.json supersession + compare_to on the
RELEASED rollup pages, preview-milestone rollup, contributor credit,
local skia links, `--all` idempotency):
* `_page_filename`: versioned branch (incl. -rc/-preview) -> released
`{version}.md`; `main`/`.x` head -> `{version}-unreleased.md`.
* `determine_diff_range` (main + servicing `.x`): drop the versions.json
`compare_to` override on heads so the unreleased page is again the
small delta from the last release to head, not a rollup. `compare_to`
still drives the released rollup pages produced by versioned branches.
* `cmd_all`: process main + servicing + ALL canonical versioned branches;
no deferral (distinct filenames never collide).
* `cleanup_stale_unreleased`: delete `{v}-unreleased.md` only once the
line advances to a strictly-higher version in the same minor — keeps
the in-flight released+unreleased pair, still prunes obsolete deltas
(e.g. 3.119.4-unreleased once 3.119.5 appears).
* `_write_page`: an unreleased head with an empty delta emits no page
(and prunes any stale one) — nothing to ship next.
Net effect on the 4.x line: 4.148.0.md / 4.150.0.md are full released
rollups (with preview milestones + supersede banners), 4.150.0-unreleased.md
is the small `release/4.150.0-preview.1..main` delta, and 4.148.0 has no
unreleased page because release/4.148.x has zero commits past the rc.
Verified by running the script for real (`--all`): it emitted exactly
those pages and listed only the changed ones under "Files to polish".
Keep the page model where it belongs — in the SCRIPT. The script owns ALL
file creation, naming, diff ranges, supersession, and cleanup; the AI/skill
only polishes the prose of the files the script lists. The detailed model
now lives in the script's module + function docstrings, and SKILL.md is
trimmed to a clear "division of responsibility" instead of duplicating
(and drifting from) the naming rules.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
A version's "released" and "unreleased" states are orthogonal: a version
can be on NuGet as a shipped prerelease (e.g. 4.150.0-preview.1) AND have
newer, not-yet-released commits on its head branch (main). The original
two-file model gave each of those its own page — a full-rollup released
`{version}.md` and a small-delta `{version}-unreleased.md` — and they
coexisted while the version was in flight.
A five-PR refactor stack (#4174, #4177, #4179) collapsed this into a
single page per version:
* #4174 added `--all` + `cleanup_stale_unreleased`, which deleted
`{v}-unreleased.md` whenever `{v}.md` existed — killing the
coexisting in-flight delta page.
* #4179 (R2) forced `main`/`.x` heads to honor `versions.json`
`compare_to`, turning the small "what may ship next" delta into a
full rollup.
* #4179 (R1) remapped prerelease branches to `-unreleased` and
deferred them, collapsing released + unreleased onto one file.
Restore the original delta semantics while keeping the genuinely-good
additions from the stack (versions.json supersession + compare_to on the
RELEASED rollup pages, preview-milestone rollup, contributor credit,
local skia links, `--all` idempotency):
* `_page_filename`: versioned branch (incl. -rc/-preview) -> released
`{version}.md`; `main`/`.x` head -> `{version}-unreleased.md`.
* `determine_diff_range` (main + servicing `.x`): drop the versions.json
`compare_to` override on heads so the unreleased page is again the
small delta from the last release to head, not a rollup. `compare_to`
still drives the released rollup pages produced by versioned branches.
* `cmd_all`: process main + servicing + ALL canonical versioned branches;
no deferral (distinct filenames never collide).
* `cleanup_stale_unreleased`: delete `{v}-unreleased.md` only once the
line advances to a strictly-higher version in the same minor — keeps
the in-flight released+unreleased pair, still prunes obsolete deltas
(e.g. 3.119.4-unreleased once 3.119.5 appears).
* `_write_page`: an unreleased head with an empty delta emits no page
(and prunes any stale one) — nothing to ship next.
Net effect on the 4.x line: 4.148.0.md / 4.150.0.md are full released
rollups (with preview milestones + supersede banners), 4.150.0-unreleased.md
is the small `release/4.150.0-preview.1..main` delta, and 4.148.0 has no
unreleased page because release/4.148.x has zero commits past the rc.
Verified by running the script for real (`--all`): it emitted exactly
those pages and listed only the changed ones under "Files to polish".
Keep the page model where it belongs — in the SCRIPT. The script owns ALL
file creation, naming, diff ranges, supersession, and cleanup; the AI/skill
only polishes the prose of the files the script lists. The detailed model
now lives in the script's module + function docstrings, and SKILL.md is
trimmed to a clear "division of responsibility" instead of duplicating
(and drifting from) the naming rules.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow
added a commit
that referenced
this pull request
Jun 17, 2026
A version's "released" and "unreleased" states are orthogonal: a version
can be on NuGet as a shipped prerelease (e.g. 4.150.0-preview.1) AND have
newer, not-yet-released commits on its head branch (main). The original
two-file model gave each of those its own page — a full-rollup released
`{version}.md` and a small-delta `{version}-unreleased.md` — and they
coexisted while the version was in flight.
A five-PR refactor stack (#4174, #4177, #4179) collapsed this into a
single page per version:
* #4174 added `--all` + `cleanup_stale_unreleased`, which deleted
`{v}-unreleased.md` whenever `{v}.md` existed — killing the
coexisting in-flight delta page.
* #4179 (R2) forced `main`/`.x` heads to honor `versions.json`
`compare_to`, turning the small "what may ship next" delta into a
full rollup.
* #4179 (R1) remapped prerelease branches to `-unreleased` and
deferred them, collapsing released + unreleased onto one file.
Restore the original delta semantics while keeping the genuinely-good
additions from the stack (versions.json supersession + compare_to on the
RELEASED rollup pages, preview-milestone rollup, contributor credit,
local skia links, `--all` idempotency):
* `_page_filename`: versioned branch (incl. -rc/-preview) -> released
`{version}.md`; `main`/`.x` head -> `{version}-unreleased.md`.
* `determine_diff_range` (main + servicing `.x`): drop the versions.json
`compare_to` override on heads so the unreleased page is again the
small delta from the last release to head, not a rollup. `compare_to`
still drives the released rollup pages produced by versioned branches.
* `cmd_all`: process main + servicing + ALL canonical versioned branches;
no deferral (distinct filenames never collide).
* `cleanup_stale_unreleased`: delete `{v}-unreleased.md` only once the
line advances to a strictly-higher version in the same minor — keeps
the in-flight released+unreleased pair, still prunes obsolete deltas
(e.g. 3.119.4-unreleased once 3.119.5 appears).
* `_write_page`: an unreleased head with an empty delta emits no page
(and prunes any stale one) — nothing to ship next.
Bucket PRs per preview so the AI can summarize each milestone directly.
A released rollup spans several prerelease tags; a single flat PR list
left the AI guessing which work shipped in which preview. The script now
partitions the PRs into per-preview buckets via git ancestry — each PR
under the EARLIEST milestone tag whose range contains its commit, i.e.
the preview it first shipped in (`bucket_prs_by_milestone`). The buckets
exhaustively cover the range (every PR lands in exactly one), so they ARE
the full list — no separate flat list to drift. The AI renders one
`## Preview N` section per bucket and merges them for the Highlights.
Verified: 4.148.0.md partitions its 162 PRs as RC1 35 + P3 37 + P2 27 +
P1 63 = 162 (no leftover); 4.150.0.md as Preview 1 = 2; the
4.150.0-unreleased.md delta has no previews and stays a flat 7-PR list.
Keep the page model where it belongs — in the SCRIPT. The script owns ALL
file creation, naming, diff ranges, supersession, cleanup, and PR
bucketing; the AI/skill only polishes prose and, on any anomaly (missing
or unexpected page, bad data), STOPS and reports rather than editing the
script or working around it. The model lives in the script's module +
function docstrings; SKILL.md is trimmed to a "division of responsibility"
plus how to consume the pre-bucketed PR data, instead of duplicating (and
drifting from) the naming rules.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The
update-release-notesworkflow timed out after 15 minutes on its first--allrun after the unified docs-automation system landed (#4171,08ac410ead). This PR fixes the timeout and does the one-time migration that makes future runs cheap.What changed
1. Fast-path: compute PR effort only after the skip check
_write_pagecomputed per-PR effort (commit count + working days, ~1s/PR fetchingrefs/pull/N/head) for every page before the_is_content_unchangedcheck. The 4.148 page alone (162 PRs) took ~150s; across 66 pages an all-unchanged run blew past the 15-min agent cap.get_prs_from_diff(now a cheap git-log parse) into a newadd_pr_effort()._write_pageonly after the unchanged check passes.Measured: 4.148 page ~170s → ~0.12s when skipped; a fully-migrated
--allnow runs in ~30s instead of timing out. (+22/−8 in the script.)2. One-time migration: regenerate + re-polish every page
Only 7 of 65 pages carried the
RAW PR DATAmetadata block the skip check relies on; the other 58 were legacy hand-curated pages that could never be skipped. This PR runs the full--allregen so every page now carries the block, then re-polishes all 61 pages from their own raw PR data perTEMPLATE.md(Highlights, grouped New Features with Skia milestone bumps first, Bug Fixes, Platform Support, Community Contributors, Links). Backport-bot authors (github-actions[bot]) were dropped from contributor tables.3. Page renames / additions
4.148.0-unreleased.md→4.148.0.md(now thatrelease/4.148.0-rc.1exists)4.150.0.md(Skia m150 preview) and1.54.1.1.mdResult
With every page migrated, future workflow runs skip all unchanged pages in seconds and only re-polish the 0–2 pages that actually changed — so the website release notes stay current with no manual effort.
Verification
python3 -m py_compileon the script# Versionheading + polished body; no leftover<!-- AI: -->skeletons--allrun skips 68/68 real pages in ~30s (proves migration + fast-path)*-unreleasedreferences in TOC/index; 4.148.0 & 4.150.0 listedCo-authored-by: Copilot 223556219+Copilot@users.noreply.github.com