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.33 → 0.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 (commit/push/merge/tag):
./scripts/release.sh release

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.33 → 0.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)
./scripts/release.sh release