-
Notifications
You must be signed in to change notification settings - Fork 0
92 lines (84 loc) · 3.5 KB
/
Copy pathrelease.yml
File metadata and controls
92 lines (84 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
name: GitHub Release
on:
push:
tags:
- 'v[0-9]*'
# Repair the Release for a tag that already exists, without moving it. See
# RELEASING.md, "If a release workflow fails" — added alongside this trigger,
# since a capability nobody can find is not much better than not having it.
workflow_dispatch:
inputs:
tag:
description: Existing tag to create or update a Release for (e.g. v1.2.3)
required: true
type: string
permissions:
contents: write
jobs:
release:
name: Create GitHub Release
runs-on: ubuntu-latest
env:
# The tag being released, whether it arrived by push or by dispatch.
TAG: ${{ inputs.tag || github.ref_name }}
steps:
# Before checkout, because checkout resolves the input as an arbitrary ref
# — and this workflow needs the guard more than publish.yml does. It holds
# `contents: write`, and action-gh-release CREATES a tag when tag_name does
# not resolve to one, so an unvalidated `tag: main` would check out cleanly
# and leave refs/tags/main plus a release named for it. The push path is
# constrained by the v[0-9]* filter; the dispatch path was not constrained
# at all.
- name: Validate release tag format
if: github.event_name == 'workflow_dispatch'
env:
INPUT_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [[ ! "$INPUT_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "tag must look like vX.Y.Z, got: $INPUT_TAG" >&2
exit 1
fi
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.12'
- name: Read package metadata
id: meta
run: |
pkg_name=$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['name'])")
pkg_version="${TAG#v}"
echo "name=${pkg_name}" >> "$GITHUB_OUTPUT"
echo "version=${pkg_version}" >> "$GITHUB_OUTPUT"
- name: Extract changelog notes
id: notes
run: |
set -euo pipefail
version="${TAG#v}"
if [[ -f CHANGELOG.md ]]; then
body="$(python scripts/extract-changelog.py "$version")"
else
body="Release ${version}."
fi
delimiter="EOF_${RANDOM}_${RANDOM}"
{
echo "body<<${delimiter}"
echo "$body"
echo "${delimiter}"
} >> "$GITHUB_OUTPUT"
- name: Create GitHub Release
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
with:
tag_name: ${{ inputs.tag || github.ref_name }}
name: ${{ steps.meta.outputs.name }} ${{ steps.meta.outputs.version }}
body: ${{ steps.notes.outputs.body }}
generate_release_notes: false
# Let GitHub decide by tag date/semver rather than by run order. On a
# push the tag is the newest version and becomes latest; on a dispatch
# repairing an older tag, a newer release keeps the badge. Note `false`
# is not "leave alone" — it explicitly marks a release NOT latest, so
# gating on the event would demote the newest tag in the very case this
# trigger exists for: repairing its Release after a failed push run.
make_latest: legacy