Skip to content

Commit f592f4d

Browse files
committed
ci(release): support manual prerelease publishing
Allow the Release workflow to run from workflow_dispatch using a version input, derive prerelease status from the package version, and limit release assets to the current build output.
1 parent 492c2ac commit f592f4d

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

.github/workflows/release.yml

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ on:
44
push:
55
tags:
66
- "v*"
7+
workflow_dispatch:
8+
inputs:
9+
version:
10+
description: "Project version from pyproject.toml, for example 0.2.0a0"
11+
required: true
12+
type: string
713

814
permissions:
915
contents: write
@@ -22,23 +28,44 @@ jobs:
2228
with:
2329
python-version: "3.11"
2430

25-
- name: Verify tag matches project version
31+
- name: Resolve release metadata
32+
id: release_meta
2633
env:
34+
GITHUB_EVENT_NAME: ${{ github.event_name }}
2735
GITHUB_REF_NAME: ${{ github.ref_name }}
36+
INPUT_VERSION: ${{ inputs.version }}
2837
run: |
2938
python - <<'PY'
3039
import os
3140
import pathlib
41+
import re
3242
import tomllib
3343
3444
pyproject = pathlib.Path("pyproject.toml")
3545
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
3646
version = data["project"]["version"]
37-
expected_tag = f"v{version}"
38-
actual_tag = os.environ["GITHUB_REF_NAME"]
39-
40-
if actual_tag != expected_tag:
41-
raise SystemExit(f"Tag {actual_tag!r} does not match project version {expected_tag!r}.")
47+
event_name = os.environ["GITHUB_EVENT_NAME"]
48+
actual_tag = os.environ.get("GITHUB_REF_NAME", "")
49+
requested_version = os.environ.get("INPUT_VERSION", "").strip()
50+
51+
if event_name == "workflow_dispatch":
52+
if requested_version != version:
53+
raise SystemExit(
54+
f"Manual release version {requested_version!r} does not match project version {version!r}."
55+
)
56+
release_tag = f"v{version}"
57+
else:
58+
expected_tag = f"v{version}"
59+
if actual_tag != expected_tag:
60+
raise SystemExit(f"Tag {actual_tag!r} does not match project version {expected_tag!r}.")
61+
release_tag = actual_tag
62+
63+
prerelease = bool(re.search(r"[A-Za-z]", version))
64+
github_output = pathlib.Path(os.environ["GITHUB_OUTPUT"])
65+
with github_output.open("a", encoding="utf-8") as handle:
66+
handle.write(f"version={version}\n")
67+
handle.write(f"tag={release_tag}\n")
68+
handle.write(f"prerelease={'true' if prerelease else 'false'}\n")
4269
PY
4370
4471
- name: Install release tooling
@@ -53,19 +80,23 @@ jobs:
5380
run: python -m build
5481

5582
- name: Validate package metadata
56-
run: python -m twine check dist/*
83+
run: python -m twine check dist/always_attend-${{ steps.release_meta.outputs.version }}*
5784

5885
- name: Publish GitHub release
5986
uses: softprops/action-gh-release@v2
6087
with:
61-
files: dist/*
88+
tag_name: ${{ steps.release_meta.outputs.tag }}
89+
name: ${{ steps.release_meta.outputs.tag }}
90+
target_commitish: ${{ github.sha }}
91+
prerelease: ${{ steps.release_meta.outputs.prerelease == 'true' }}
92+
files: dist/always_attend-${{ steps.release_meta.outputs.version }}*
6293
generate_release_notes: true
6394

6495
- name: Upload release artifacts
6596
uses: actions/upload-artifact@v4
6697
with:
6798
name: python-dist
68-
path: dist/
99+
path: dist/always_attend-${{ steps.release_meta.outputs.version }}*
69100

70101
publish-pypi:
71102
needs: build-release

0 commit comments

Comments
 (0)