|
| 1 | +# Releasing point-collocation to PyPI |
| 2 | + |
| 3 | +This document describes how to publish a new version of `point-collocation` to |
| 4 | +[PyPI](https://pypi.org/project/point-collocation/) using the automated |
| 5 | +GitHub Actions workflow. |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +Publishing is fully automated via `.github/workflows/publish.yml`. |
| 10 | +The workflow uses **PyPI Trusted Publishing** (OIDC) so no API tokens need to |
| 11 | +be stored in GitHub Secrets — authentication happens through a short-lived |
| 12 | +OIDC token issued by GitHub Actions. |
| 13 | + |
| 14 | +The workflow is triggered whenever a **GitHub Release is published**. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Step 1 — Bump the version |
| 19 | + |
| 20 | +Edit `pyproject.toml` and update the `version` field under `[project]`: |
| 21 | + |
| 22 | +```toml |
| 23 | +[project] |
| 24 | +name = "point-collocation" |
| 25 | +version = "0.2.0" # ← new version |
| 26 | +``` |
| 27 | + |
| 28 | +Commit the change directly to `main` (or open a PR and merge it first): |
| 29 | + |
| 30 | +```bash |
| 31 | +git add pyproject.toml |
| 32 | +git commit -m "chore: bump version to 0.2.0" |
| 33 | +git push origin main |
| 34 | +``` |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +## Step 2 — Create and push a git tag |
| 39 | + |
| 40 | +Tags must match the version in `pyproject.toml` and follow the `vX.Y.Z` format: |
| 41 | + |
| 42 | +```bash |
| 43 | +git tag v0.2.0 |
| 44 | +git push origin v0.2.0 |
| 45 | +``` |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## Step 3 — Create a GitHub Release |
| 50 | + |
| 51 | +1. Open the repository on GitHub. |
| 52 | +2. Click **Releases → Draft a new release**. |
| 53 | +3. Select the tag you just pushed (`v0.2.0`). |
| 54 | +4. Fill in the **Release title** and **Release notes**. |
| 55 | +5. Click **Publish release**. |
| 56 | + |
| 57 | +Publishing the release triggers the workflow automatically. |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +## What the workflow does |
| 62 | + |
| 63 | +1. **Build** — Runs `python -m build` to produce an sdist (`.tar.gz`) and a |
| 64 | + wheel (`.whl`) inside the `dist/` directory. |
| 65 | +2. **Smoke check** — Installs the built wheel and runs |
| 66 | + `import point_collocation` to confirm the package is importable. |
| 67 | +3. **Publish** — Uploads both artifacts to PyPI via |
| 68 | + [`pypa/gh-action-pypi-publish`](https://github.com/pypa/gh-action-pypi-publish) |
| 69 | + using Trusted Publishing (no stored token required). |
| 70 | + |
| 71 | +--- |
| 72 | + |
| 73 | +## One-time PyPI setup (Trusted Publishing) |
| 74 | + |
| 75 | +Before the workflow can publish for the first time you need to register |
| 76 | +GitHub as a trusted publisher on PyPI: |
| 77 | + |
| 78 | +1. Log in to <https://pypi.org> and navigate to the `point-collocation` |
| 79 | + project page (or create the project by uploading a first release manually). |
| 80 | +2. Go to **Manage → Settings → Trusted Publishers**. |
| 81 | +3. Click **Add a new publisher** and fill in: |
| 82 | + |
| 83 | + | Field | Value | |
| 84 | + |---|---| |
| 85 | + | Owner / organisation | `fish-pace` | |
| 86 | + | Repository name | `point-collocation` | |
| 87 | + | Workflow file name | `publish.yml` | |
| 88 | + | Environment name | *(leave blank)* | |
| 89 | + |
| 90 | +4. Save. |
| 91 | + |
| 92 | +From that point on, every GitHub Release will trigger a fully automated, |
| 93 | +token-free publish. |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## Troubleshooting |
| 98 | + |
| 99 | +### `403 Forbidden` — trusted publisher not configured |
| 100 | + |
| 101 | +The PyPI trusted publisher has not been set up yet, or the workflow filename / |
| 102 | +repo name does not match what was registered. |
| 103 | +**Fix:** complete the one-time setup described above. |
| 104 | + |
| 105 | +### `400 File already exists` — version already on PyPI |
| 106 | + |
| 107 | +PyPI does not allow re-uploading a version. |
| 108 | +**Fix:** bump the version in `pyproject.toml`, commit, re-tag, and create a |
| 109 | +new GitHub Release. |
| 110 | + |
| 111 | +### Metadata validation errors |
| 112 | + |
| 113 | +PyPI rejects packages with missing or invalid metadata. |
| 114 | +**Fix:** check `pyproject.toml` for required fields (`name`, `version`, |
| 115 | +`requires-python`, `readme`, `license`) and run `python -m build` locally to |
| 116 | +verify before tagging. |
| 117 | + |
| 118 | +### Smoke check fails |
| 119 | + |
| 120 | +The wheel is not importable — likely a packaging misconfiguration. |
| 121 | +**Fix:** confirm `[tool.hatch.build.targets.wheel].packages` in |
| 122 | +`pyproject.toml` points to `["src/point_collocation"]` and run |
| 123 | +`pip install dist/*.whl && python -c "import point_collocation"` locally. |
0 commit comments