diff --git a/.gitea/workflows/iso-builder.yml b/.gitea/workflows/iso-builder.yml index adb6002..1a178ed 100644 --- a/.gitea/workflows/iso-builder.yml +++ b/.gitea/workflows/iso-builder.yml @@ -112,9 +112,29 @@ jobs: exit 1 fi - API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" + # Strip any trailing slash from GITHUB_SERVER_URL so we don't end up + # with a double-slash in the API path. + SERVER_URL="${GITHUB_SERVER_URL%/}" + API="${SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" + # Gitea accepts both `token ` and `Bearer `; the + # auto-injected GITHUB_TOKEN works with the `token` scheme. AUTH="Authorization: token ${GITEA_TOKEN}" + echo "API base: $API" + echo "Repo: $GITHUB_REPOSITORY" + + # Sanity-check auth + reachability with a single authenticated GET. + # Print status + first chunk of body so failures are visible. + http_code=$(curl -sS -o /tmp/api-check.body -w '%{http_code}' \ + -H "$AUTH" "$API" || true) + echo "GET $API -> HTTP $http_code" + if [ "$http_code" != "200" ]; then + echo "::error::Auth/reachability check failed (HTTP $http_code). Response body:" + head -c 2000 /tmp/api-check.body || true + echo + exit 1 + fi + # Pick a release tag. Use the pushed tag for tag-triggered runs; # otherwise generate a unique CI tag so re-runs don't collide. if [ "${GITHUB_REF:-}" = "refs/tags/${GITHUB_REF_NAME:-}" ] && [ -n "${GITHUB_REF_NAME:-}" ]; then @@ -127,33 +147,74 @@ jobs: fi echo "Release tag: $TAG (prerelease=$PRERELEASE)" - # Create the release. If it already exists (re-run), fall back to lookup. - RELEASE_ID=$(curl -fsS -X POST "$API/releases" \ - -H "$AUTH" -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"$TAG\",\"name\":\"${{ matrix.host }} ISO $TAG\",\"body\":\"Automated ISO build for ${{ matrix.host }}.\\n\\nCommit: ${GITHUB_SHA}\\nRun: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",\"prerelease\":$PRERELEASE}" \ - | jq -r '.id') || RELEASE_ID="" + # Helper: parse the id field from a JSON body, returning "" on any error. + extract_id() { + jq -r '.id // empty' 2>/dev/null || true + } - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then - RELEASE_ID=$(curl -fsS "$API/releases/tags/$TAG" -H "$AUTH" | jq -r '.id') + # Create the release. Capture status + body separately so we can + # diagnose non-JSON responses instead of feeding them to jq blindly. + http_code=$(curl -sS -o /tmp/release-create.body -w '%{http_code}' \ + -X POST "$API/releases" \ + -H "$AUTH" -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"$TAG\",\"name\":\"${{ matrix.host }} ISO $TAG\",\"body\":\"Automated ISO build for ${{ matrix.host }}.\\n\\nCommit: ${GITHUB_SHA}\\nRun: ${SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",\"prerelease\":$PRERELEASE}" \ + || true) + echo "POST $API/releases -> HTTP $http_code" + RELEASE_ID="" + if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then + RELEASE_ID=$(extract_id < /tmp/release-create.body) + else + # Common case: tag already exists from a prior run. Show the body + # for any other error so it's debuggable. + echo "Create response body (first 2000 bytes):" + head -c 2000 /tmp/release-create.body || true + echo fi - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then + + # Fall back to looking up an existing release by tag. + if [ -z "$RELEASE_ID" ]; then + http_code=$(curl -sS -o /tmp/release-lookup.body -w '%{http_code}' \ + -H "$AUTH" "$API/releases/tags/$TAG" || true) + echo "GET $API/releases/tags/$TAG -> HTTP $http_code" + if [ "$http_code" = "200" ]; then + RELEASE_ID=$(extract_id < /tmp/release-lookup.body) + else + echo "Lookup response body (first 2000 bytes):" + head -c 2000 /tmp/release-lookup.body || true + echo + fi + fi + + if [ -z "$RELEASE_ID" ]; then echo "::error::Could not create or find release for tag $TAG" exit 1 fi echo "Release ID: $RELEASE_ID" # Remove any existing asset with the same name so re-runs succeed. - curl -fsS "$API/releases/$RELEASE_ID/assets" -H "$AUTH" \ - | jq -r ".[] | select(.name == \"$ISO\") | .id" \ - | while read -r aid; do - curl -fsS -X DELETE "$API/releases/$RELEASE_ID/assets/$aid" -H "$AUTH" || true - done + http_code=$(curl -sS -o /tmp/assets.body -w '%{http_code}' \ + -H "$AUTH" "$API/releases/$RELEASE_ID/assets" || true) + if [ "$http_code" = "200" ]; then + jq -r ".[] | select(.name == \"$ISO\") | .id" /tmp/assets.body 2>/dev/null \ + | while read -r aid; do + curl -fsS -X DELETE "$API/releases/$RELEASE_ID/assets/$aid" \ + -H "$AUTH" || true + done + fi # Attach the ISO as a release asset (multipart form, Gitea-compatible). - curl -fsS -X POST "$API/releases/$RELEASE_ID/assets?name=$ISO" \ + http_code=$(curl -sS -o /tmp/asset-upload.body -w '%{http_code}' \ + -X POST "$API/releases/$RELEASE_ID/assets?name=$ISO" \ -H "$AUTH" \ -F "attachment=@$ISO;type=application/octet-stream" \ - -o /dev/null + || true) + echo "POST .../assets?name=$ISO -> HTTP $http_code" + if [ "$http_code" != "201" ] && [ "$http_code" != "200" ]; then + echo "::error::Asset upload failed (HTTP $http_code). Response body:" + head -c 2000 /tmp/asset-upload.body || true + echo + exit 1 + fi echo "::notice::Published $ISO to release $TAG" - echo "::notice::Download: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/download/$TAG/$ISO" + echo "::notice::Download: ${SERVER_URL}/${GITHUB_REPOSITORY}/releases/download/$TAG/$ISO"