Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ jobs:
exit 1
fi
VERSION="${TAG#v}"
PKG_VERSION=$(python -c "
import tomllib
with open('pyproject.toml', 'rb') as f:
print(tomllib.load(f)['project']['version'])
")
PKG_VERSION=$(sed -nE 's/.*VERSION *= *"([^"]+)".*/\1/p' segment/analytics/version.py)
if [ -z "$PKG_VERSION" ]; then
echo "::error::Could not read VERSION from segment/analytics/version.py"
exit 1
fi
if [ "$VERSION" != "$PKG_VERSION" ]; then
echo "::error::Tag $TAG does not match pyproject.toml version $PKG_VERSION"
echo "::error::Tag $TAG does not match VERSION $PKG_VERSION in segment/analytics/version.py"
exit 1
fi

Expand Down
32 changes: 20 additions & 12 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
Releasing
=========

Publishing happens in CI through PyPI Trusted Publishing (OIDC). There is no
PyPI token to hold locally, and `make release` is not the release path — it
uploads with a stored credential and skips provenance.
Publishing happens in CI through PyPI Trusted Publishing (OIDC). There is no PyPI token
to hold locally.

1. Update the version in **both** `pyproject.toml` and
`segment/analytics/version.py`. The publish workflow validates the release
tag against `pyproject.toml` and fails if the two disagree.
2. Update `HISTORY.md`.
3. `git commit -am "Release X.Y.Z."` (where X.Y.Z is the new version)
1. Update `VERSION` in `segment/analytics/version.py`. This is the only place the
version lives — hatchling reads it at build time, and the publish workflow validates
the release tag against it.
2. In `HISTORY.md`, change the `Unreleased` heading to `X.Y.Z / YYYY-M-D`.
3. `git commit -am "Release X.Y.Z."`
4. Open a PR and merge it to `master`.
5. Tag the merged commit and push it:
`git tag -a X.Y.Z -m "Version X.Y.Z" && git push --tags`
5. Tag the merged commit — no `v` prefix:

```
git tag X.Y.Z && git push origin X.Y.Z
```

6. Create a **GitHub Release** for that tag. The workflow triggers on
`release: published`; pushing the tag by itself does not start it.
7. Approve the `production` environment when the publish job requests review.

The workflow runs the test matrix, builds with `uv`, and uploads with twine, which
performs the OIDC exchange itself — no flag is needed.

The workflow then runs the test matrix, builds with `uv`, and uploads to PyPI
with `--trusted-publishing=always`.
> **Note:** the workflow runs from the *tagged* commit. If it needs fixing, the tag has
> to be recreated after the fix lands; merging to `master` alone changes nothing for a
> release that is already tagged.
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "segment-analytics-python"
version = "2.4.0"
dynamic = ["version"]
description = "The hassle-free way to integrate analytics into any python application."
readme = "README.md"
license = "MIT"
Expand Down Expand Up @@ -41,6 +41,9 @@ dev = [
"mock>=2.0",
]

[tool.hatch.version]
path = "segment/analytics/version.py"

[tool.hatch.build.targets.wheel]
packages = ["segment"]

Expand Down
Loading