-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Publish AgentReady to PyPI with Automated Release Workflow
Overview
AgentReady should be published to PyPI to make it easily installable for users (pip install agentready). This issue tracks the manual publishing workflow (✅ implemented) and provides a cold-startable prompt for future automated integration with the existing semantic-release workflow.
Current State
✅ Implemented: Manual PyPI Publishing Workflow
A manual workflow has been created at .github/workflows/publish-pypi.yml that allows on-demand publishing to PyPI or TestPyPI.
Features:
- Manual trigger via GitHub Actions UI (workflow_dispatch)
- Optional version override (or use current version from
pyproject.toml) - Dry run mode (publishes to TestPyPI for testing)
- Production mode (publishes to PyPI)
- Automatic GitHub release creation when publishing with version
- Built-in validation with
twine check - Security: Uses environment variables to prevent command injection
Usage:
- Go to Actions → "Publish to PyPI" → "Run workflow"
- Choose options:
- Version: Leave empty to use current version, or specify (e.g.,
1.2.0) - Dry run: Check to publish to TestPyPI first (recommended)
- Version: Leave empty to use current version, or specify (e.g.,
- Click "Run workflow"
🔧 Required Setup
Before the workflow can be used, configure these secrets in GitHub repository settings:
-
TEST_PYPI_TOKEN (for dry runs):
- Go to https://test.pypi.org/manage/account/token/
- Create new API token with scope "Entire account"
- Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
TEST_PYPI_TOKEN
-
PYPI_TOKEN (for production):
- Go to https://pypi.org/manage/account/token/
- Create new API token with scope "Entire account"
- Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
PYPI_TOKEN
-
Register package name (first time only):
- Run a dry run first to test
- Then run production publish to claim the
agentreadypackage name - Future publishes will update the existing package
Future Enhancement: Automated PyPI Publishing
Currently, the semantic-release workflow (.releaserc.json + .github/workflows/release.yml) handles:
- Automated version bumping based on conventional commits
- CHANGELOG.md generation
- GitHub releases
- Git tagging
Goal: Integrate PyPI publishing into the automated release workflow so that every semantic release automatically publishes to PyPI.
🎯 Cold-Startable Prompt for Automated Integration
Use this prompt with Claude Code to implement automated PyPI publishing:
I need to integrate PyPI publishing into the existing semantic-release workflow for the AgentReady project.
CURRENT STATE:
- Semantic-release is configured in .releaserc.json and .github/workflows/release.yml
- Manual PyPI publishing workflow exists at .github/workflows/publish-pypi.yml
- GitHub secrets TEST_PYPI_TOKEN and PYPI_TOKEN are configured
REQUIREMENTS:
1. Integrate PyPI publishing into .github/workflows/release.yml
2. Publish to PyPI AFTER semantic-release creates the GitHub release
3. Use the version that semantic-release determined (from conventional commits)
4. Maintain existing semantic-release functionality (changelog, version bump, GitHub release)
5. Use the same security patterns as the manual workflow (environment variables, no command injection)
6. Handle failures gracefully (don't fail the entire release if PyPI publish fails)
7. Add a workflow summary showing PyPI publication status
IMPLEMENTATION STEPS:
1. Read .github/workflows/release.yml to understand current flow
2. Read .releaserc.json to understand semantic-release config
3. Add PyPI publishing step after semantic-release completes
4. Extract version from pyproject.toml that semantic-release just updated
5. Build and publish package using the same build tools as manual workflow
6. Test with a dry run first (semantic-release dry-run mode + TestPyPI)
TESTING CHECKLIST:
- [ ] Dry run mode works (semantic-release --dry-run + TestPyPI)
- [ ] Production mode works (real release + PyPI)
- [ ] Version from semantic-release is correctly used
- [ ] Existing semantic-release features still work (changelog, GitHub release)
- [ ] Failure handling works (PyPI failure doesn't break GitHub release)
- [ ] Workflow summary shows publication status
CONSTRAINTS:
- Do not modify semantic-release behavior (version bumping, changelog, GitHub releases)
- Reuse build/publish logic from .github/workflows/publish-pypi.yml
- Follow security best practices (environment variables for all inputs)
- Maintain backwards compatibility with existing release workflow
OUTPUT:
- Updated .github/workflows/release.yml with integrated PyPI publishing
- Documentation in CLAUDE.md about the automated publishing flow
- Testing instructions for validating the integration
Best Practices for PyPI Maintenance
Version Management
- Let semantic-release control versions: Don't manually edit version in
pyproject.toml - Use conventional commits:
feat:triggers minor bump,fix:triggers patch,BREAKING CHANGE:triggers major - Version source of truth: After release,
pyproject.tomlversion is authoritative
Publishing Workflow
- Always dry run first: Test with TestPyPI before production
- Verify package contents: Check
twine checkoutput for warnings - Test installation: After TestPyPI publish, try installing and running
- Monitor PyPI dashboard: Check download stats, security advisories
Security
- Rotate tokens annually: Update
PYPI_TOKENandTEST_PYPI_TOKENyearly - Use scoped tokens: When available, scope tokens to specific projects
- Enable 2FA: Require 2FA for PyPI account
- Trusted publishing (future): Consider migrating to PyPI's trusted publishing with OIDC
Package Metadata
The package metadata is defined in pyproject.toml:
- Name:
agentready - Description: Defined in
project.description - License: Defined in
project.license - Author: Defined in
project.authors - URLs: Defined in
project.urls(homepage, repository, issues) - Classifiers: Defined in
project.classifiers(Python versions, license, topic)
Review before first publish: Ensure all metadata in pyproject.toml is accurate and complete.
Dependabot Integration
- Dependabot is already configured (
.github/dependabot.yml) - It will create PRs for dependency updates
- After merging dependency updates with
fix:prefix, semantic-release will auto-publish patch version
Release Cadence
- Automated: Every merge to
mainwithfeat:orfix:triggers release - Manual: Use manual workflow for hotfixes or special releases
- Frequency: Expect weekly releases during active development
Acceptance Criteria
Phase 1: Manual Publishing (✅ Complete)
- Manual PyPI publishing workflow created
- PyPI and TestPyPI tokens configured in GitHub secrets
- First test publish to TestPyPI successful
- First production publish to PyPI successful
- Package installable via
pip install agentready - Documentation updated in CLAUDE.md
Phase 2: Automated Publishing (Future)
- PyPI publishing integrated into semantic-release workflow
- Dry run testing complete (semantic-release + TestPyPI)
- First automated release to PyPI successful
- Documentation updated with automated workflow details
- Manual workflow remains available for emergency publishes
Related Issues / PRs
- PR feat: Add automated demo command for AgentReady #24: Fixed CI workflow to install from source (prerequisite for testing)
.github/workflows/publish-pypi.yml: Manual publishing workflow (implemented).github/workflows/release.yml: Semantic-release workflow (to be enhanced)
Notes for Implementation
When implementing automated integration:
- Preserve manual workflow: Keep
.github/workflows/publish-pypi.ymlfor emergency publishes - Test thoroughly: Use semantic-release's
--dry-runmode + TestPyPI first - Handle failures: PyPI publish failure shouldn't prevent GitHub release creation
- Add observability: Log version, build artifacts, publication status
- Document clearly: Update CLAUDE.md with new automated flow
Version extraction pattern (for automated workflow):
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")Build and publish pattern (reuse from manual workflow):
python -m build
twine check dist/*
twine upload dist/*🤖 Generated with Claude Code