11name : Release
22
33on :
4- workflow_run :
5- workflows : ["CI"]
6- types :
7- - completed
4+ push :
5+ tags :
6+ - ' v*'
87
9- jobs :
10- evaluate-trigger :
11- runs-on : ubuntu-latest
12- outputs :
13- should_release : ${{ steps.resolve-tag.outputs.should_release }}
14- target_tag : ${{ steps.resolve-tag.outputs.target_tag }}
15- permissions :
16- contents : read
17- steps :
18- - name : Log triggering CI run
19- shell : bash
20- run : |
21- set -euo pipefail
22- head_branch="${{ github.event.workflow_run.head_branch }}"
23- if [ -z "$head_branch" ]; then
24- head_branch="<none>"
25- fi
26-
27- echo "Triggered by CI run #${{ github.event.workflow_run.run_number }}"
28- echo "event=${{ github.event.workflow_run.event }}"
29- echo "conclusion=${{ github.event.workflow_run.conclusion }}"
30- echo "head_branch=${head_branch}"
31- echo "head_sha=${{ github.event.workflow_run.head_sha }}"
32-
33- - name : Checkout repository for tag resolution
34- if : ${{ github.event.workflow_run.event == 'push' && github.event.workflow_run.conclusion == 'success' }}
35- uses : actions/checkout@v4
36- with :
37- fetch-depth : 0
38- ref : ${{ github.event.workflow_run.head_sha }}
39-
40- - name : Resolve release target
41- id : resolve-tag
42- shell : bash
43- run : |
44- set -euo pipefail
45- echo "should_release=false" >> "$GITHUB_OUTPUT"
46- echo "target_tag=" >> "$GITHUB_OUTPUT"
47-
48- event="${{ github.event.workflow_run.event }}"
49- conclusion="${{ github.event.workflow_run.conclusion }}"
50- head_branch="${{ github.event.workflow_run.head_branch }}"
51- head_sha="${{ github.event.workflow_run.head_sha }}"
52-
53- if [ "$event" != "push" ]; then
54- echo "Skipping release: CI completed for event '$event', not a push."
55- exit 0
56- fi
57-
58- if [ -n "$head_branch" ]; then
59- echo "Skipping release: CI completed for branch '$head_branch', not a tag push."
60- exit 0
61- fi
62-
63- case "$conclusion" in
64- success)
65- ;;
66- failure|cancelled|timed_out|action_required)
67- echo "Release blocked: CI for tag candidate at $head_sha concluded with '$conclusion'."
68- exit 1
69- ;;
70- *)
71- echo "Release blocked: CI completed with unexpected conclusion '$conclusion' for tag candidate at $head_sha."
72- exit 1
73- ;;
74- esac
75-
76- git fetch --force --tags origin
77- mapfile -t matching_tags < <(git tag --points-at "$head_sha" 'v*' | sort)
78-
79- if [ "${#matching_tags[@]}" -eq 0 ]; then
80- echo "Release blocked: CI looks like a tag run, but no v* tag points at $head_sha."
81- exit 1
82- fi
83-
84- if [ "${#matching_tags[@]}" -gt 1 ]; then
85- printf 'Release blocked: multiple v* tags point at %s: %s\n' "$head_sha" "${matching_tags[*]}"
86- exit 1
87- fi
88-
89- target_tag="${matching_tags[0]}"
90- echo "Resolved release tag: ${target_tag}"
91- echo "should_release=true" >> "$GITHUB_OUTPUT"
92- echo "target_tag=${target_tag}" >> "$GITHUB_OUTPUT"
8+ concurrency :
9+ group : release-${{ github.ref }}
10+ cancel-in-progress : false
9311
12+ jobs :
9413 create-release :
95- needs : evaluate-trigger
96- if : ${{ needs.evaluate-trigger.outputs.should_release == 'true' }}
9714 runs-on : ubuntu-latest
98- concurrency :
99- group : release-${{ needs.evaluate-trigger.outputs.target_tag }}
100- cancel-in-progress : false
10115 permissions :
10216 contents : write
10317 steps :
10721 uses : actions/checkout@v4
10822 with :
10923 fetch-depth : 0
110- ref : ${{ github.event.workflow_run.head_sha }}
11124
11225 - name : Checkout repository (attempt 2)
11326 id : checkout_attempt_2
@@ -116,18 +29,12 @@ jobs:
11629 uses : actions/checkout@v4
11730 with :
11831 fetch-depth : 0
119- ref : ${{ github.event.workflow_run.head_sha }}
12032
12133 - name : Checkout repository (attempt 3)
12234 if : ${{ steps.checkout_attempt_1.outcome == 'failure' && steps.checkout_attempt_2.outcome == 'failure' }}
12335 uses : actions/checkout@v4
12436 with :
12537 fetch-depth : 0
126- ref : ${{ github.event.workflow_run.head_sha }}
127-
128- - name : Log release target
129- run : |
130- echo "Creating release for ${{ needs.evaluate-trigger.outputs.target_tag }} at ${{ github.event.workflow_run.head_sha }}"
13138
13239 - name : Setup Python
13340 uses : actions/setup-python@v5
@@ -137,17 +44,17 @@ jobs:
13744 - name : Generate release changelog
13845 run : |
13946 python3 scripts/generate_release_changelog.py \
140- --target-ref "${{ needs.evaluate-trigger.outputs.target_tag } }" \
141- --tag-name "${{ needs.evaluate-trigger.outputs.target_tag } }" \
47+ --target-ref "${GITHUB_REF_NAME }" \
48+ --tag-name "${GITHUB_REF_NAME }" \
14249 --output "release-changelog.md"
14350
14451 - name : Create GitHub Release
14552 uses : softprops/action-gh-release@v2
14653 with :
147- tag_name : ${{ needs.evaluate-trigger.outputs.target_tag }}
148- target_commitish : ${{ github.event.workflow_run.head_sha }}
54+ tag_name : ${{ github.ref_name }}
55+ target_commitish : ${{ github.sha }}
14956 draft : false
150- prerelease : ${{ contains(needs.evaluate-trigger.outputs.target_tag , '-') }}
57+ prerelease : ${{ contains(github.ref_name , '-') }}
15158 generate_release_notes : false
15259 body_path : release-changelog.md
15360 env :
0 commit comments