This document describes the process for deploying a new version of data-spec-validator to PyPI.
There are two ways to deploy to PyPI:
- Automated via GitHub Actions (Recommended) - Automatically publishes when you create a GitHub release
- Manual deployment - Using
twinedirectly from your local machine
For Production PyPI:
- Go to https://pypi.org/manage/account/token/
- Click "Add API token"
- Token name:
data-spec-validator-github-actions(or any name you prefer) - Scope: Select "Project: data-spec-validator" (recommended) or "Entire account"
- Click "Add token"
- Copy the token (starts with
pypi-) - you won't see it again!
For Test PyPI (optional, for manual testing):
- Go to https://test.pypi.org/manage/account/token/
- Follow the same steps as above
- Copy the token
- Go to repository settings: https://github.com/hardcoretech/data-spec-validator/settings/secrets/actions
- Click "New repository secret"
- For production PyPI:
- Name:
PYPI_API_TOKEN - Secret: Paste your PyPI token (the
pypi-...string) - Click "Add secret"
- Name:
- For Test PyPI (if you want manual testing):
- Click "New repository secret" again
- Name:
TEST_PYPI_API_TOKEN - Secret: Paste your Test PyPI token
- Click "Add secret"
- Prepare the release (see "Prepare the Release" section below)
- Create a GitHub Release:
- Go to https://github.com/hardcoretech/data-spec-validator/releases/new
- Create a new tag:
vX.Y.Z(e.g.,v3.5.1) - Set release title:
vX.Y.Z - Copy the changelog entry for this version into the description
- Click "Publish release"
- GitHub Actions will automatically:
- Build the package
- Upload to production PyPI
- You can monitor progress at https://github.com/hardcoretech/data-spec-validator/actions
You can manually trigger the workflow to test deployment or deploy to production:
- Go to Actions tab:
- Click "Run workflow"
- Select target:
- Choose
testpypito test deployment (requiresTEST_PYPI_API_TOKENsecret) - Choose
pypito deploy to production PyPI
- Choose
- Click "Run workflow"
- Monitor the workflow execution in the Actions tab
- Python 3.8 or higher
twineinstalled (pip install twine)- PyPI account with maintainer permissions for
data-spec-validator - PyPI API token configured
pip install build twineOption 1: Environment Variables (Recommended)
# Set credentials as environment variables
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=your-pypi-token-here
# Twine will automatically use these
twine upload dist/*Option 2: Using .pypirc file
Create .pypirc in the project root (for multiple profiles):
[distutils]
index-servers =
pypi
testpypi
[pypi]
repository = https://upload.pypi.org/legacy/
username = __token__
password = <paste-your-token-here>
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = <paste-your-token-here>Important: Never commit .pypirc to version control (it's already in .gitignore).
Option 3: Pass credentials directly
twine upload dist/* -u __token__ -p "${PYPI_TOKEN}"-
Fetch the latest develop branch:
git fetch origin develop git checkout develop git pull origin develop
-
Update the version number:
- Edit
data_spec_validator/__version__.py - Update the version following Semantic Versioning:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality additions
- PATCH version for backwards-compatible bug fixes
- Edit
-
Update the CHANGELOG:
- Edit
CHANGELOG.md - Add a new section at the top with the new version number
- Document all changes since the last release:
[feature]for new features[fix]for bug fixes[improvement]for enhancements[behavior-change]for breaking changes[internal]for internal refactoring
- Edit
-
Commit the version bump:
git add data_spec_validator/__version__.py CHANGELOG.md git commit -m "bump version to X.Y.Z" git push origin develop
Install build tools:
pip install build twineBuild the package:
# Clean old builds
rm -rf dist/ build/ *.egg-info
# Build source distribution and wheel
python -m buildUpload to Test PyPI (for testing):
twine upload --repository testpypi dist/*
# Or use a specific profile from .pypirc:
twine upload --config-file .pypirc -r testdsv dist/*Upload to Production PyPI:
twine upload dist/*
# Or use a specific profile from .pypirc:
twine upload --config-file .pypirc -r pypi dist/*Verify the upload:
# For Test PyPI
pip install --index-url https://test.pypi.org/simple/ --no-deps data-spec-validator
# For Production PyPI
pip install --upgrade data-spec-validator
python -c "from data_spec_validator.__version__ import __version__; print(__version__)"-
Create a Git tag:
git tag vX.Y.Z git push origin vX.Y.Z
-
Create a GitHub Release:
- Go to https://github.com/hardcoretech/data-spec-validator/releases/new
- Select the tag you just created
- Copy the changelog entry for this version
- Publish the release
- setup.py: Package metadata and dependencies
- pyproject.toml: Build system requirements (Black configuration)
- setup.cfg: Flake8 and isort configuration
- .pypirc: PyPI credentials (NOT committed to git)
- data_spec_validator/version.py: Current version number
- This means the version number is already uploaded to PyPI
- Increment the version number and try again
- PyPI does not allow re-uploading the same version
- Verify
.pypirccredentials are correct - Ensure you have maintainer permissions for the package
- Generate a new API token from https://pypi.org/manage/account/token/
- Test PyPI and production PyPI use separate accounts and API tokens
- The version may already exist on Test PyPI (each version can only be uploaded once)
- If testing is needed, increment to a dev version (e.g.,
3.5.2.dev1) for Test PyPI - Alternatively, skip Test PyPI and deploy directly to production if you're confident in the release
- Install twine:
pip install twine - Ensure twine is available in your PATH
- Ensure all dependencies are installed:
pip install -r requirements-dev.txt - Check that
setup.pyis valid:python setup.py check
# 1. Update version and changelog
git checkout develop
git pull origin develop
# Edit data_spec_validator/__version__.py
# Edit CHANGELOG.md
git add data_spec_validator/__version__.py CHANGELOG.md
git commit -m "bump version to X.Y.Z"
git push origin develop
# 2. Create GitHub release
# Go to: https://github.com/hardcoretech/data-spec-validator/releases/new
# Tag: vX.Y.Z
# Title: vX.Y.Z
# Description: Copy changelog entry
# Click "Publish release"
#
# GitHub Actions will automatically publish to PyPI# 1. Update version and changelog (same as above)
git checkout develop
git pull origin develop
# Edit data_spec_validator/__version__.py
# Edit CHANGELOG.md
git add data_spec_validator/__version__.py CHANGELOG.md
git commit -m "bump version to X.Y.Z"
git push origin develop
# 2. Manually trigger GitHub Action
# Go to: https://github.com/hardcoretech/data-spec-validator/actions/workflows/publish.yml
# Click "Run workflow"
# Select branch: develop
# Select environment: testpypi or pypi
# Click "Run workflow"
#
# Monitor at: https://github.com/hardcoretech/data-spec-validator/actions# 1. Update version and changelog
git checkout develop
git pull origin develop
# Edit data_spec_validator/__version__.py
# Edit CHANGELOG.md
git add data_spec_validator/__version__.py CHANGELOG.md
git commit -m "bump version to X.Y.Z"
git push origin develop
# 2. Build and deploy
pip install build twine
rm -rf dist/ build/ *.egg-info
python -m build
twine upload dist/*
# 3. Tag the release
git tag vX.Y.Z
git push origin vX.Y.Z
# 4. Create GitHub release at:
# https://github.com/hardcoretech/data-spec-validator/releases/new