بنقرة واحدة
pypi-release
// This skill should be used when releasing tunacode-cli to PyPI. It keeps the existing local release checks, then hands the actual PyPI upload to a GitHub Actions workflow that uses the repository's PYPI_API_TOKEN secret.
// This skill should be used when releasing tunacode-cli to PyPI. It keeps the existing local release checks, then hands the actual PyPI upload to a GitHub Actions workflow that uses the repository's PYPI_API_TOKEN secret.
| name | pypi-release |
| description | This skill should be used when releasing tunacode-cli to PyPI. It keeps the existing local release checks, then hands the actual PyPI upload to a GitHub Actions workflow that uses the repository's PYPI_API_TOKEN secret. |
Keep the existing local release gates for tunacode-cli, then hand the actual PyPI upload to GitHub Actions. This keeps the release checks local while moving the credentialed publish step into the repository workflow.
Trigger this skill when the user requests:
The skill provides two approaches: Manual (REQUIRED) and Automated (deprecated - skips critical test step).
WARNING: The automated script is currently discouraged because it skips the mandatory manual test step.
Use the Manual Release workflow below instead to ensure proper testing before release.
Execute the full release workflow with a single script:
~~```bash uv run python skills/pypi-release/scripts/release.py
~~The script performs these steps automatically:~~
1. ~~Pre-flight checks (git status, branch check, linting, tests)~~
2. ~~Version bump~~
3. ~~Git operations (commit, tag, push)~~
4. ~~GitHub release~~
5. ~~Workflow monitoring~~
**Issue:** The automated script does not include the mandatory manual import test (Step 3) which has caused multiple broken releases. Always use the manual workflow.
### Manual Release (REQUIRED - Step-by-Step)
**This is the ONLY recommended workflow. Follow these steps in order:**
#### Step 1: Pre-flight Checks
Verify the repository is ready for release:
```bash
# Check git status (must be clean)
git status
# Verify on master branch
git branch --show-current
# Run linting
ruff check .
# Run tests
source .venv/bin/activate && pytest tests/ -q
# MANDATORY: Run tmux E2E tool tests (all 6 must pass)
uv run pytest tests/system/cli/test_tmux_tools.py -v -m tmux
HARD GATE: If the tmux tool tests fail, DO NOT proceed with the release. These tests verify all 6 tools (bash, read_file, write_file, update_file, discover, web_fetch) work end-to-end in the real TUI. No exceptions.
Use the version bumping script:
uv run python skills/pypi-release/scripts/bump_version.py
The script:
pyproject.tomlpyproject.toml:8 (project version)pyproject.toml:175 (hatch script version)src/tunacode/constants.py:12 (APP_VERSION constant)README.md (version header)REQUIRED: Manually update CHANGELOG.md with the new version entry.
Check commits since last release:
git log --oneline $(git describe --tags --abbrev=0)..HEAD --no-merges
Add entry under ## [Unreleased]:
## [X.Y.Z.W] - YYYY-MM-DD
### Added
- New features
### Changed
- Changes to existing functionality
### Fixed
- Bug fixes
Stage the file:
git add CHANGELOG.md
CRITICAL: You MUST test that tunacode actually works before releasing!
Test the import and basic functionality:
# Activate venv and test import
source .venv/bin/activate && python -c "from tunacode.ui.main import app; print('✓ Import successful')"
# Optionally test the CLI starts without errors
python -m tunacode.ui.main --help
If the import fails, DO NOT PROCEED with the release! Fix the issue first, then re-test.
This step prevents releasing broken packages to PyPI (which cannot be undone).
Commit the version changes and push them to master:
# Stage version files (CHANGELOG.md should already be staged from Step 2.5)
git add pyproject.toml src/tunacode/constants.py README.md CHANGELOG.md
# Commit with conventional commit message
git commit -m "chore: bump version to X.Y.Z.W"
# Push to remote
git push origin master
Run the manual publish workflow after the local checks and release commit have passed:
gh workflow run publish-release.yml --ref master -f version=X.Y.Z.W
This workflow:
pyproject.toml and src/tunacode/constants.py match the requested versiontwine check on the built artifactsPYPI_API_TOKEN secretCheck the status of the GitHub Actions workflow:
# List recent workflow runs
gh run list --workflow=publish-release.yml --limit 1
# Watch workflow in real-time
gh run watch
# View logs if failed
gh run view <run-id> --log-failed
If the GitHub Actions workflow fails:
Check workflow status:
gh run list --workflow=publish-release.yml --limit 1
View failure logs:
gh run view <run-id> --log-failed
Common issues: See references/common-issues.md for detailed troubleshooting
If the workflow reports version mismatch between the requested version and the code:
Verify all four version locations match:
grep 'version = ' pyproject.toml
grep 'APP_VERSION' src/tunacode/constants.py
grep '^## v' README.md | head -1
Re-run bump_version.py script to sync versions
Push the corrected commit and re-run:
git push origin master
gh workflow run publish-release.yml --ref master -f version=X.Y.Z.W
If the workflow fails with Python version errors:
.github/workflows/publish-release.yml line 20python-version: '3.12' (not '3.x')Common error message:
ERROR: Package 'tunacode-cli' requires a different Python: 3.14.0 not in '<3.14,>=3.10'
Fix: Pin Python version in workflow to 3.12
pyproject.toml:8 - Project version in [project] sectionpyproject.toml:175 - Hatch script versionsrc/tunacode/constants.py:12 - APP_VERSION constantREADME.md - Version header (line 40)CHANGELOG.md - Version history (manual update required).github/workflows/publish-release.yml - Manual GitHub Actions workflow
workflow_dispatchtwine checkPYPI_API_TOKENscripts/bump_version.py - Atomic version bumping across all filesscripts/release.py - Full automated release workflowreferences/common-issues.md - Detailed troubleshooting guide for common problemsreferences/workflow-structure.md - Complete GitHub Actions workflow documentationEnsure these are configured before releasing:
GitHub CLI authenticated:
gh auth status
PyPI API token configured as PYPI_API_TOKEN in repository secrets
Clean git state - all changes committed
On master branch
Tests passing - pytest tests/
Linting passing - ruff check .
After a successful release:
Verify on PyPI:
Test installation:
pip install --upgrade tunacode-cli
tunacode --version
When the workflow fails, follow this debug process:
references/common-issues.md for known problemsmaster:
git push origin master
gh workflow run publish-release.yml --ref master -f version=X.Y.Z.W
This skill does not implement automatic rollback. If a release fails:
Rationale: PyPI releases are immutable once published. The version number cannot be reused. Focus on fixing forward rather than rolling back.