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
814permissions :
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