Release Process and PyPI Publishing =================================== .. note:: **Internal HoneyHive SDK Development - Release Management** Release process and PyPI publishing workflows for HoneyHive SDK maintainers and contributors. For SDK installation, see :doc:`../tutorials/01-setup-first-tracer`. This guide covers the automated release process for publishing the HoneyHive Python SDK to PyPI. The SDK uses version-based triggering with automated validation and publishing. **Current Release Infrastructure**: - **Trigger**: Push to ``main`` branch with version change in ``src/honeyhive/__init__.py`` - **Validation**: Automatic PyPI version check (idempotent, won't re-publish) - **Testing**: Full test suite must pass before merge - **Publishing**: Automatic PyPI upload with GitHub release creation - **Safety**: Version format validation, package integrity checks, installation testing Release Workflow Architecture ----------------------------- **Automated Release Pipeline** (``sdk-publish.yml``): The SDK uses a version-triggered release workflow that executes on every push to ``main`` that modifies the version file: .. code-block:: yaml # .github/workflows/sdk-publish.yml on: push: branches: [main] paths: - 'src/honeyhive/__init__.py' **Workflow Execution Flow**: 1. **Version Extraction**: Parse ``__version__`` from ``src/honeyhive/__init__.py`` 2. **PyPI Validation**: Query PyPI API to check if version exists 3. **Conditional Execution**: - **Version exists**: Exit successfully with "already published" message - **Version is new**: Continue to build and publish 4. **Package Build**: Create source distribution and wheel 5. **Integrity Verification**: Run ``twine check`` on built packages 6. **Installation Test**: Test package installation in clean environment 7. **PyPI Publication**: Upload to PyPI using ``PYPI_TOKEN`` secret 8. **GitHub Release**: Create release with version tag 9. **Verification**: Confirm package availability on PyPI **Idempotent Design**: The workflow is safe to re-run multiple times. If the version already exists on PyPI, the workflow exits successfully without attempting to re-publish. This prevents errors from accidental re-runs or non-version changes to ``__init__.py``. Version Management ------------------ **Version Source of Truth**: The SDK version is defined in a single location: .. code-block:: python # src/honeyhive/__init__.py __version__ = "1.0.0" All SDK modules import version from this file: .. code-block:: python from honeyhive import __version__ **Version Format Requirements**: The workflow validates version strings against the following pattern: - **Stable releases**: ``X.Y.Z`` (e.g., ``1.0.0``, ``1.2.3``) - **Release candidates**: ``X.Y.Zrc#`` (e.g., ``1.0.0rc1``, ``1.0.0rc2``) - **Alpha releases**: ``X.Y.Zalpha#`` (e.g., ``1.0.0alpha1``) - **Beta releases**: ``X.Y.Zbeta#`` (e.g., ``1.0.0beta1``) Invalid version formats will cause the workflow to fail early with a validation error. **Semantic Versioning**: The SDK follows `Semantic Versioning `_ (SemVer): - **MAJOR** (``1.0.0`` → ``2.0.0``): Breaking API changes - **MINOR** (``1.0.0`` → ``1.1.0``): New features (backward compatible) - **PATCH** (``1.0.0`` → ``1.0.1``): Bug fixes (backward compatible) Release Procedure ----------------- **Standard Release Process**: 1. **Update Version**: .. code-block:: bash # Edit src/honeyhive/__init__.py __version__ = "1.0.0" 2. **Update Changelog**: Add release notes to ``CHANGELOG.md``: .. code-block:: markdown ## [1.0.0] - 2025-10-31 ### Added - Multi-instance tracer architecture - Direct OpenTelemetry integration ### Changed - Improved thread safety and context propagation ### Breaking Changes - See MIGRATION_GUIDE.md for details 3. **Create Release Branch**: .. code-block:: bash git checkout -b release-v1.0.0 git add src/honeyhive/__init__.py CHANGELOG.md git commit -m "Release v1.0.0" git push origin release-v1.0.0 4. **Create Pull Request**: .. code-block:: bash gh pr create --title "Release v1.0.0" --body "See CHANGELOG.md" 5. **Review and Merge**: - Verify all CI checks pass (tests, linting, documentation) - Review changes one final time - Merge to ``main`` branch 6. **Automatic Publication**: - Workflow triggers on merge to ``main`` - Package builds, validates, and publishes to PyPI - GitHub release created with tag ``v1.0.0`` - Users can install: ``pip install honeyhive==1.0.0`` **Pre-Release Checklist**: Before creating the release PR, verify: - [ ] Full test suite passes locally: ``tox -e unit && tox -e integration`` - [ ] Code quality checks pass: ``tox -e lint && tox -e format`` - [ ] Documentation builds without warnings: ``tox -e docs`` - [ ] Version number follows SemVer conventions - [ ] ``CHANGELOG.md`` updated with all notable changes - [ ] Breaking changes documented in migration guide - [ ] All integration tests pass with real APIs PyPI Publishing Workflow Details -------------------------------- **Workflow Configuration**: The ``sdk-publish.yml`` workflow includes multiple validation steps: **Version Validation**: .. code-block:: bash # Extract version from source version=$(python -c "exec(open('src/honeyhive/__init__.py').read()); print(__version__)") # Validate format (regex check) echo "$version" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(rc[0-9]+|alpha[0-9]+|beta[0-9]+)?$' **PyPI Existence Check**: .. code-block:: bash # Query PyPI API response=$(curl -s https://pypi.org/pypi/honeyhive/json) # Check if version exists in releases if echo "$response" | python -c "import sys, json; ..."; then echo "Version already published - skipping" exit 0 fi **Package Build and Verification**: .. code-block:: bash # Build distribution packages python -m build # Verify package integrity python -m twine check dist/* # Test installation python -m venv test-install source test-install/bin/activate pip install dist/*.whl python -c "import honeyhive; print(honeyhive.__version__)" **PyPI Publication**: .. code-block:: bash # Publish using PYPI_TOKEN secret python -m twine upload dist/* **GitHub Release Creation**: .. code-block:: yaml - uses: actions/create-release@v1 with: tag_name: v${{ steps.get_version.outputs.version }} release_name: v${{ steps.get_version.outputs.version }} prerelease: ${{ contains(version, 'rc') || contains(version, 'alpha') }} **Required Secrets**: The workflow requires the following GitHub repository secrets: - ``PYPI_TOKEN``: PyPI API token with upload permissions for ``honeyhive`` package - ``GITHUB_TOKEN``: Automatically provided by GitHub Actions Integration with CI/CD Pipeline ------------------------------- **Release Candidate Workflow**: Before releasing to PyPI, use the release candidate workflow for comprehensive validation: .. code-block:: bash # Manually trigger release candidate build gh workflow run release-candidate.yml \ --field version_type=minor \ --field pre_release=rc The release candidate workflow (see :doc:`testing/ci-cd-integration`) executes: 1. Full test suite across Python 3.11, 3.12, 3.13 2. Integration tests with real APIs 3. Lambda compatibility tests 4. Package building and validation 5. Multi-Python installation testing Release candidates are uploaded as workflow artifacts but not published to PyPI. **Main Branch Protection**: The ``main`` branch is protected and requires: - All status checks must pass (tests, linting, documentation) - At least one approval from code owners - Branch must be up to date with base branch This ensures only validated code triggers the release workflow. Troubleshooting Release Issues ------------------------------ **Version Already Published**: **Symptom**: Workflow shows "Version already published" message **Cause**: Version string in ``__init__.py`` already exists on PyPI **Solution**: Update ``__version__`` to a new version number and re-run .. code-block:: bash # Check current PyPI versions pip index versions honeyhive # Update to new version __version__ = "1.0.1" # Increment appropriately **Build Failures**: **Symptom**: Package build step fails **Common Causes**: - Syntax errors in Python code - Missing dependencies in ``pyproject.toml`` - Import errors in ``__init__.py`` **Solution**: .. code-block:: bash # Test build locally python -m build # If build fails, check for errors python -m pip install -e . python -c "import honeyhive" **Publication Failures**: **Symptom**: PyPI upload fails **Common Causes**: - Invalid or expired ``PYPI_TOKEN`` - Network connectivity issues - PyPI service outage **Solution**: 1. Verify ``PYPI_TOKEN`` secret is configured correctly 2. Check PyPI status: https://status.python.org/ 3. Re-run workflow after resolving issues **GitHub Release Not Created**: **Symptom**: Package published to PyPI but no GitHub release **Common Causes**: - Insufficient GitHub Actions permissions - ``GITHUB_TOKEN`` permission issues **Solution**: 1. Verify workflow has ``contents: write`` permission 2. Manually create release if needed: .. code-block:: bash gh release create v1.0.0 \ --title "v1.0.0" \ --notes "See CHANGELOG.md for details" **Version Mismatch**: **Symptom**: Published package has different version than expected **Cause**: ``__init__.py`` version doesn't match expected value **Solution**: .. code-block:: bash # Verify version in source python -c "exec(open('src/honeyhive/__init__.py').read()); print(__version__)" # Ensure this matches intended release version # If mismatch, update __init__.py and release again with correct version Emergency Manual Release ------------------------ If the automated workflow fails and an emergency release is required: **Manual Release Procedure**: 1. **Verify Version**: .. code-block:: bash python -c "exec(open('src/honeyhive/__init__.py').read()); print(__version__)" 2. **Build Package**: .. code-block:: bash python -m build 3. **Verify Package**: .. code-block:: bash twine check dist/* 4. **Test Installation**: .. code-block:: bash python -m venv test-env source test-env/bin/activate pip install dist/*.whl python -c "import honeyhive; print(honeyhive.__version__)" deactivate 5. **Publish to PyPI**: .. code-block:: bash # Set credentials export TWINE_USERNAME=__token__ export TWINE_PASSWORD= # Upload twine upload dist/* 6. **Create GitHub Release**: .. code-block:: bash git tag v1.0.0 git push origin v1.0.0 gh release create v1.0.0 \ --title "v1.0.0" \ --notes "See CHANGELOG.md for details" **Post-Manual Release**: After manual release, update the repository to trigger the automated workflow on the next release. Investigate why the automated workflow failed and fix the root cause. Release Monitoring ------------------ **Post-Release Verification**: After workflow completes, verify the release: 1. **Check PyPI**: .. code-block:: bash pip index versions honeyhive # Should show new version 2. **Test Installation**: .. code-block:: bash pip install honeyhive==1.0.0 python -c "import honeyhive; print(honeyhive.__version__)" 3. **Verify GitHub Release**: .. code-block:: bash gh release view v1.0.0 4. **Check Documentation**: Verify documentation deployed: https://honeyhiveai.github.io/python-sdk/ **Release Metrics**: Monitor the following metrics for release health: - Workflow execution time (target: < 10 minutes) - Package build success rate (target: 100%) - PyPI publication success rate (target: 100%) - GitHub release creation success rate (target: 100%) Version History and Changelog ----------------------------- **Changelog Maintenance**: The ``CHANGELOG.md`` file tracks all notable changes: .. code-block:: markdown # Changelog All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - Features in development ## [1.0.0] - 2025-10-31 ### Added - Initial stable release **Changelog Format**: Follow `Keep a Changelog `_ format: - **Added**: New features - **Changed**: Changes in existing functionality - **Deprecated**: Soon-to-be removed features - **Removed**: Removed features - **Fixed**: Bug fixes - **Security**: Security improvements **Version Links**: Include comparison links at the bottom of ``CHANGELOG.md``: .. code-block:: markdown [1.0.0]: https://github.com/honeyhiveai/python-sdk/compare/v0.1.0rc3...v1.0.0 [Unreleased]: https://github.com/honeyhiveai/python-sdk/compare/v1.0.0...HEAD Best Practices -------------- **Release Timing**: - **Stable releases**: Only from ``main`` branch - **Pre-releases**: Use ``rc``, ``alpha``, or ``beta`` identifiers - **Hotfixes**: Patch version increment with minimal changes **Testing Before Release**: Always run comprehensive tests before releasing: .. code-block:: bash # Full local validation tox -e unit tox -e integration tox -e lint tox -e format tox -e docs # Multi-Python testing tox -e py311,py312,py313 **Documentation Updates**: Ensure documentation is current before release: - API reference matches implementation - Migration guides updated for breaking changes - Examples tested and working - Changelog complete and accurate **Communication**: For major or breaking releases: - Announce in community channels (Discord, Slack) - Update documentation with migration guides - Consider blog post for significant changes - Notify users of deprecations in advance See Also -------- - :doc:`testing/ci-cd-integration` - CI/CD pipeline and GitHub Actions workflows - :doc:`testing/setup-and-commands` - Development environment setup - :doc:`../how-to/migration-compatibility/migration-guide` - User migration guides - ``CHANGELOG.md`` - Complete version history - ``.github/workflows/sdk-publish.yml`` - Release workflow implementation - ``.github/workflows/release-candidate.yml`` - Release candidate validation