Compare commits

...

2 Commits

Author SHA1 Message Date
Shaun Arman
6d8263c5b5 fix(ci): consolidate all auto-tag changelog fixes
All checks were successful
Test / rust-fmt-check (pull_request) Successful in 1m50s
Test / rust-clippy (pull_request) Successful in 3m8s
Test / frontend-typecheck (pull_request) Successful in 1m44s
Test / frontend-tests (pull_request) Successful in 1m27s
PR Review Automation / review (pull_request) Successful in 5m32s
Test / rust-tests (pull_request) Successful in 4m47s
Three issues addressed together:

1. Race condition (was PR #56): changelog job now CREATES the Gitea
   release rather than assuming build jobs have already created it.
   Build jobs continue to use create-or-skip + upload unchanged.

2. Detached HEAD push: 'git push origin master' fails when HEAD is
   detached (no local branch named master). Changed to 'HEAD:master'.

3. git-cliff tag guard: verify tag is present locally before running
   git-cliff, to fail fast with a clear message rather than silently
   generating a wrong changelog.

4. git commit idiom: replaced 'git commit || echo' (swallows all
   non-zero exit codes including real failures) with an explicit
   'git diff --staged --quiet' guard so set -euo pipefail is not
   undermined.
2026-05-31 16:26:31 -05:00
Shaun Arman
6dbc40ec96 fix(ci): push detached HEAD to master using HEAD:master refspec
Some checks failed
Test / rust-fmt-check (pull_request) Successful in 2m59s
PR Review Automation / review (pull_request) Successful in 6m38s
Test / frontend-typecheck (pull_request) Successful in 1m19s
Test / rust-clippy (pull_request) Successful in 6m18s
Test / frontend-tests (pull_request) Successful in 1m8s
Test / rust-tests (pull_request) Has been cancelled
The changelog job checks out a specific SHA (detached HEAD) then
commits CHANGELOG.md and tries to push with 'git push origin master'.
Since there is no local branch named 'master', git rejects the push
with 'src refspec master does not match any'.

Fix: use 'git push origin HEAD:master' which explicitly maps the
current detached HEAD to the remote master branch regardless of
local branch state.
2026-05-31 16:16:44 -05:00

View File

@ -125,22 +125,28 @@ jobs:
RELEASE_TAG: ${{ needs.autotag.outputs.release_tag }}
run: |
set -eu
# Use the tag output from autotag — never rely on git describe
CURRENT_TAG="${RELEASE_TAG}"
echo "Building changelog for $CURRENT_TAG"
# Verify the tag is present locally after fetch
if ! git rev-parse "refs/tags/${CURRENT_TAG}" >/dev/null 2>&1; then
echo "ERROR: tag ${CURRENT_TAG} not found locally after fetch"
exit 1
fi
git-cliff --config cliff.toml --output CHANGELOG.md
PREV_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| grep -v "^${CURRENT_TAG}$" | head -1 || echo "")
if [ -n "$PREV_TAG" ]; then
git-cliff --config cliff.toml --tag "$CURRENT_TAG" --strip all > /tmp/release_body.md || true
else
echo "=== No previous tag found, generating from git commits ==="
echo "No previous tag found, generating from git commits"
git log --pretty=format:"- %s" > /tmp/release_body.md || true
fi
echo "=== Release body preview ==="
cat /tmp/release_body.md
- name: Update Gitea release body
- name: Create or update Gitea release
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
RELEASE_TAG: ${{ needs.autotag.outputs.release_tag }}
@ -148,18 +154,41 @@ jobs:
set -eu
TAG="${RELEASE_TAG}"
API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY"
RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \
-H "Authorization: token $RELEASE_TOKEN" | jq -r '.id')
# Try to find an existing release for this tag
RELEASE_ID=$(curl -s "$API/releases/tags/$TAG" \
-H "Authorization: token $RELEASE_TOKEN" | jq -r '.id // empty')
if [ -z "$RELEASE_ID" ]; then
# First run: changelog job owns release creation so build jobs
# never race against a missing release object
echo "Creating release $TAG..."
RELEASE_ID=$(jq -n \
--arg tag "$TAG" \
--arg name "TFTSR $TAG" \
--rawfile body /tmp/release_body.md \
'{tag_name: $tag, name: $name, body: $body, draft: false}' \
| curl -sf -X POST "$API/releases" \
-H "Authorization: token $RELEASE_TOKEN" \
-H "Content-Type: application/json" \
--data @- \
| jq -r '.id')
echo "✓ Release created (id=$RELEASE_ID)"
else
# Re-run: patch the body only
echo "Updating existing release $TAG (id=$RELEASE_ID)..."
jq -n --rawfile body /tmp/release_body.md '{body: $body}' \
| curl -sf -X PATCH "$API/releases/$RELEASE_ID" \
-H "Authorization: token $RELEASE_TOKEN" \
-H "Content-Type: application/json" \
--data @-
echo "✓ Release body updated"
fi
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
echo "ERROR: Could not find release for tag $TAG"
echo "ERROR: Failed to create or locate release for $TAG"
exit 1
fi
BODY=$(jq -n --rawfile note /tmp/release_body.md '{body: $note}')
curl -sf -X PATCH "$API/releases/$RELEASE_ID" \
-H "Authorization: token $RELEASE_TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY"
echo "✓ Release body updated"
- name: Commit CHANGELOG.md to master
env:
@ -167,14 +196,21 @@ jobs:
run: |
set -euo pipefail
TAG="${RELEASE_TAG}"
# Validate tag format to prevent shell injection in commit message / JSON
if ! echo "$TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: Unexpected tag format: $TAG"
exit 1
fi
git add CHANGELOG.md
git commit -m "chore: update CHANGELOG.md for ${TAG} [skip ci]" || echo "No changes to commit"
git push origin master
# Only commit if CHANGELOG.md actually changed — avoids ambiguous
# exit-code handling from 'git commit || echo' with set -e
if git diff --staged --quiet; then
echo "No CHANGELOG.md changes to commit"
else
git commit -m "chore: update CHANGELOG.md for ${TAG} [skip ci]"
fi
# HEAD:master works in detached HEAD state; 'git push origin master'
# would fail because there is no local branch named master
git push origin HEAD:master
echo "✓ CHANGELOG.md committed to master"
- name: Upload CHANGELOG.md as release asset