Skip to content

fix(release): retry commit PR API with curl - #717

Merged
syzsunshine219 merged 1 commit into
mainfrom
codex/fix-draft-release-curl
Oct 22, 2026
Merged

syzsunshine219 merged 1 commit into
mainfrom
codex/fix-draft-release-curl

Conversation

@syzsunshine219

Copy link
Copy Markdown
Collaborator

Fixes the remaining GitHub Draft Release v2 snapshot failures caused by truncated commit-to-PR responses on Actions runners.

The workflow now uses curl with transport retries, status validation, and JSON validation for each per_page=100 request. It remains fail-closed after the bounded outer retries and reports the affected commit SHA.

Validation

  • npm run test:release-workflow -- --run: 31 tests passed.
  • Shell simulation confirmed a truncated HTTP 200 body is retried and produces PULL_REQUESTS.json.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

🤖 Open Code Review

Target: PR #717
Task: a9c6fb0432fd2971
Base: main
Head: codex/fix-draft-release-curl

🔍 OpenCodeReview found 4 issue(s) in this PR.

⚠️ 1 warning(s) occurred during review.


1. .github/workflows/github-draft-release-v2.yml (L364-L372)

The combination of --retry-all-errors and || true can cause silent failures to be indistinguishable from genuine empty output. More importantly, --retry-all-errors retries on all errors including HTTP 4xx responses (e.g., 401 Unauthorized or 404 Not Found). A permanent 401 caused by an expired GH_TOKEN will burn through all 4 internal curl retries × 3 outer loop attempts (12 total fruitless API calls) before failing. Consider limiting retries to transient conditions: use --retry-connrefused instead of --retry-all-errors, or explicitly check for permanent HTTP error codes to break the outer loop early.

💡 Suggested Change

Before:

                curl --silent --show-error --location \
                  --retry 4 --retry-delay 2 --retry-max-time 30 --retry-all-errors \
                  --connect-timeout 10 --max-time 45 \
                  --header "Accept: application/vnd.github+json" \
                  --header "Authorization: Bearer ${GH_TOKEN}" \
                  --header "X-GitHub-Api-Version: 2022-11-28" \
                  --output "$pr_response" \
                  --write-out '%{http_code}' \
                  "$api_url/repos/${GITHUB_REPOSITORY}/commits/${commit_sha}/pulls?per_page=100" || true

After:

              http_status="$(
                curl --silent --show-error --location \
                  --retry 4 --retry-delay 2 --retry-max-time 30 --retry-connrefused \
                  --connect-timeout 10 --max-time 45 \
                  --header "Accept: application/vnd.github+json" \
                  --header "Authorization: Bearer ${GH_TOKEN}" \
                  --header "X-GitHub-Api-Version: 2022-11-28" \
                  --output "$pr_response" \
                  --write-out '%{http_code}' \
                  "$api_url/repos/${GITHUB_REPOSITORY}/commits/${commit_sha}/pulls?per_page=100" || true
              )"
              # Bail immediately on permanent client errors (4xx)
              if [[ "$http_status" =~ ^4[0-9]{2}$ ]]; then
                echo "::error title=Pull request evidence failed::Permanent HTTP $http_status for commit $commit_sha. Aborting retries." >&2
                exit 1
              fi

2. .github/workflows/github-draft-release-v2.yml (L374-L383)

If jq -c '.[] | {...}' fails (e.g., a field like .base.ref is null or the array contains an unexpected object shape), it exits non-zero but the error is not caught because set -e does not apply inside a conditional's left-hand side after &&. The >> release-assets/PULL_REQUESTS.jsonl append happens regardless of whether jq partially wrote malformed records before erroring. Consider adding an explicit error check, or write to a temp file first and only append on a full-success exit code:

if tmp=$(jq -c '.[] | {...}' "$pr_response"); then
  printf '%s\n' "$tmp" >> release-assets/PULL_REQUESTS.jsonl
fi
💡 Suggested Change

