Skip to content

Publishing PyCharter to PyPI

Releases are tag-driven: push a version tag on main and the CI workflow runs tests, builds the package, publishes to PyPI, and creates a GitHub Release.

Quick start

  1. From main, create and push a tag (use the version you want, e.g. 0.0.33):
git tag v0.0.33
git push origin v0.0.33
  1. That’s it. The workflow (.github/workflows/publish.yml) will:
  2. Run the test suite
  3. Build the UI and Python package
  4. Publish to PyPI (Trusted Publishing, no tokens in the repo)
  5. Create a GitHub Release for that tag

The tag is the source of truth for the published version: the workflow derives the version from the tag (e.g. v0.0.330.0.33) and uses it for the build. You don’t have to edit pyproject.toml before tagging if you don’t care about having the version in the repo updated.

Optional: keep pyproject.toml in sync

If you want the version in the repo to match the release, you can:

  • Bump version in pyproject.toml before or after the release, or
  • Use the release script (which bumps version, commits, tags, and pushes):
./bin/release.sh 0.0.33

The script will create the tag; the workflow still uses the tag for the version published to PyPI.

How it works

Workflow triggers

  • Push to a tag v* (e.g. v0.0.33): full release (tests → build → PyPI → GitHub Release).
  • Manual run (workflow_dispatch): uses the version in pyproject.toml, runs tests and build, publishes to PyPI. No GitHub Release is created.

Trusted Publishing

PyPI Trusted Publishing is used: no API tokens are stored in GitHub. The workflow uses OIDC; configure the Trusted Publisher on PyPI for this repo and workflow file.

Version from tag

On tag push, the workflow sets the package version from the tag (e.g. v0.0.330.0.33) and updates pyproject.toml in CI for that run only. The tag is the single source of truth for what gets published.

Local builds

From the repo root:

# Full build (with UI)
make clean && make build

# Core package only (no Node.js)
make clean && python -m build

To test publishing locally (requires tokens):

export TWINE_PASSWORD=your-testpypi-token
make publish-test

Troubleshooting

  • Workflow didn’t run: Ensure you pushed a tag matching v* (e.g. v0.0.33) to the default branch.
  • Trusted Publishing failed: On PyPI, check the Trusted Publisher for this repository and workflow (e.g. .../workflows/publish.yml). The workflow must have permissions: id-token: write.
  • Version already on PyPI: Use a new version and a new tag (e.g. v0.0.34).

Quick reference

# Release (from main)
git tag v0.0.33
git push origin v0.0.33

# Optional: use release script (bumps version, tags, pushes)
./bin/release.sh 0.0.33