Skip to content

Commit 359e998

Browse files
reyortiz3claude
andauthored
Trigger release notes via workflow_run not release event (#5490)
* Trigger release notes via workflow_run not release event The Generate Release Notes workflow ran anthropics/claude-code-action on the `release: published` event, but that action only accepts a fixed set of event types and rejects `release` with "Unsupported event type: release", failing the step before the skill could run. Switch the trigger to workflow_run on "Create Release Tag" (the workflow that creates the tag and GitHub Release). workflow_run is a supported event and is not subject to the GITHUB_TOKEN downstream-trigger limit. Resolve the tag from the VERSION file at the run's head commit and keep workflow_dispatch for manual runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Pass github_token to claude-code-action to skip OIDC Without a github_token input, the action mints its own token via OIDC (the Claude GitHub App flow), which fails with "Could not fetch an OIDC token" unless the workflow has id-token: write and the app installed. We only need the API key for Anthropic auth and GH_TOKEN for the skill's read-only gh calls, so pass github.token directly to bypass OIDC. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Check out default branch, not workflow_run head ref Checking out github.event.workflow_run.head_sha in a workflow that has access to secrets is the untrusted-checkout anti-pattern (flagged by CodeQL actions/untrusted-checkout, high). The head ref was only used to read VERSION; since "Create Release Tag" only runs on a VERSION push to main, main HEAD already is the release commit, so checking out the default branch yields the same VERSION without trusting an event ref. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 629b9b4 commit 359e998

1 file changed

Lines changed: 48 additions & 16 deletions

File tree

.github/workflows/release-notes.yml

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
# Generate Release Notes workflow
22
#
3-
# When a GitHub Release is published (by create-release-tag.yml after a release
4-
# PR merges), this workflow runs the `release-notes` Claude skill to produce
5-
# polished, copy-pasteable release notes:
3+
# Runs after "Create Release Tag" completes (that workflow creates the git tag
4+
# and GitHub Release once a release PR merges). It then runs the `release-notes`
5+
# Claude skill to produce polished, copy-pasteable release notes:
66
# - analyzes every merged PR between the previous tag and this one
77
# - cross-references linked issues
88
# - dispatches expert subagents to assess breaking changes
99
#
10+
# Why workflow_run and not the `release` event: anthropics/claude-code-action
11+
# only accepts a fixed set of event types (issues, pull_request*, comments,
12+
# workflow_dispatch, repository_dispatch, schedule, workflow_run). A `release`
13+
# trigger makes the action fail immediately with "Unsupported event type:
14+
# release". workflow_run is supported and is not subject to the GITHUB_TOKEN
15+
# downstream-trigger limitation, so it fires reliably after the tag workflow.
16+
#
1017
# Delivery is REVIEW-THEN-PUBLISH: the public release notes are NOT overwritten.
1118
# The generated markdown is uploaded as a build artifact, written to the job
1219
# summary, and posted as a comment on the release PR for a maintainer to review
@@ -17,8 +24,9 @@
1724
name: Generate Release Notes
1825

1926
on:
20-
release:
21-
types: [published]
27+
workflow_run:
28+
workflows: ["Create Release Tag"]
29+
types: [completed]
2230
workflow_dispatch:
2331
inputs:
2432
tag:
@@ -36,32 +44,51 @@ jobs:
3644
name: Generate Release Notes
3745
runs-on: ubuntu-latest
3846
timeout-minutes: 30
47+
# On workflow_run, only proceed if the tag workflow actually succeeded.
48+
# Manual dispatch always proceeds.
49+
if: >-
50+
github.event_name == 'workflow_dispatch' ||
51+
github.event.workflow_run.conclusion == 'success'
3952
env:
4053
# Mapped to a job-level env var so the Slack step can gate on it: the
4154
# `secrets` context is not available in step-level `if:` conditions.
4255
SLACK_WEBHOOK: ${{ secrets.SLACK_TOOLHIVE_RELEASE_WEBHOOK_URL }}
4356
steps:
57+
- name: Checkout repository
58+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
59+
with:
60+
# Always check out the default branch, never the workflow_run head ref.
61+
# Checking out an event-supplied ref in a secrets-bearing workflow_run
62+
# is the "untrusted checkout" anti-pattern (CodeQL actions/untrusted-
63+
# checkout). It is safe here too: "Create Release Tag" only runs on a
64+
# VERSION push to main, so main HEAD already is the release commit and
65+
# its VERSION matches the tag being announced.
66+
#
67+
# Full history + tags are required: the skill lists/sorts tags and
68+
# compares ranges between the current and previous release.
69+
fetch-depth: 0
70+
4471
- name: Resolve release tag
4572
id: tag
4673
env:
47-
EVENT_TAG: ${{ github.event.release.tag_name }}
4874
INPUT_TAG: ${{ inputs.tag }}
4975
run: |
50-
TAG="${EVENT_TAG:-$INPUT_TAG}"
51-
if [ -z "$TAG" ]; then
52-
echo "::error::No release tag resolved from event or input"
76+
# Manual runs pass the tag explicitly; workflow_run derives it from the
77+
# VERSION file on the default branch (the release commit that triggered
78+
# the tag workflow), prefixed with "v".
79+
if [ -n "$INPUT_TAG" ]; then
80+
TAG="$INPUT_TAG"
81+
else
82+
VERSION=$(tr -d '[:space:]' < VERSION)
83+
TAG="v$VERSION"
84+
fi
85+
if [ -z "$TAG" ] || [ "$TAG" = "v" ]; then
86+
echo "::error::No release tag resolved from input or VERSION file"
5387
exit 1
5488
fi
5589
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
5690
echo "Generating release notes for: $TAG"
5791
58-
- name: Checkout repository
59-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
60-
with:
61-
# Full history + tags are required: the skill lists/sorts tags and
62-
# compares ranges between the current and previous release.
63-
fetch-depth: 0
64-
6592
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
6693
with:
6794
go-version: 'stable'
@@ -79,6 +106,11 @@ jobs:
79106
GH_TOKEN: ${{ github.token }}
80107
with:
81108
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
109+
# Hand the action a token explicitly so it does not try to mint one via
110+
# OIDC (the Claude GitHub App flow), which would require `id-token: write`
111+
# and the app installed. We only need the API key for Anthropic auth and
112+
# GH_TOKEN for the skill's read-only gh calls.
113+
github_token: ${{ github.token }}
82114
prompt: |
83115
You are generating GitHub release notes for the ToolHive release ${{ steps.tag.outputs.tag }}.
84116

0 commit comments

Comments
 (0)