Before:

              if [[ "$http_status" == "200" ]] \
                && jq -e 'type == "array"' "$pr_response" >/dev/null 2>&1; then
                jq -c '.[] | {
                  number,
                  title,
                  htmlUrl: .html_url,
                  mergedAt: .merged_at,
                  baseRef: .base.ref,
                  headRef: .head.ref
                }' "$pr_response" >> release-assets/PULL_REQUESTS.jsonl

After:

              if [[ "$http_status" == "200" ]] \
                && jq -e 'type == "array"' "$pr_response" >/dev/null 2>&1; then
                if pr_lines="$(jq -c '.[] | {
                  number,
                  title,
                  htmlUrl: .html_url,
                  mergedAt: .merged_at,
                  baseRef: .base.ref,
                  headRef: .head.ref
                }' "$pr_response")"; then
                  printf '%s\n' "$pr_lines" >> release-assets/PULL_REQUESTS.jsonl
                else
                  echo "::warning title=PR transform failed::jq transform failed for commit $commit_sha response." >&2
                  continue
                fi

3. .github/workflows/github-draft-release-v2.yml (L387-L388)

On the final attempt (attempt=3), the warning message is printed and sleep 6 is executed unnecessarily before the loop exits. This adds 6 seconds of dead wait per failing commit SHA. Move the sleep inside a guard that checks attempt < 3, or restructure as [[ $attempt -lt 3 ]] && sleep "$((attempt * 2))".

💡 Suggested Change

Before:

              echo "::warning title=Retrying pull request evidence::GitHub PR metadata for commit $commit_sha was unavailable or malformed (HTTP $http_status, attempt $attempt/3)." >&2
              sleep "$((attempt * 2))"

After:

              echo "::warning title=Retrying pull request evidence::GitHub PR metadata for commit $commit_sha was unavailable or malformed (HTTP $http_status, attempt $attempt/3)." >&2
              [[ $attempt -lt 3 ]] && sleep "$((attempt * 2))"

4. .github/workflows/github-draft-release-v2.yml (L363-L373)

Using --location (follow redirects) together with --header "Authorization: Bearer ${GH_TOKEN}" causes curl to forward the token to any redirect destination. If the GitHub API ever returns a redirect to a third-party host (including CDN endpoints or future URL changes), the bearer token is silently sent to that host. Use --location --proto-redir -all,https to limit redirects to HTTPS only, or replace --location with the explicit --proto '=https' flag, or better yet add --no-location since the GitHub REST API for this endpoint does not issue meaningful redirects.

💡 Suggested Change

Before:

              http_status="$(
                curl --silent --show-error --location \
                  --retry 4 --retry-delay 2 --retry-max-time 30 --retry-all-errors \
                  --connect-timeout 10 --max-time 45 \
                  --header "Accept: application/vnd.github+json" \
                  --header "Authorization: Bearer ${GH_TOKEN}" \
                  --header "X-GitHub-Api-Version: 2022-11-28" \
                  --output "$pr_response" \
                  --write-out '%{http_code}' \
                  "$api_url/repos/${GITHUB_REPOSITORY}/commits/${commit_sha}/pulls?per_page=100" || true
              )"

After:

              http_status="$(
                curl --silent --show-error \
                  --retry 4 --retry-delay 2 --retry-max-time 30 --retry-all-errors \
                  --connect-timeout 10 --max-time 45 \
                  --header "Accept: application/vnd.github+json" \
                  --header "Authorization: Bearer ${GH_TOKEN}" \
                  --header "X-GitHub-Api-Version: 2022-11-28" \
                  --output "$pr_response" \
                  --write-out '%{http_code}' \
                  "$api_url/repos/${GITHUB_REPOSITORY}/commits/${commit_sha}/pulls?per_page=100" || true
              )"

🧹 Filtered 1 low-confidence OCR finding(s) before posting/fix-loop (duplicate: 1).

Generated by cloud-assistant via Open Code Review.

@syzsunshine219
syzsunshine219 merged commit 31e45f3 into main Oct 22, 2026
2 of 3 checks passed
@syzsunshine219
syzsunshine219 deleted the codex/fix-draft-release-curl branch October 22, 2026 17:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants