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
18 changes: 12 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ env:
jobs:
test:
name: Test - Python ${{ matrix.python-version }}
runs-on: ${{ github.repository_owner == 'twilio' && 'ubuntu-x64' || 'ubuntu-latest' }}
if: github.repository_owner == 'twilio'
runs-on: ubuntu-x64
# Guards against forks publishing. Bare ubuntu-latest gets no runner in
# this org, so the fork branch of the old expression was unusable anyway.
if: github.repository_owner == 'segmentio'
permissions:
contents: read
id-token: write
Expand All @@ -34,8 +36,10 @@ jobs:
deploy:
name: Publish to PyPI
needs: [test]
runs-on: ${{ github.repository_owner == 'twilio' && 'ubuntu-x64' || 'ubuntu-latest' }}
if: github.repository_owner == 'twilio'
runs-on: ubuntu-x64
# Guards against forks publishing. Bare ubuntu-latest gets no runner in
# this org, so the fork branch of the old expression was unusable anyway.
if: github.repository_owner == 'segmentio'
environment: production
permissions:
contents: read
Expand All @@ -53,8 +57,10 @@ jobs:
- name: Validate tag format and version match
run: |
TAG="${GITHUB_REF#refs/tags/}"
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "::error::Release tag must be in the form v1.2.3 (got '$TAG')"
# This repo's tags carry no v prefix (2.3.6, 2.3.5, ...); accept both
# so the existing convention keeps working.
if [[ ! "$TAG" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "::error::Release tag must be X.Y.Z or vX.Y.Z (got '$TAG')"
exit 1
fi
VERSION="${TAG#v}"
Expand Down
21 changes: 16 additions & 5 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
Releasing
=========

1. Update `VERSION` in `segment/analytics/version.py` to the new version.
2. Update the `HISTORY.md` for the impending release.
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.

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)
4. `git tag -a X.Y.Z -m "Version X.Y.Z"` (where X.Y.Z is the new version).
5. `git push && git push --tags`
6. `make release`.
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`
6. Create a **GitHub Release** for that tag. The workflow triggers on
`release: published`; pushing the tag by itself does not start it.

The workflow then runs the test matrix, builds with `uv`, and uploads to PyPI
with `--trusted-publishing=always`.
Loading