From 9a0871a2a9c81d34e0a3986d88febd1d61e84d7f Mon Sep 17 00:00:00 2001 From: M57 Date: Sun, 2 Aug 2026 10:37:08 +0300 Subject: [PATCH] fix(ci): harden version fetches and auto-open issue on workflow failure - Harden all external fetches (fail-fast connect timeout, 3x retry with backoff, max-time cap) so transient network flakes don't kill the run - Capture the real failure reason and open a GitHub issue automatically via a report-failure job (deduped with the 'auto-failure' label, closed automatically when the workflow succeeds again) - Add issues: write permission; run still fails visibly (red) on error --- .github/workflows/update.yml | 70 ++++++++++++++++++++++++++++++++++-- update-version.sh | 4 +-- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 4da57f3..00990b6 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -10,6 +10,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + issues: write + outputs: + fail_reason: ${{ steps.check.outputs.fail_reason }} steps: - uses: actions/checkout@v6 @@ -19,16 +22,31 @@ jobs: - name: Check for updates id: check + continue-on-error: true env: GH_TOKEN: ${{ github.token }} run: | - LATEST_VERSION=$(gh api repos/anomalyco/opencode/releases/latest --jq '.tag_name[1:]') + ERR_LOG="$(mktemp)" + die() { + echo "fail_reason=$1" | tr -d '\n\r' >> "$GITHUB_OUTPUT" + echo "$1" >&2 + exit 1 + } + + LATEST_VERSION="" + for i in 1 2 3; do + if LATEST_VERSION=$(gh api repos/anomalyco/opencode/releases/latest --jq '.tag_name[1:]' 2>>"$ERR_LOG"); then + break + fi + [ "$i" -lt 3 ] && sleep 5 || true + done if [ -z "$LATEST_VERSION" ]; then - echo "Could not find latest version." - exit 1 + die "Could not fetch latest opencode version from GitHub API after 3 attempts. Last error: $(tail -n 1 "$ERR_LOG" 2>/dev/null || echo 'unknown')" fi + echo "fail_reason=" >> "$GITHUB_OUTPUT" + CURRENT_VERSION=$(grep -oP '"version":\s*"\K[^"]+' version.json) echo "Latest: $LATEST_VERSION" @@ -67,3 +85,49 @@ jobs: git add version.json opencode.nix opencode-desktop.nix flake.lock git commit -m "chore: update opencode to ${{ steps.check.outputs.version }}" git push + + - name: Close resolved failure issues + if: success() + env: + GH_TOKEN: ${{ github.token }} + run: | + LABEL="auto-failure" + gh label create "$LABEL" --repo "$GITHUB_REPOSITORY" 2>/dev/null || true + OPEN=$(gh issue list --repo "$GITHUB_REPOSITORY" --label "$LABEL" --state open --json number --jq '.[].number') + for n in $OPEN; do + echo "Closing auto-failure issue #$n (workflow succeeded again)" + gh issue close "$n" --repo "$GITHUB_REPOSITORY" --comment "The Update OpenCode workflow succeeded again — closing automatically." + done + + # continue-on-error above would let the job pass; fail the run when the check failed. + - name: Fail the run + if: steps.check.outcome == 'failure' + run: exit 1 + + report-failure: + runs-on: ubuntu-latest + needs: update-opencode + if: failure() + permissions: + issues: write + steps: + - name: Open failure issue + env: + GH_TOKEN: ${{ github.token }} + run: | + LABEL="auto-failure" + gh label create "$LABEL" --repo "$GITHUB_REPOSITORY" 2>/dev/null || true + + REASON="${{ needs.update-opencode.outputs.fail_reason }}" + [ -n "$REASON" ] || REASON="See the failed run logs for details." + + TITLE="[auto] Update OpenCode workflow failed" + BODY=$(printf 'The **Update OpenCode** workflow failed on %s.\n\n- Run: %s/%s/actions/runs/%s\n- Job: update-opencode\n\n**Failure reason:** %s\n\n_This issue was created automatically. It will be closed automatically when the workflow succeeds again._\n' "$(date -u +'%Y-%m-%d %H:%M UTC')" "$GITHUB_SERVER_URL" "$GITHUB_REPOSITORY" "$GITHUB_RUN_ID" "$REASON") + + EXISTING=$(gh issue list --repo "$GITHUB_REPOSITORY" --label "$LABEL" --state open --json number --jq '.[0].number // empty') + if [ -n "$EXISTING" ]; then + echo "Failure issue #$EXISTING already open — adding comment instead." + gh issue comment "$EXISTING" --repo "$GITHUB_REPOSITORY" --body "Still failing on run $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID — $REASON" + else + gh issue create --repo "$GITHUB_REPOSITORY" --title "$TITLE" --label "$LABEL" --body "$BODY" + fi diff --git a/update-version.sh b/update-version.sh index f044dac..8cb1265 100755 --- a/update-version.sh +++ b/update-version.sh @@ -27,8 +27,8 @@ if [ -n "${1:-}" ]; then echo "Version provided from argument: $version" else echo "Fetching latest version from GitHub..." - version=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" | \ - grep -oP '"tag_name":\s*"v\K[^"]+') + version=$(curl -fsSL --connect-timeout 10 --max-time 30 --retry 3 --retry-delay 3 --retry-all-errors "https://api.github.com/repos/$REPO/releases/latest" | \ + grep -oP '"tag_name":\s*"v\K[^"]+' || true) if [[ -z "$version" ]]; then echo "Error: Failed to fetch latest version from GitHub."