Status: Active Last Updated: 2026-01-15
Checklist for releasing a new version of notebooklm-py.
For Claude Code: Follow this checklist step by step. NO STEPS ARE OPTIONAL. "Quick release" means efficient execution, NOT skipping steps.
Critical rules:
- Never combine commit and push - always commit first, show user, then ask "Push to main?"
- Explicit confirmation required for: pushing to main, publishing to TestPyPI, creating tags, pushing tags
- "ok" is not confirmation - restate what you're about to do and wait for explicit "yes"
- TestPyPI is mandatory - it catches packaging issues that tests cannot detect
Before starting, present this summary to the user:
Release Plan for vX.Y.Z:
1. Update pyproject.toml and CHANGELOG.md
2. Commit (will show diff first)
3. ⏸️ CONFIRM: Push to main?
4. Wait for CI (test.yml + E2E)
5. ⏸️ CONFIRM: Publish to TestPyPI?
6. Verify TestPyPI package
7. ⏸️ CONFIRM: Create and push tag vX.Y.Z?
8. Wait for PyPI publish
9. Create GitHub release
Proceed with release preparation?
- Verify README.md reflects current features
- Check CLI reference matches
notebooklm --helpoutput - Verify Python API docs match public exports in
__init__.py - Update
Last Updateddates in modified docs - Verify example scripts have valid syntax:
python -m py_compile docs/examples/*.py
Related docs to check/update if relevant:
| Doc | Update when... |
|---|---|
| SKILL.md | New CLI commands, changed flags, new workflows |
| cli-reference.md | Any CLI changes |
| python-api.md | New/changed Python API |
| troubleshooting.md | New known issues, fixed issues to remove |
| development.md | Architecture changes, new test patterns |
| configuration.md | New env vars, config options |
| stability.md | Public API changes, deprecations |
-
Determine version bump type using this decision tree:
Did you add new items to `__all__` in `__init__.py`? ├── YES → MINOR (new public API) └── NO → PATCH (fixes, logging, UX, internal improvements) When in doubt, it's PATCH.See Version Numbering for full details.
-
Update version in
pyproject.toml:version = "X.Y.Z"
- Get commits since last release:
git log $(git describe --tags --abbrev=0)..HEAD --oneline - Generate changelog entries in Keep a Changelog format:
- Added - New features
- Fixed - Bug fixes
- Changed - Changes in existing functionality
- Deprecated - Soon-to-be removed features
- Removed - Removed features
- Security - Security fixes
- Add entries under
## [Unreleased]inCHANGELOG.md - Move
[Unreleased]content to new version section:## [Unreleased] ## [X.Y.Z] - YYYY-MM-DD
- Update comparison links at bottom of
CHANGELOG.md:[Unreleased]: https://github.com/teng-lin/notebooklm-py/compare/vX.Y.Z...HEAD [X.Y.Z]: https://github.com/teng-lin/notebooklm-py/compare/vPREV...vX.Y.Z
- Verify changes:
git diff
- Commit (do NOT push yet):
git add pyproject.toml CHANGELOG.md git commit -m "chore: release vX.Y.Z" - Show commit to user:
git show --stat
- ⏸️ CONFIRM: Ask user "Ready to push to main? This will trigger CI."
- Push to main:
git push origin main
- Wait for test.yml to pass:
- Linting and formatting
- Type checking
- Unit and integration tests (Python 3.10-3.14, all platforms)
- Go to Actions → Nightly E2E
- Click Run workflow, select
mainbranch - Wait for E2E tests to pass
⚠️ REQUIRED: Do NOT skip TestPyPI verification. Always test on TestPyPI before publishing to PyPI. This catches packaging issues that unit tests cannot detect (missing files, broken imports, dependency problems).
- ⏸️ CONFIRM: Ask user "Ready to publish to TestPyPI?"
- Go to Actions → Publish to TestPyPI
- Click Run workflow
- Wait for upload to complete
- Verify package appears: https://test.pypi.org/project/notebooklm-py/
Note: TestPyPI does not allow re-uploading the same version. If you need to fix issues after publishing, bump the patch version and start over.
- Go to Actions → Verify Package
- Click Run workflow with source:
testpypi - Wait for all tests to pass (unit, integration, E2E)
- If verification fails:
- Fix issues locally
- Bump patch version in
pyproject.toml - Update
CHANGELOG.mdwith fix - Amend or create new commit
- Push and re-run Publish to TestPyPI
- ⏸️ CONFIRM: Ask user "TestPyPI verified. Ready to create tag vX.Y.Z and publish to PyPI? This is irreversible."
- Create tag:
git tag vX.Y.Z
- Push tag:
git push origin vX.Y.Z
- Wait for publish.yml to complete
- Verify on PyPI: https://pypi.org/project/notebooklm-py/
- Go to Actions → Verify Package
- Click Run workflow with:
- source:
pypi
- source:
- Wait for all tests to pass
- Create release from tag:
Or manually:
gh release create vX.Y.Z --title "vX.Y.Z" --notes "$(cat CHANGELOG.md | sed -n '/## \[X.Y.Z\]/,/## \[/p' | sed '$d')"
- Go to Releases → Draft a new release
- Select tag
vX.Y.Z - Title:
vX.Y.Z - Copy release notes from
CHANGELOG.md - Publish release
Warning: Only do this immediately after your own push, before anyone else pulls.
# Fix locally, then amend
git add -A
git commit --amend --no-edit
git push --force origin mainWarning: Force pushing rewrites history. Only do this if you haven't shared the commit.
# Undo release commit (local only)
git reset --hard HEAD~1
# If already pushed (use with caution)
git push --force origin main# Delete local tag
git tag -d vX.Y.Z
# Delete remote tag (if pushed)
git push origin :refs/tags/vX.Y.Z- Check if version already exists on TestPyPI
- TestPyPI doesn't allow re-uploading same version
- Bump to next patch version if needed
IMPORTANT: Read stability.md before deciding version bump.
| Change Type | Bump | Example |
|---|---|---|
| RPC method ID fixes | PATCH | 0.1.0 → 0.1.1 |
| Bug fixes | PATCH | 0.1.1 → 0.1.2 |
| Internal improvements (logging, auth UX, CI) | PATCH | 0.1.2 → 0.1.3 |
New public API (new classes, methods in __all__) |
MINOR | 0.1.3 → 0.2.0 |
| Breaking changes to public API | MAJOR | 0.2.0 → 1.0.0 |
Key distinction: "New features" means new public API surface (additions to __all__ in __init__.py). Internal improvements, better error messages, logging enhancements, and UX improvements are PATCH releases.