Create a release on every merge to main #478
No reviewers
Labels
No labels
Kestra
bug
enhancement
someday
subtask
☁️ api
🎛️ infrastructure
🐞 sentry
📆 2025 Season
📝 pages
allpicks
📝 pages
picks
📝 pages
standings
🚀 performance
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
johnsturgeon/tgfp-web!478
Loading…
Reference in a new issue
No description provided.
Delete branch "create-a-new-release-every-time-a-pr-lands-477"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds a Forgejo workflow that cuts a release + tag whenever a PR merges to
main.pull_request: closedwhenmerged == truepyproject.tomlat the merge commit (via the/raw/API, no checkout)resolves/closes/fixeskeywords)Note: this PR itself will not produce a release — the closed-PR event runs the workflow as it exists on
main, which does not have the file until after this lands. The first real release will be the next PR merged after this.resolves #477
🤖 Generated with Claude Code
I have enough context. The version-parsing approach matches the existing
build-image.ymlconvention, and theFJ_API_URL/FJ_TOKENenv pattern is consistent withclaude.ymlandclaude-code-review.yml. Here is my review.This adds a well-constructed workflow that publishes a Forgejo release + tag on each merge to
main, with untrusted PR text handled safely (env vars +jq --arg, never interpolated into the shell) and a sensible no-op path for un-bumped versions. The version-parsing,FJ_API_URL/FJ_TOKEN, andself-hostedconventions all match the existing workflows, and the version bump (2.29.0 → 2.30.0, withuv.lock) follows CLAUDE.md. No blocking issues.Worth fixing
release-on-merge.yml:87.GET /pulls/{n}/commitspaginates (Forgejo default ~30 per page), so a PR with more than a page of commits will only have its early commits scanned for closing keywords. In practice the PR body is the primary source and usually carries theresolves #n, so this rarely bites — but when it does it fails silently (fewer issues listed, no warning). If you want it robust, either add?limit=50(or paginate) or lean on the body only. Minor, since the body scan is the real workhorse.Nits
The graceful "could not parse version" branch is effectively unreachable —
release-on-merge.yml:65-70. Underset -euo pipefail, if theraw/pyproject.tomlfetch 404s (badref) or the file has noversion =line, eithercurl -sSforgrep -m1exits non-zero, the command substitution's pipeline fails, andset -eaborts before theif [[ -z "$version" ]]check runs. The script still fails loudly, so this is cosmetic — the custom::error::message just never prints. (Same latent pattern exists inbuild-image.yml:56-60, but theregrepreads a local file so it's even less likely to trip.)Duplicate detection only covers releases, not bare tags —
release-on-merge.yml:76-82.GET /releases/tags/$versionreturns 404 if a git tag named$versionexists without an associated release (e.g. one created manually or by a prior partial run). The subsequentPOST /releaseswould then fail on the tag conflict rather than hitting the clean "already exists" no-op. Edge case; the normal path wherebuild-image/this workflow own the tags is fine.Nice touches worth calling out:
curl -sS(no-f) for the existence check so a 404 doesn't tripset -e, the globalconcurrencygroup to serialize back-to-back merges carrying the same version, and the header comment explaining why this PR won't release itself.