ci(release): publish with curl instead of a go action, and lift MessagePack
The v2.0.0 tag built fine and then died on its last step: gitea.com's release-action declares `using: go`, the runner has to compile it, and act cannot -- exec: "go": executable file not found, exit 127, after a green build. The zip existed and never got attached, so the Discord announcement went out while the download link pointed at nothing. This is a known failure. It was diagnosed on another repo in June and the note from then says in as many words that this repo carries the same pattern and should migrate before its next release. It did not, and here we are. The publish step is a plain curl call against the Gitea API now, running in the job image with curl and python3, independent of go, the action cache, and whatever @main happens to point at. Idempotent by design: a re-run reuses an existing release and replaces the asset rather than failing on the duplicate, which is exactly the state a recovery run finds. MessagePack moves from the 3.1.4 floor to 3.1.7, which is what the trivy scan was failing on. The range already allowed it -- NuGet resolves the lower bound of a range, and trivy reads it the same way, so the floor is the version that counts. The advisories are recursion depth in Skip and an LZ4 decompression fault, both reachable only through crafted input; this plugin serialises its own payloads and reads back its own bytes from a local database, so the practical exposure is someone who already has write access to the file. Lifted because it costs nothing and a scan that stays red for a known-harmless reason is how a real finding gets missed later.
This commit is contained in:
@@ -22,9 +22,9 @@ on:
|
||||
- 'v*'
|
||||
# Manual recovery trigger. Use Gitea's "Run workflow" UI and select the
|
||||
# tag (e.g. v1.4.4) from the Ref dropdown - not main. The Validate tag
|
||||
# ref step below hard-fails if a non-tag ref is selected, because the
|
||||
# release-action reads GITHUB_REF directly and rejects anything that
|
||||
# does not start with refs/tags/.
|
||||
# ref step below hard-fails if a non-tag ref is selected: the release
|
||||
# name and body are both derived from the tag, so a branch ref would
|
||||
# publish a release named after a branch.
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -37,11 +37,8 @@ jobs:
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
# release-action@main reads GITHUB_REF directly (its action.yml
|
||||
# does not declare a tag_name input). Validate up-front so manual
|
||||
# dispatches from a branch ref fail loud here instead of burning
|
||||
# a full build before the final step errors out with "ref X is
|
||||
# not a tag".
|
||||
# Validate up-front so a manual dispatch from a branch ref fails loud
|
||||
# here instead of burning a full build before the publish step notices.
|
||||
- name: Validate tag ref
|
||||
run: |
|
||||
if [[ "${GITHUB_REF}" != refs/tags/v* ]]; then
|
||||
@@ -156,28 +153,55 @@ jobs:
|
||||
Write-Host $body
|
||||
Write-Host "----------------------------------------"
|
||||
|
||||
# release-action@main only declares files/title/body/pre_release/
|
||||
# draft/api_key/insecure as inputs (see its action.yml). It silently
|
||||
# ignores anything else, including body_path and tag_name. The tag
|
||||
# itself comes from GITHUB_REF, the body must be passed inline via
|
||||
# body:, so we re-emit release-body.md as a step output first.
|
||||
- name: Expose release body for release-action
|
||||
id: body
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
echo 'content<<RELEASE_BODY_EOF'
|
||||
cat release-body.md
|
||||
echo 'RELEASE_BODY_EOF'
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Gitea-native release action. Creates the release if the tag has no
|
||||
# release yet, or updates the existing one with latest.zip attached
|
||||
# and the generated body. The auto-injected GITHUB_TOKEN on Gitea
|
||||
# Actions has Gitea-API scope and is sufficient for release write.
|
||||
# The tag comes from GITHUB_REF, the body from the step above. Posted with
|
||||
# curl rather than gitea.com/actions/release-action, which declares
|
||||
# `using: go` and has to be compiled by the runner -- act cannot do that
|
||||
# here and the step dies with exec: "go": executable file not found, exit
|
||||
# 127, after a build that otherwise succeeded. This runs as a plain shell
|
||||
# step in the job image, which has curl and python3.
|
||||
#
|
||||
# Idempotent on purpose: a re-run against an existing release reuses it and
|
||||
# replaces the asset instead of failing on the duplicate.
|
||||
- name: Attach to Gitea release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: ${{ steps.locate.outputs.path }}
|
||||
body: ${{ steps.body.outputs.content }}
|
||||
api_key: ${{ secrets.GITHUB_TOKEN }}
|
||||
shell: bash
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ZIP_PATH: ${{ steps.locate.outputs.path }}
|
||||
TAG_NAME: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}"
|
||||
auth="Authorization: token ${GITEA_TOKEN}"
|
||||
|
||||
# Existing release for this tag, or create one.
|
||||
rel_id="$(curl -sf -H "$auth" "$api/releases/tags/${TAG_NAME}" \
|
||||
| python3 -c 'import sys,json; print(json.load(sys.stdin).get("id",""))' 2>/dev/null || true)"
|
||||
|
||||
if [ -z "$rel_id" ]; then
|
||||
payload="$(python3 -c '
|
||||
import json, os, sys
|
||||
body = open("release-body.md", encoding="utf-8").read()
|
||||
json.dump({"tag_name": os.environ["TAG_NAME"], "name": os.environ["TAG_NAME"],
|
||||
"body": body, "draft": False, "prerelease": False}, sys.stdout)
|
||||
')"
|
||||
rel_id="$(printf '%s' "$payload" \
|
||||
| curl -sf -X POST -H "$auth" -H "Content-Type: application/json" -d @- "$api/releases" \
|
||||
| python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')"
|
||||
echo "Created release $rel_id for ${TAG_NAME}"
|
||||
else
|
||||
echo "Reusing release $rel_id for ${TAG_NAME}"
|
||||
fi
|
||||
|
||||
# Drop a same-named asset from an earlier attempt, or the upload 409s.
|
||||
old_id="$(curl -sf -H "$auth" "$api/releases/${rel_id}/assets" \
|
||||
| python3 -c 'import sys,json; print(next((a["id"] for a in json.load(sys.stdin) if a["name"]=="latest.zip"), ""))' 2>/dev/null || true)"
|
||||
if [ -n "$old_id" ]; then
|
||||
curl -sf -X DELETE -H "$auth" "$api/releases/${rel_id}/assets/${old_id}"
|
||||
echo "Replaced existing latest.zip (asset $old_id)"
|
||||
fi
|
||||
|
||||
curl -sf -X POST -H "$auth" \
|
||||
-F "attachment=@${ZIP_PATH};filename=latest.zip" \
|
||||
"$api/releases/${rel_id}/assets?name=latest.zip" \
|
||||
| python3 -c 'import sys,json; a=json.load(sys.stdin); print("Attached", a["name"], a["size"], "bytes")'
|
||||
|
||||
Reference in New Issue
Block a user