fix: use integer label IDs for Forgejo issue creation

Forgejo's create-issue API expects `labels` as `[int64]` (label IDs),
not `[{"name": "..."}]` like GitHub. The previous format caused a JSON
unmarshal error, silently returning null instead of creating the issue.

Changes:
- Split label step to create-if-missing then look up the ID
- Pass label ID as integer to issue creation: `labels: [169]`
- Add error handling: log API response if issue creation returns null
- Also cleaned up another duplicate upstream-sync label

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Vlad MocanuandClaude Opus 4.6 committed 2026-02-27 13:21:52 +02:00
1 parent d1c8fd0946
commit f3e800e254
2 files changed
+60 -31

No files matched your search

+30 -15
View File
@@ -389,21 +389,34 @@ else
fi""" fi"""
} }
{ {
name = "Create upstream-sync label" name = "Ensure upstream-sync label exists"
"if" = h.gha_steps_eq("compare", "needs_sync", "true") "if" = h.gha_steps_eq("compare", "needs_sync", "true")
id = "label"
run = """\ run = """\
API="${h.gha_env("GITHUB_API_URL")}/repos/${h.gha_github("repository")}"
AUTH="Authorization: token ${h.gha_secret("CLAUDE_BOT_TOKEN")}"
# Try to create the label (409 = already exists, which is fine)
curl -s -o /dev/null -w "%{http_code}" \\ curl -s -o /dev/null -w "%{http_code}" \\
-X POST \\ -X POST -H "${"$"}AUTH" -H "Content-Type: application/json" \\
-H "Authorization: token ${h.gha_secret("CLAUDE_BOT_TOKEN")}" \\
-H "Content-Type: application/json" \\
-d '{"name":"upstream-sync","color":"#0075ca","description":"Upstream sync tracking"}' \\ -d '{"name":"upstream-sync","color":"#0075ca","description":"Upstream sync tracking"}' \\
"${h.gha_env("GITHUB_API_URL")}/repos/${h.gha_github("repository")}/labels" || true""" "${"$"}API/labels" || true
# Look up the label ID (Forgejo needs integer IDs, not names)
LABEL_ID=${"$"}(curl -s -H "${"$"}AUTH" "${"$"}API/labels" | jq -r '[.[] | select(.name == "upstream-sync")] | .[0].id // ""')
echo "label_id=${"$"}LABEL_ID" >> "${"$"}GITHUB_OUTPUT"
echo "upstream-sync label ID: ${"$"}LABEL_ID"
"""
} }
{ {
name = "Create or update sync issue" name = "Create or update sync issue"
"if" = h.gha_steps_eq("compare", "needs_sync", "true") "if" = h.gha_steps_eq("compare", "needs_sync", "true")
id = "sync-issue" id = "sync-issue"
run = """\ run = """\
API="${h.gha_env("GITHUB_API_URL")}/repos/${h.gha_github("repository")}"
AUTH="Authorization: token ${h.gha_secret("CLAUDE_BOT_TOKEN")}"
LABEL_ID="${h.gha_steps("label", "label_id")}"
BEHIND="${h.gha_steps("compare", "behind")}" BEHIND="${h.gha_steps("compare", "behind")}"
AHEAD="${h.gha_steps("compare", "ahead")}" AHEAD="${h.gha_steps("compare", "ahead")}"
COMMIT_LOG=${"$"}(cat <<'LOG_EOF' COMMIT_LOG=${"$"}(cat <<'LOG_EOF'
@@ -460,22 +473,24 @@ TITLE="Upstream sync: ${"$"}{BEHIND} new commits from anthropics/claude-code-act
if [ "${h.gha_steps("existing", "issue_exists")}" = "true" ]; then if [ "${h.gha_steps("existing", "issue_exists")}" = "true" ]; then
ISSUE_NUMBER="${h.gha_steps("existing", "issue_number")}" ISSUE_NUMBER="${h.gha_steps("existing", "issue_number")}"
curl -s -o /dev/null \\ curl -s -o /dev/null \\
-X PATCH \\ -X PATCH -H "${"$"}AUTH" -H "Content-Type: application/json" \\
-H "Authorization: token ${h.gha_secret("CLAUDE_BOT_TOKEN")}" \\
-H "Content-Type: application/json" \\
-d "${"$"}(jq -n --arg title "${"$"}TITLE" --arg body "${"$"}BODY" '{title: ${"$"}title, body: ${"$"}body}')" \\ -d "${"$"}(jq -n --arg title "${"$"}TITLE" --arg body "${"$"}BODY" '{title: ${"$"}title, body: ${"$"}body}')" \\
"${h.gha_env("GITHUB_API_URL")}/repos/${h.gha_github("repository")}/issues/${"$"}{ISSUE_NUMBER}" "${"$"}API/issues/${"$"}{ISSUE_NUMBER}"
echo "Updated existing issue #${"$"}{ISSUE_NUMBER}" echo "Updated existing issue #${"$"}{ISSUE_NUMBER}"
echo "issue_number=${"$"}{ISSUE_NUMBER}" >> "${"$"}GITHUB_OUTPUT" echo "issue_number=${"$"}{ISSUE_NUMBER}" >> "${"$"}GITHUB_OUTPUT"
else else
# Forgejo expects labels as integer IDs, not objects with names
RESPONSE=${"$"}(curl -s \\ RESPONSE=${"$"}(curl -s \\
-X POST \\ -X POST -H "${"$"}AUTH" -H "Content-Type: application/json" \\
-H "Authorization: token ${h.gha_secret("CLAUDE_BOT_TOKEN")}" \\ -d "${"$"}(jq -n --arg title "${"$"}TITLE" --arg body "${"$"}BODY" --argjson labels "[${"$"}{LABEL_ID:-0}]" '{title: ${"$"}title, body: ${"$"}body, labels: ${"$"}labels}')" \\
-H "Content-Type: application/json" \\ "${"$"}API/issues")
-d "${"$"}(jq -n --arg title "${"$"}TITLE" --arg body "${"$"}BODY" '{title: ${"$"}title, body: ${"$"}body, labels: [{"name": "upstream-sync"}]}')" \\
"${h.gha_env("GITHUB_API_URL")}/repos/${h.gha_github("repository")}/issues")
ISSUE_NUMBER=${"$"}(echo "${"$"}RESPONSE" | jq '.number') ISSUE_NUMBER=${"$"}(echo "${"$"}RESPONSE" | jq '.number')
echo "Created new upstream sync issue #${"$"}{ISSUE_NUMBER}" if [ "${"$"}ISSUE_NUMBER" = "null" ] || [ -z "${"$"}ISSUE_NUMBER" ]; then
echo "::error::Failed to create issue. API response:"
echo "${"$"}RESPONSE" | jq '.'
else
echo "Created new upstream sync issue #${"$"}{ISSUE_NUMBER}"
fi
echo "issue_number=${"$"}{ISSUE_NUMBER}" >> "${"$"}GITHUB_OUTPUT" echo "issue_number=${"$"}{ISSUE_NUMBER}" >> "${"$"}GITHUB_OUTPUT"
fi""" fi"""
} }
+30 -16
View File
@@ -88,19 +88,31 @@ jobs:
echo "issue_exists=false" >> "$GITHUB_OUTPUT" echo "issue_exists=false" >> "$GITHUB_OUTPUT"
echo "No existing sync issue found" echo "No existing sync issue found"
fi fi
- name: Create upstream-sync label - name: Ensure upstream-sync label exists
if: steps.compare.outputs.needs_sync == 'true' if: steps.compare.outputs.needs_sync == 'true'
run: |- id: label
run: |
API="${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}"
AUTH="Authorization: token ${{ secrets.CLAUDE_BOT_TOKEN }}"
# Try to create the label (409 = already exists, which is fine)
curl -s -o /dev/null -w "%{http_code}" \ curl -s -o /dev/null -w "%{http_code}" \
-X POST \ -X POST -H "$AUTH" -H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.CLAUDE_BOT_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"name":"upstream-sync","color":"#0075ca","description":"Upstream sync tracking"}' \ -d '{"name":"upstream-sync","color":"#0075ca","description":"Upstream sync tracking"}' \
"${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}/labels" || true "$API/labels" || true
# Look up the label ID (Forgejo needs integer IDs, not names)
LABEL_ID=$(curl -s -H "$AUTH" "$API/labels" | jq -r '[.[] | select(.name == "upstream-sync")] | .[0].id // ""')
echo "label_id=$LABEL_ID" >> "$GITHUB_OUTPUT"
echo "upstream-sync label ID: $LABEL_ID"
- name: Create or update sync issue - name: Create or update sync issue
if: steps.compare.outputs.needs_sync == 'true' if: steps.compare.outputs.needs_sync == 'true'
id: sync-issue id: sync-issue
run: |- run: |-
API="${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}"
AUTH="Authorization: token ${{ secrets.CLAUDE_BOT_TOKEN }}"
LABEL_ID="${{ steps.label.outputs.label_id }}"
BEHIND="${{ steps.compare.outputs.behind }}" BEHIND="${{ steps.compare.outputs.behind }}"
AHEAD="${{ steps.compare.outputs.ahead }}" AHEAD="${{ steps.compare.outputs.ahead }}"
COMMIT_LOG=$(cat <<'LOG_EOF' COMMIT_LOG=$(cat <<'LOG_EOF'
@@ -157,22 +169,24 @@ jobs:
if [ "${{ steps.existing.outputs.issue_exists }}" = "true" ]; then if [ "${{ steps.existing.outputs.issue_exists }}" = "true" ]; then
ISSUE_NUMBER="${{ steps.existing.outputs.issue_number }}" ISSUE_NUMBER="${{ steps.existing.outputs.issue_number }}"
curl -s -o /dev/null \ curl -s -o /dev/null \
-X PATCH \ -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.CLAUDE_BOT_TOKEN }}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg title "$TITLE" --arg body "$BODY" '{title: $title, body: $body}')" \ -d "$(jq -n --arg title "$TITLE" --arg body "$BODY" '{title: $title, body: $body}')" \
"${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}/issues/${ISSUE_NUMBER}" "$API/issues/${ISSUE_NUMBER}"
echo "Updated existing issue #${ISSUE_NUMBER}" echo "Updated existing issue #${ISSUE_NUMBER}"
echo "issue_number=${ISSUE_NUMBER}" >> "$GITHUB_OUTPUT" echo "issue_number=${ISSUE_NUMBER}" >> "$GITHUB_OUTPUT"
else else
# Forgejo expects labels as integer IDs, not objects with names
RESPONSE=$(curl -s \ RESPONSE=$(curl -s \
-X POST \ -X POST -H "$AUTH" -H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.CLAUDE_BOT_TOKEN }}" \ -d "$(jq -n --arg title "$TITLE" --arg body "$BODY" --argjson labels "[${LABEL_ID:-0}]" '{title: $title, body: $body, labels: $labels}')" \
-H "Content-Type: application/json" \ "$API/issues")
-d "$(jq -n --arg title "$TITLE" --arg body "$BODY" '{title: $title, body: $body, labels: [{"name": "upstream-sync"}]}')" \
"${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}/issues")
ISSUE_NUMBER=$(echo "$RESPONSE" | jq '.number') ISSUE_NUMBER=$(echo "$RESPONSE" | jq '.number')
echo "Created new upstream sync issue #${ISSUE_NUMBER}" if [ "$ISSUE_NUMBER" = "null" ] || [ -z "$ISSUE_NUMBER" ]; then
echo "::error::Failed to create issue. API response:"
echo "$RESPONSE" | jq '.'
else
echo "Created new upstream sync issue #${ISSUE_NUMBER}"
fi
echo "issue_number=${ISSUE_NUMBER}" >> "$GITHUB_OUTPUT" echo "issue_number=${ISSUE_NUMBER}" >> "$GITHUB_OUTPUT"
fi fi
merge-upstream: merge-upstream: