-
Confirm the tree is clean and pushed. git status should be clean and up to date with
origin/master. The release is cut from master.
-
Review what's shipping so you can write accurate highlights:
PREV=$(git tag --sort=-creatordate | head -1)
git log $PREV..HEAD --oneline
git show <sha> # inspect each meaningful change to describe it correctly
-
Create the release (this triggers the PyPI publish). Use --target master, not a raw
SHA — targeting a bare commit SHA fails with Release.target_commitish is invalid:
gh release create vX.Y.Z --target master --title vX.Y.Z --generate-notes
-
Add a curated ## Highlights section above ## What's Changed.
--generate-notes alone does NOT include highlights — every prior release has a hand-written
one, so always add it. Match the house style (see gh release view v9.32.0):
- One
### subsection per notable change, prefixed with an emoji:
✨ new feature · 🐛 bug fix · 📚/📝 docs · other emoji as fitting.
- A short prose paragraph explaining the user-visible impact, plus a fenced
shell example
for new commands/features.
-
Rewrite ## What's Changed as a commit history, not the PR-link list --generate-notes
produces. One line per commit since the previous tag, formatted
* <shortsha8> <subject> (#<pr>) (@<committer>):
for sha in $(git log $PREV..HEAD --format='%H'); do
short=$(git rev-parse --short=8 $sha)
subj=$(git show -s --format='%s' $sha)
login=$(gh api repos/doronz88/pymobiledevice3/commits/$sha --jq '.author.login')
pr=$(gh api repos/doronz88/pymobiledevice3/commits/$sha/pulls --jq '.[0].number')
echo "* $short $subj (#$pr) (@$login)"
done
Keep the generated ## New Contributors and **Full Changelog** lines.
Write the full body (Highlights + What's Changed + New Contributors + Full Changelog) to a file
and apply it:
gh release edit vX.Y.Z --notes-file /tmp/rel_notes.md
Editing notes does not re-trigger the publish workflow — it already fired on creation.
-
Verify the publish workflow.
gh run list --workflow=python-publish.yml --limit 3
Watch it to completed / success if the user wants confirmation it landed on PyPI.