DEV Community

Tosin Akinosho
Tosin Akinosho

Posted on

How to Keep Your Python Package Metadata in Sync with GitHub Release Tags

Keeping versions aligned across setup.py, pyproject.toml, and GitHub tags is critical for maintaining a healthy Python project. It prevents mismatches, enables CI/CD automation, and ensures seamless releases.

In this guide, you'll learn best practices for versioning Python packages and syncing metadata with GitHub release tags using bump-my-version, GitHub Actions, and automation scripts.


πŸ“Œ Table of Contents

  1. Why Versioning is Crucial
  2. The Right Way to Define Your Version
  3. Aligning Versions with GitHub Tags
  4. Keeping Dependencies in Sync
  5. Using bump-my-version for Automated Versioning
  6. Validating Versions in CI/CD
  7. Mistakes to Avoid
  8. Final Checklist
  9. FAQs

Why Versioning is Crucial

Imagine deploying a package and realizing later that the version in setup.py differs from pyproject.toml. πŸ€¦β€β™‚οΈ This breaks automation, confuses users, and complicates debugging.

When you keep versions in sync, you:

  • Ensure smooth CI/CD deployments
  • Reduce version conflicts in dependencies
  • Automate and streamline release workflows

Following best practices prevents the dreaded "version mismatch" error and keeps your project organized.


The Right Way to Define Your Version

A common pitfall is defining the version in multiple places. Instead, define it in a single source of truth.

1️⃣ Store Version in __version__.py

Create a __version__.py file inside your package:

# my_package/__version__.py
__version__ = "1.2.3"
Enter fullscreen mode Exit fullscreen mode

2️⃣ Use It in setup.py

Instead of manually entering a version, import it dynamically:

from my_package.__version__ import __version__

setup(
    name="my_package",
    version=__version__,
    ...
)
Enter fullscreen mode Exit fullscreen mode

3️⃣ Sync with pyproject.toml (for Poetry)

If you're using Poetry, manually update pyproject.toml:

[tool.poetry]
name = "my-package"
version = "1.2.3"
Enter fullscreen mode Exit fullscreen mode

πŸ“Œ Poetry does not support dynamic version importsβ€”so keeping this updated manually (or via automation) is necessary.


Aligning Versions with GitHub Tags

To ensure GitHub releases match your code, follow this release process:

  1. Update the version in __version__.py and pyproject.toml.
  2. Commit the change:
   git commit -am "Release version 1.2.3"
Enter fullscreen mode Exit fullscreen mode
  1. Create a tag matching the version:
   git tag v1.2.3
   git push origin main --tags
Enter fullscreen mode Exit fullscreen mode
  1. Ensure the tag and package version match before deploying.

🚨 If the tag and package version don’t match, CI/CD should catch the issue and stop the release.


Keeping Dependencies in Sync

Beyond versioning, managing dependencies properly prevents unexpected failures.

Lock Dependencies in requirements.txt

For reproducible builds, lock dependencies:

pip freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

Separate Dev Dependencies

Use a separate file for development dependencies:

pip install -r requirements-dev.txt
Enter fullscreen mode Exit fullscreen mode

Alternatively, if using Poetry, do:

poetry add pytest --dev
Enter fullscreen mode Exit fullscreen mode

This ensures production installs don’t pull unnecessary dev dependencies.


Using bump-my-version for Automated Versioning

What is bump-my-version?

bump-my-version is the modern replacement for bump2version (which is no longer maintained).

It updates version numbers across all necessary files (e.g., __version__.py, setup.py, pyproject.toml).

How to Install It

pip install bump-my-version
Enter fullscreen mode Exit fullscreen mode

How to Use It

Increment version numbers automatically:

bump-my-version patch   # Updates 1.2.3 β†’ 1.2.4
bump-my-version minor   # Updates 1.2.3 β†’ 1.3.0
bump-my-version major   # Updates 1.2.3 β†’ 2.0.0
Enter fullscreen mode Exit fullscreen mode

This ensures versioning consistency, preventing human errors in updates.


Validating Versions in CI/CD

To prevent mismatched versions between GitHub tags and your package metadata, add a validation step to GitHub Actions.

CI Workflow to Validate Versions

Create .github/workflows/version-check.yml:

name: Version Check

on:
  push:
    tags:
      - 'v*'  # Runs only on version tags

jobs:
  check-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Validate package version consistency
        run: |
          TAG_VERSION=${GITHUB_REF#refs/tags/v}
          PACKAGE_VERSION=$(python -c "import my_package.__version__ as v; print(v.__version__)")

          if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
            echo "Version mismatch! GitHub tag is $TAG_VERSION but package version is $PACKAGE_VERSION."
            exit 1
          fi
Enter fullscreen mode Exit fullscreen mode

βœ… If the versions don’t match, the pipeline will fail, preventing a broken release.


Mistakes to Avoid

🚨 Hardcoding Versions in Multiple Files – Instead, use __version__.py

🚨 Pushing GitHub Tags Without Updating Files First

🚨 Ignoring Dependency Locking (requirements.txt)

🚨 Manual Version Updates Instead of Automation (bump-my-version)

Avoid these, and your releases will be smooth! πŸš€


Final Checklist

βœ… Keep version centralized in __version__.py

βœ… Always sync pyproject.toml (for Poetry users)

βœ… Automate with bump-my-version

βœ… Validate version consistency in CI/CD

βœ… Lock dependencies for reliable builds


FAQs

1. Why is bump2version no longer recommended?

bump2version is no longer maintained. bump-my-version is the modern alternative with active support.

2. How do I ensure my GitHub release matches my package version?

Use GitHub Actions to verify that the Git tag matches __version__.py before releasing.

3. Should I use setup.py or Poetry?

  • If you use setuptools, update setup.py
  • If you use Poetry, manually update pyproject.toml

4. Do I still need requirements.txt if using Poetry?

No! Poetry manages dependencies internally, so requirements.txt is unnecessary.

5. Is bump-my-version required?

No, but it automates versioning, preventing human mistakes.


Conclusion

Keeping your Python packaging metadata in sync with GitHub release tags prevents deployment issues, enables automation, and ensures smooth releases.

By following best practices like centralized versioning, GitHub Actions validation, and automated version bumps, you'll create a robust, foolproof versioning system!

Want to take it a step further? Integrate this workflow into your CI/CD pipeline today! πŸš€

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay