Skip to content

ci: draft the GitHub Release page from the CHANGELOG on tag - #389

Merged
cyfyifanchen merged 3 commits into
mainfrom
ci/github-release-draft
Aug 5, 2026
Merged

ci: draft the GitHub Release page from the CHANGELOG on tag#389
cyfyifanchen merged 3 commits into
mainfrom
ci/github-release-draft

Conversation

@gloryfromca

Copy link
Copy Markdown
Collaborator

Summary

release.yml only published to PyPI. Creating the GitHub Release page was a manual step that no workflow performed and no doc mentioned — so v1.2.2 went out to PyPI with no release page, which is what prompted this.

A second job now drafts the page after a successful upload:

  • Title EverOS X.Y.Z; body lifted from the matching ## [X.Y.Z] CHANGELOG section, with the ### Added group headings demoted to ## to match the existing pages.
  • --prerelease --latest=false for PEP 440 suffixed tags, so an rc can never become /releases/latest.
  • Left as a draft: the lead summary that opens every EverOS release page is prose CI cannot write. The step summary prints both the draft URL and the eventual public one.

Design notes:

  • Separate job so the publish job keeps contents: read next to its OIDC token, and so no page appears for a version that failed to upload.
  • A stable tag with no CHANGELOG section fails the job instead of publishing an empty page. Pre-releases fall back to a placeholder body.
  • Existing releases are detected through the list endpoint: the by-tag endpoint is published-only, so the Actions token cannot see a draft through it (cli/cli#3037) and a re-run would 422. A stale draft is replaced; a published release is left alone.

This mirrors what Raven has done for ten releases, with the body sourced from the CHANGELOG rather than a mostly-TODO template.

Area

  • CI, build, or release

Verification

Both steps were extracted from the workflow YAML and executed locally — the extraction step against the real CHANGELOG.md, the shell step under bash -e against a stubbed gh.

extraction (real CHANGELOG.md)
  v1.2.2     rc=0  7887 chars  headings: ## Added / ## Changed / ## Fixed / ## Docs
  v1.1.4     rc=0  3046 chars
  v1.0.0     rc=0  1163 chars  (stops before the link-reference block)
  v9.9.9     rc=1  ::error::CHANGELOG.md has no '## [9.9.9]' section
  v1.2.3rc1  rc=0  prerelease=true, placeholder body

shell step under `bash -e`, stubbed gh, 3 states x stable/pre-release
  no release   -> create --draft --latest            rc=0
  no release   -> create --draft --prerelease --latest=false  rc=0
  stale draft  -> DELETE releases/42, then create    rc=0
  published    -> no write calls, summary line only  rc=0

The first draft of the shell step used [ cond ] && assign, which fails a bash -e step when the test is false; the stubbed run caught it and it is now an if.

v1.2.2's page was created by hand from the same CHANGELOG section this job extracts, as a draft awaiting its lead summary.

Checklist

  • I kept the change scoped to the relevant area.
  • I am opening this from a separate branch, not pushing directly to main.
  • I updated docs, examples, or setup notes when behavior changed.
  • I added or updated tests when the change affects behavior.
  • I did not commit secrets, .env files, dependency folders, or generated output.
  • Active relative links in Markdown files resolve.

Notes for Reviewers

/release gains a step 8 (write the lead summary, click Publish) and a warning about the releases/tag/untagged-<hash> draft URL, which keeps serving a stale page after publication with no redirect.

The workflow can only be exercised for real by pushing a tag. If you would rather validate it end to end before the next release, a throwaway v1.2.3rc1 tag exercises the whole path without touching /releases/latest — the rc release and tag get deleted afterward.

🤖 Generated with Claude Code

zhanghui and others added 3 commits August 5, 2026 12:35
release.yml only published to PyPI; creating the Release page was an
undocumented manual step, and v1.2.2 shipped to PyPI without one.

A second job, gated on a successful upload, now drafts the page: title
"EverOS X.Y.Z", body lifted from the matching CHANGELOG section with the
group headings demoted to h2, `--prerelease` for PEP 440 suffixed tags. It
stays a draft because the lead summary that opens every EverOS release page
is prose CI cannot write.

The job runs separately from the publish job so that one keeps `contents:
read` alongside its OIDC token. A stable tag with no CHANGELOG section fails
the job rather than publishing an empty page; pre-releases fall back to a
placeholder. Existing releases are detected through the list endpoint, since
the by-tag endpoint cannot see drafts (cli/cli#3037) and a re-run would 422 —
a stale draft is replaced, a published release left alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every EverOS release page since 1.1.3 closes with an Upgrade section — the
pip line, any migration notes, and a compare link to the previous tag. The
first draft dropped it, so a published page would have lost the one section
readers act on.

The pip line and the compare link are prefilled; the previous tag comes from
`git tag --sort=-v:refname`, which needs the full tag list, hence
fetch-depth: 0. Migration notes stay hand-written next to the lead summary,
since only a human knows whether a release needs them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Flipping `draft` through the API without `tag_name` rebinds the release to
the `untagged-<hash>` placeholder and creates a git tag by that name against
the default branch. Hit while publishing 1.2.2; the web UI button is
unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cyfyifanchen
cyfyifanchen merged commit ace0d79 into main Aug 5, 2026
9 checks passed
@cyfyifanchen
cyfyifanchen deleted the ci/github-release-draft branch August 5, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants