mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 19:18:25 +00:00
Create the GitHub Release object automatically on a tag push
Nothing in the repository published the Release object. All five packaging workflows run a "Wait for tag release" step that polls `gh release view` twenty times at fifteen-second intervals and then fails the job, so a tag push failed every packaging leg unless someone ran `gh release create` by hand inside that five-minute budget. The previous creator lived in package-openwrt.yml and generated the release body from the commit list, which raced the hand-created object and could strand the written release notes. It was removed for v0.4.2 and nothing replaced it. This adds a dedicated workflow instead, so there is one creator, it runs as early as a tag push allows, and it publishes `docs/releases/release-notes-<tag>.md` rather than a generated commit list. It is idempotent in both directions: an existing Release is left untouched, and a Release created concurrently between the check and the create is treated as success. A pre-release tag is marked as such and gets the RC placeholder body, since the written notes are finalized only for the stable tag. (cherry picked from commit 3429fd6064a8b8ea1f87023cfccabd499696a37f)
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
name: Release Object
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: "Tag to create the Release object for"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
# Every packaging workflow's upload job runs a `Wait for tag release` step that
|
||||||
|
# polls `gh release view` 20 times at 15s intervals and then fails the job. Five
|
||||||
|
# waiters and no creator means a tag push fails all five unless a human runs
|
||||||
|
# `gh release create` inside that five-minute budget. This job is the creator.
|
||||||
|
#
|
||||||
|
# It deliberately does not live in a packaging workflow. The previous creator did
|
||||||
|
# (package-openwrt.yml, via an action with generate_release_notes), and it raced
|
||||||
|
# the operator's hand-created object for the right to decide the Release body;
|
||||||
|
# whichever lost left the written notes stranded. Here there is one creator, it
|
||||||
|
# publishes the notes file the release wrote, and it is idempotent, so running it
|
||||||
|
# alongside a hand-created object is a no-op rather than a race.
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: release-object-${{ github.ref }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
name: Create the Release object
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.tag || github.ref }}
|
||||||
|
|
||||||
|
- name: Create the Release object if it does not exist
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
TAG: ${{ inputs.tag || github.ref_name }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
|
||||||
|
echo "Release ${TAG} already exists; leaving it untouched."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
args=(--repo "${GITHUB_REPOSITORY}" --title "FIPS ${TAG}")
|
||||||
|
|
||||||
|
# A tag carrying a pre-release suffix (v0.5.0-rc1) is an RC: it is
|
||||||
|
# marked as a pre-release and has no written notes of its own, since
|
||||||
|
# the notes are finalized for the stable tag.
|
||||||
|
notes="docs/releases/release-notes-${TAG}.md"
|
||||||
|
if [[ "${TAG}" == *-* ]]; then
|
||||||
|
args+=(--prerelease --notes "Release candidate - packaging validation only.")
|
||||||
|
elif [[ -f "${notes}" ]]; then
|
||||||
|
args+=(--notes-file "${notes}")
|
||||||
|
else
|
||||||
|
# Never --generate-notes: an auto-generated commit list published
|
||||||
|
# under a stable tag is exactly what stranded the written notes
|
||||||
|
# before. An empty body is visibly wrong and trivially editable.
|
||||||
|
echo "::warning::${notes} is missing; publishing ${TAG} with an empty body."
|
||||||
|
args+=(--notes "")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! gh release create "${TAG}" "${args[@]}"; then
|
||||||
|
# A concurrent creator - the operator by hand, or a re-run - may have
|
||||||
|
# won between the check above and here. An object that now exists is
|
||||||
|
# the outcome this job wanted.
|
||||||
|
gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1
|
||||||
|
echo "Release ${TAG} was created concurrently; nothing to do."
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user