This guide covers the development workflow for pyblu, including how to release new versions and handle issues that may arise.
- Clone the repository:
git clone https://github.com/LouisChrist/pyblu.git
cd pyblu- Install dependencies:
uv sync- Run tests and checks:
uv run pytest # Run tests
uv run pylint src tests # Run linting
uv run black src tests # Format code
uv run mypy src # Type checkThe project uses an automated CI/CD pipeline for building and publishing releases to PyPI. The process is triggered when you create and push a version tag.
-
GitHub Token: Set the
GITHUB_TOKEN_PYBLUenvironment variable with a GitHub personal access token that has repository access. -
PyPI Trusted Publisher: The project uses PyPI's Trusted Publisher feature (OIDC authentication) instead of API tokens.
- Ensure you're on the
mainbranch with no uncommitted changes:
git checkout main
git pull
git status # Should show clean working directory- Run the release task:
uv run invoke release-
The script will:
- Display current version and bump options (patch/minor/major)
- Prompt you to select which version component to bump
- Update
pyproject.tomlwith the new version - Create a git commit with message
Release v{version} - Create a git tag
v{version} - Push the commit and tag to GitHub
- Create a GitHub release with auto-generated release notes
-
Once the tag is pushed, the CI/CD pipeline automatically:
- Runs all quality gates (lint, typecheck, test)
- Builds the package (sdist and wheel)
- Publishes to PyPI using Trusted Publisher authentication
-
Monitor the release workflow at: https://github.com/LouisChrist/pyblu/actions
To test the build process without actually publishing to PyPI:
- Go to the GitHub Actions page: https://github.com/LouisChrist/pyblu/actions/workflows/release.yml
- Click "Run workflow"
- Check the "Run build without publishing (dry-run)" checkbox
- Select the branch (usually
main) - Click "Run workflow"
This will run all quality gates and build the package, but skip the PyPI publish step. You can download the built artifacts to inspect them.
Trusted Publisher must be configured once on PyPI. This allows GitHub Actions to publish packages without using API tokens.
-
If the project already exists on PyPI:
- Go to https://pypi.org/manage/project/pyblu/settings/publishing/
- Add a new "Trusted Publisher"
-
If this is the first release:
- Use "Pending Publisher" at https://pypi.org/manage/account/publishing/
-
Configure with these details:
- PyPI Project Name:
pyblu - Owner:
LouisChrist - Repository name:
pyblu - Workflow name:
release.yml - Environment name:
pypi
- PyPI Project Name:
-
Save the configuration
The GitHub Actions workflow is already configured with the necessary permissions (id-token: write) to authenticate using OIDC.
If a release failed some of these steps might be necessary:
Delete locally and remotely:
# Delete local tag
git tag -d v{version}
# Delete remote tag
git push origin :refs/tags/v{version}- Go to https://github.com/LouisChrist/pyblu/releases
- Find the release for the version
- Click "Delete" to remove it
# Find the commit hash of the version bump
git log --oneline -n 5
# Revert the commit
git revert <commit-hash>
# Push the revert
git push origin mainAfter rolling back:
- Fix the issue in the codebase
- Run
uv run invoke releaseagain to create a new release with the fix
If lint, typecheck, or tests fail:
- The workflow will stop before building/publishing
- Fix the issues locally
- The tag already exists, so you need to:
- Delete the tag (see rollback procedure)
- Fix the code
- Run
uv run invoke releaseagain
Error: Authentication failed: OIDC token is invalid or expired
Solutions:
- Verify the Trusted Publisher is configured correctly on PyPI
- Check that the workflow name is exactly
release.yml - Ensure the environment name is exactly
pypi - Verify the repository owner and name match exactly
If the publish step can't find the built packages:
- Check the
buildjob completed successfully - Verify artifacts were uploaded (check the build job logs)
- Ensure artifact name matches in download step (
dist)
If you try to re-release a version:
- PyPI will reject it (versions are immutable)
- You must bump to a new version number
- Consider using a post-release version (e.g.,
1.2.3.post1) for quick fixes
Error: GITHUB_TOKEN_PYBLU environment variable is required
Solutions:
- Set the environment variable:
export GITHUB_TOKEN_PYBLU=ghp_... - Generate a token at: https://github.com/settings/tokens
- Required scopes:
repo(full repository access)
Error: There are uncommitted changes
Solutions:
- Commit or stash your changes before releasing
- Use
git statusto see what's uncommitted - The release must be from a clean working directory
Build documentation locally:
uv run invoke build-docsDocumentation is automatically deployed to GitHub Pages when a version tag is pushed.
Format code and run linters:
uv run invoke format-and-lint # Formats with black and runs pylintIf commits with version changes are missing tags:
uv run invoke add-missing-tagsThis will scan git history and create tags for any version bumps that weren't tagged.