Skip to content

Commit 8b157a5

Browse files
committed
ci: compact release-workflow comments
Trim explanatory comments to one or two lines each and drop the operator-side semver regex from release.sh — release.yaml validates it.
1 parent fdb6135 commit 8b157a5

2 files changed

Lines changed: 32 additions & 67 deletions

File tree

.github/workflows/release.yaml

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
name: Release
2-
# Cuts a FrankenPHP release end-to-end: refreshes the PGO profile, bumps the
3-
# Caddy module's frankenphp dependency, commits the result as
4-
# github-actions[bot], tags v<version> and caddy/v<version>, drafts a GitHub
5-
# release, dispatches the downstream binary builds, and opens a Homebrew
6-
# formula bump PR. Dispatched by release.sh.
7-
#
8-
# The workflow is idempotent: re-dispatching after a partial failure (flaky
9-
# test, network blip, registry hiccup) detects which steps already completed
10-
# and skips them, so the release can be resumed without manual cleanup.
2+
# Refreshes PGO, bumps caddy/go.mod, commits as github-actions[bot],
3+
# tags v<version> and caddy/v<version>, drafts the GitHub release,
4+
# dispatches the binary build workflows, and bumps the Homebrew formula.
5+
# Idempotent: a re-dispatch after a partial failure resumes by tag.
116
on:
127
workflow_dispatch:
138
inputs:
@@ -18,8 +13,7 @@ on:
1813
type: string
1914
permissions:
2015
contents: write
21-
# Needed to dispatch the downstream binary build workflows from this run.
22-
actions: write
16+
actions: write # to dispatch downstream binary build workflows
2317
concurrency:
2418
group: ${{ github.workflow }}
2519
cancel-in-progress: false
@@ -35,13 +29,10 @@ jobs:
3529
BENCH_SEC: "30"
3630
steps:
3731
- name: Validate inputs
38-
# UI-triggered dispatches bypass release.sh's preflight regex, so
39-
# re-validate the version string here. Any payload that would not
40-
# produce a clean semver tag is rejected before it propagates into
41-
# go get / sed / tag refs and breaks the release in mid-flight.
32+
# Reject non-main refs and non-semver versions before they reach
33+
# go get / sed / tag refs. https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
4234
env:
4335
VERSION: ${{ inputs.version }}
44-
# Adapted from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
4536
run: |
4637
if [[ "${GITHUB_REF}" != "refs/heads/main" ]]; then
4738
echo "::error::release.yaml must be dispatched against refs/heads/main, got ${GITHUB_REF}"
@@ -59,8 +50,7 @@ jobs:
5950
id: classify
6051
env:
6152
VERSION: ${{ inputs.version }}
62-
# Pre-release versions (those carrying a "-" suffix per SemVer) must
63-
# not be marked --latest nor bump the stable Homebrew formula.
53+
# Pre-releases (SemVer "-" suffix) must not bump --latest or Homebrew.
6454
run: |
6555
if [[ "${VERSION}" == *-* ]]; then
6656
echo "prerelease=true" >> "${GITHUB_OUTPUT}"
@@ -72,17 +62,12 @@ jobs:
7262
env:
7363
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7464
VERSION: ${{ inputs.version }}
75-
# Tag existence is the source of truth for "release in progress":
76-
# main HEAD may have moved past the release commit (a follow-up fix
77-
# merged on top), so the commit-message check on HEAD is too narrow.
78-
# If v<version> exists, resume from the commit it points at;
79-
# otherwise it's a fresh attempt and tags must not exist.
65+
# Tag existence is the resume signal — main HEAD may have moved
66+
# past the release commit, so a HEAD message check is too narrow.
8067
run: |
8168
set -euo pipefail
82-
# matching-refs returns an empty array (still HTTP 200) when the ref
83-
# is absent — no need to parse error wording to distinguish 404
84-
# from rate-limit/5xx/auth failures, which `gh` still surfaces as a
85-
# non-zero exit through `set -e`.
69+
# matching-refs returns [] (HTTP 200) for absent tags; real
70+
# failures still trip set -e.
8671
lookup_tag() {
8772
gh api "repos/${GITHUB_REPOSITORY}/git/matching-refs/tags/$1" \
8873
--jq ".[] | select(.ref == \"refs/tags/$1\") | {sha: .object.sha, type: .object.type}"
@@ -102,16 +87,12 @@ jobs:
10287
caddy_entry=$(lookup_tag "caddy/v${VERSION}")
10388
if [[ -n "${main_entry}" ]]; then
10489
sha=$(resolve_commit "${main_entry}")
105-
# Refuse to resume against a tag that isn't reachable from main:
106-
# protects against an orphan tag created on a side branch.
90+
# Reject orphan tags created on a side branch.
10791
if ! git merge-base --is-ancestor "${sha}" HEAD; then
10892
echo "::error::Tag v${VERSION} (${sha}) is not reachable from main; refusing to resume."
10993
exit 1
11094
fi
111-
# Symmetric split-state guard: the create_tag step further down
112-
# also fails if caddy/v${VERSION} points to a different commit,
113-
# but flagging the inconsistency here surfaces it before any
114-
# writes happen.
95+
# Catch a mismatched caddy/v${VERSION} before any writes.
11596
if [[ -n "${caddy_entry}" ]]; then
11697
caddy_sha=$(resolve_commit "${caddy_entry}")
11798
if [[ "${caddy_sha}" != "${sha}" ]]; then
@@ -149,8 +130,7 @@ jobs:
149130
run: ./profiles/build-pgo.sh
150131
- if: steps.state.outputs.resume != 'true'
151132
name: Sanity-check PGO profile
152-
# Catch the degenerate case where wrk silently failed to drive load
153-
# and we ended up shipping a near-empty profile.
133+
# Guard against wrk silently failing and producing a near-empty profile.
154134
run: |
155135
size=$(wc -c <caddy/frankenphp/default.pgo)
156136
echo "PGO profile: ${size} bytes"
@@ -167,8 +147,8 @@ jobs:
167147
go get "github.com/dunglas/frankenphp@v${VERSION}"
168148
go mod tidy
169149
- name: Commit and tag via GitHub API
170-
# API-created commits/tags are signed server-side with GitHub's key
171-
# and show as "Verified" under the github-actions[bot] identity.
150+
# API-created commits/tags are signed server-side and show as
151+
# Verified under github-actions[bot].
172152
env:
173153
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
174154
REPO: ${{ github.repository }}
@@ -182,10 +162,8 @@ jobs:
182162
commit_sha="${RELEASE_COMMIT}"
183163
echo "Reusing existing release commit ${commit_sha}"
184164
else
185-
# Stage the base64 in a temp file and feed it to jq via
186-
# --rawfile: passing big blobs (the PGO profile is ~2 MB encoded)
187-
# through --arg exceeds ARG_MAX on the runner. Subshell body +
188-
# EXIT trap clean up the tmpfile even if base64/jq/gh aborts.
165+
# Use --rawfile: the PGO blob (~2 MB encoded) exceeds ARG_MAX
166+
# via --arg.
189167
make_blob() (
190168
local tmp
191169
tmp=$(mktemp)
@@ -199,10 +177,8 @@ jobs:
199177
parent_sha=$(gh api "repos/${REPO}/git/refs/heads/main" -q .object.sha)
200178
base_tree=$(gh api "repos/${REPO}/git/commits/${parent_sha}" -q .tree.sha)
201179
202-
# Collect every tracked file modified by the PGO/bump steps so
203-
# that, e.g., a transitive update to a go.sum entry doesn't get
204-
# silently dropped from the release commit. Matches the
205-
# `git commit -a` behavior the script used to rely on.
180+
# Capture every touched file so transitive go.sum or PGO
181+
# side effects aren't dropped from the release commit.
206182
mapfile -t changed < <(git diff --name-only HEAD)
207183
if [[ ${#changed[@]} -eq 0 ]]; then
208184
echo "::error::No file changes detected after PGO/bump steps."
@@ -224,7 +200,7 @@ jobs:
224200
'{base_tree: $base_tree, tree: $entries}' \
225201
| gh api "repos/${REPO}/git/trees" --input - -q .sha)
226202
227-
# [skip ci] keeps push-triggered workflows from firing on top of
203+
# [skip ci] avoids push-triggered workflows firing alongside
228204
# the explicit downstream dispatches below.
229205
commit_sha=$(jq -nc \
230206
--arg message "chore: prepare release ${VERSION} [skip ci]" \
@@ -236,8 +212,8 @@ jobs:
236212
gh api "repos/${REPO}/git/refs/heads/main" -X PATCH -f sha="$commit_sha" --silent
237213
fi
238214
239-
# Idempotent tag creation: if the tag already exists and points at
240-
# the release commit, leave it alone; if it points elsewhere, fail.
215+
# Idempotent: skip if tag already points at the release commit,
216+
# fail if it points elsewhere.
241217
create_tag() {
242218
local tag="$1"
243219
local existing
@@ -268,15 +244,12 @@ jobs:
268244
create_tag "v${VERSION}"
269245
create_tag "caddy/v${VERSION}"
270246
271-
# Pull the new commit + tags so the release-draft step's git
272-
# describe can resolve v${VERSION}^.
247+
# So the release-draft step's `git describe v${VERSION}^` resolves.
273248
git fetch origin main --tags
274249
- name: Draft GitHub release
275-
# `gh release create` validates the tag through GraphQL, which can
276-
# lag minutes behind the Git Data API we just used to create the
277-
# tag — leading to "no matches found" or `untagged-*` placeholder
278-
# releases. Use the REST releases endpoints directly: they see the
279-
# tag immediately and behave deterministically.
250+
# `gh release create` goes through GraphQL which can lag minutes
251+
# behind the Git Data API and yield "no matches" or `untagged-*`
252+
# placeholder releases; the REST releases endpoint is consistent.
280253
env:
281254
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
282255
REPO: ${{ github.repository }}
@@ -302,11 +275,9 @@ jobs:
302275
fi
303276
gh api "repos/${REPO}/releases" "${create_args[@]}" --silent
304277
- name: Trigger downstream release builds
305-
# GITHUB_TOKEN-driven API writes don't trigger workflows that listen
306-
# on tag/push events, so dispatch each downstream explicitly. Keep
307-
# going on partial failure so the operator only needs to re-run the
308-
# specific dispatches that didn't go through. Re-dispatch on resume
309-
# is harmless: it just queues another build run.
278+
# GITHUB_TOKEN tag writes don't fire push triggers, so dispatch
279+
# each downstream explicitly. Keep going on partial failure;
280+
# re-dispatch on resume just queues another idempotent build.
310281
env:
311282
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
312283
REPO: ${{ github.repository }}

release.sh

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@ if [[ $# -ne 1 ]]; then
1919
exit 1
2020
fi
2121

22-
# Adapted from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
23-
if [[ ! $1 =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]]; then
24-
echo "Invalid version number: $1" >&2
25-
exit 1
26-
fi
27-
28-
# Cheap operator-side guards so the workflow dispatch matches local intent.
22+
# Cheap operator-side guards; release.yaml re-validates the version.
2923
if [[ "$(git branch --show-current 2>/dev/null)" != "main" ]]; then
3024
echo "You must be on the main branch to dispatch a release." >&2
3125
exit 1

0 commit comments

Comments
 (0)