Skip to content

Commit edd8196

Browse files
committed
Add PyPI publish CD (release-labelled PR -> build & upload)
Adds two GitHub Actions workflows: - prepare-release.yml: manual dispatch; bumps version= in setup.py and opens a PR labelled "release". - publish.yml: on merge of the labelled PR, builds sdist+wheel, uploads to PyPI via twine, then creates the version git tag + GitHub release. Requires repo secret PYPI_API_TOKEN and the "Allow GitHub Actions to create and approve pull requests" setting enabled.
1 parent 9ea3601 commit edd8196

2 files changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Prepare release PR
2+
3+
# Step 1 of the release flow.
4+
# Manually triggered. Bumps the version in setup.py and opens a PR labelled
5+
# `release`. Merging that PR fires `publish.yml`.
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: "Release version, e.g. 7.2.3 (sets the ravendb package version)."
12+
required: true
13+
type: string
14+
15+
permissions:
16+
contents: write
17+
pull-requests: write
18+
19+
jobs:
20+
prepare:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Bump version
26+
env:
27+
VERSION: ${{ inputs.version }}
28+
run: |
29+
set -euo pipefail
30+
sed -i -E "s/version=\"[0-9][^\"]*\"/version=\"${VERSION}\"/" setup.py
31+
32+
echo "----- setup.py -----"
33+
grep -nE 'version=|python_requires' setup.py || true
34+
35+
if git diff --quiet; then
36+
echo "::error::No version string changed. Check the sed pattern against setup.py."
37+
exit 1
38+
fi
39+
40+
- name: Create release PR
41+
uses: peter-evans/create-pull-request@v7
42+
with:
43+
token: ${{ secrets.GITHUB_TOKEN }}
44+
base: ${{ github.event.repository.default_branch }}
45+
branch: release/${{ inputs.version }}
46+
delete-branch: true
47+
commit-message: "Release ${{ inputs.version }}"
48+
title: "Release ${{ inputs.version }}"
49+
labels: release
50+
body: |
51+
Automated release for **ravendb ${{ inputs.version }}** (Python client).
52+
53+
Bumps the version in `setup.py`.
54+
55+
> [!WARNING]
56+
> Merging this PR **while the `release` label is set** triggers the
57+
> **Publish to PyPI** workflow, which builds and uploads the package and
58+
> creates the `${{ inputs.version }}` GitHub release.
59+
60+
Review the diff, then merge to publish. Remove the `release` label before
61+
merging if you do **not** want to publish.

.github/workflows/publish.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Publish to PyPI
2+
3+
# Step 2 of the release flow.
4+
# Fires when a PR labelled `release` is merged (the PR opened by prepare-release.yml).
5+
# Also runnable manually as an emergency fallback (publishes whatever is on the branch).
6+
7+
on:
8+
pull_request:
9+
types: [closed]
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: write # create the git tag / GitHub release
14+
15+
jobs:
16+
publish:
17+
# Only on manual run, or on a merged PR that carried the `release` label.
18+
if: >-
19+
github.event_name == 'workflow_dispatch' ||
20+
(github.event.pull_request.merged == true &&
21+
contains(github.event.pull_request.labels.*.name, 'release'))
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v4
25+
with:
26+
ref: ${{ github.event.pull_request.base.ref || github.ref_name }}
27+
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: "3.11"
31+
32+
- name: Install build tooling
33+
run: python -m pip install --upgrade pip setuptools wheel twine
34+
35+
- name: Build sdist + wheel
36+
run: python setup.py sdist bdist_wheel
37+
38+
- name: Read package version
39+
id: ver
40+
run: echo "version=$(python setup.py --version)" >> "$GITHUB_OUTPUT"
41+
42+
- name: Publish to PyPI
43+
env:
44+
TWINE_USERNAME: __token__
45+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
46+
run: twine upload --non-interactive --skip-existing dist/*
47+
48+
- name: Tag & GitHub release
49+
env:
50+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51+
VERSION: ${{ steps.ver.outputs.version }}
52+
TARGET: ${{ github.event.pull_request.base.ref || github.ref_name }}
53+
run: |
54+
set -euo pipefail
55+
if gh release view "${VERSION}" >/dev/null 2>&1; then
56+
echo "Release ${VERSION} already exists, skipping."
57+
else
58+
gh release create "${VERSION}" \
59+
--target "${TARGET}" \
60+
--title "${VERSION}" \
61+
--notes "ravendb ${VERSION} published to PyPI."
62+
fi

0 commit comments

Comments
 (0)