Skip to content
Open
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
70 changes: 70 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Prepare release PR

# Step 1 of the release flow.
# Manually triggered. Bumps the version in setup.py and RequestExecutor.CLIENT_VERSION,
# then opens a PR labelled `release`. Merging that PR fires `publish.yml`.

on:
workflow_dispatch:
inputs:
version:
description: "Release version, e.g. 7.2.3 (sets the ravendb package version)."
required: true
type: string

permissions:
contents: write
pull-requests: write

jobs:
prepare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Bump version
env:
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
# setup.py carries the full PEP 440 version, incl. any .postN/.devN/rcN suffix.
sed -i -E "s/version=\"[0-9][^\"]*\"/version=\"${VERSION}\"/" setup.py

# RequestExecutor.CLIENT_VERSION is the server-facing client version and tracks
# the clean release number only (a 7.2.1.post1 hotfix keeps CLIENT_VERSION 7.2.1).
CLIENT_VERSION="$(printf '%s' "${VERSION}" | sed -E 's/(\.post[0-9]+|\.dev[0-9]+|(a|b|rc)[0-9]+).*$//')"
sed -i -E "s/CLIENT_VERSION = \".*\"/CLIENT_VERSION = \"${CLIENT_VERSION}\"/" ravendb/http/request_executor.py

echo "----- setup.py -----"
grep -nE 'version=' setup.py || true
echo "----- request_executor.py -----"
grep -nE 'CLIENT_VERSION = ' ravendb/http/request_executor.py || true

if git diff --quiet; then
echo "::error::No version strings changed. Check the sed patterns."
exit 1
fi

- name: Create release PR
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
base: ${{ github.event.repository.default_branch }}
branch: release/${{ inputs.version }}
delete-branch: true
commit-message: "Release ${{ inputs.version }}"
title: "Release ${{ inputs.version }}"
labels: release
body: |
Automated release for **ravendb ${{ inputs.version }}** (Python client).

Bumps `version` in `setup.py` and `RequestExecutor.CLIENT_VERSION`
(`.postN`/`.devN`/`rcN` suffixes are stripped from `CLIENT_VERSION`).

> [!WARNING]
> Merging this PR **while the `release` label is set** triggers the
> **Publish to PyPI** workflow, which builds and uploads the package and
> creates the `${{ inputs.version }}` GitHub release.

Review the diff, then merge to publish. Remove the `release` label before
merging if you do **not** want to publish.
62 changes: 62 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Publish to PyPI

# Step 2 of the release flow.
# Fires when a PR labelled `release` is merged (the PR opened by prepare-release.yml).
# Also runnable manually as an emergency fallback (publishes whatever is on the branch).

on:
pull_request:
types: [closed]
workflow_dispatch:

permissions:
contents: write # create the git tag / GitHub release

jobs:
publish:
# Only on manual run, or on a merged PR that carried the `release` label.
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'release'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref || github.ref_name }}

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install build tooling
run: python -m pip install --upgrade pip setuptools wheel twine

- name: Build sdist + wheel
run: python setup.py sdist bdist_wheel

- name: Read package version
id: ver
run: echo "version=$(python setup.py --version)" >> "$GITHUB_OUTPUT"

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload --non-interactive --skip-existing dist/*

- name: Tag & GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.ver.outputs.version }}
TARGET: ${{ github.event.pull_request.base.ref || github.ref_name }}
run: |
set -euo pipefail
if gh release view "${VERSION}" >/dev/null 2>&1; then
echo "Release ${VERSION} already exists, skipping."
else
gh release create "${VERSION}" \
--target "${TARGET}" \
--title "${VERSION}" \
--notes "ravendb ${VERSION} published to PyPI."
fi
Loading