From 19b4d152f70e20f0b254686bb7f451ee82323523 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Tue, 1 Sep 2026 23:18:39 -0700 Subject: [PATCH] ci-alert: match title-or-label and poll before opening a second issue Tested in claude-reads-hn on 2026-09-02: the REST issue list lags a write by a few seconds, unevenly, so two opens close together made two issues even with the label filter. Match on title OR label over the plain open list and poll up to 15 s before creating. Same script as the other two repos; live-tested here (open, open, close -> one issue, one comment, closed; test issue deleted). Co-Authored-By: Claude Fable 5.1 --- scripts/ci-alert.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/ci-alert.sh b/scripts/ci-alert.sh index 659a18f..3486e88 100755 --- a/scripts/ci-alert.sh +++ b/scripts/ci-alert.sh @@ -11,10 +11,14 @@ # labelled `ci-failure` — opened on the first failure, commented on for each # subsequent one, and closed automatically by the next green run. # -# Deliberately bounded at one open issue. Dedup uses the REST issue list -# filtered by label, never the search API: search indexing lags writes by -# minutes, which is how a sibling repo once filed byte-identical duplicates -# 13 seconds apart. +# Deliberately bounded at one open issue. Dedup never uses the search API: +# its index lags writes by minutes, which is how a sibling repo once filed +# byte-identical duplicates 13 seconds apart. The REST list lags a write +# too, by a few seconds and unevenly (measured in claude-reads-hn on +# 2026-09-02: two opens one second apart made two issues, with or without +# the label filter). So: match on title OR label over the plain open-issues +# list, and before creating, poll for up to 15 s. Runs are a week apart, so +# the wait costs nothing on the path that matters. # # Adds no secrets — uses the built-in GITHUB_TOKEN via GH_TOKEN. set -euo pipefail @@ -26,7 +30,8 @@ TITLE="deterministic-extract is failing" action="${1:-}" existing() { - gh api "repos/$REPO/issues?state=open&labels=$LABEL&per_page=1" -q '.[0].number // empty' + gh api "repos/$REPO/issues?state=open&per_page=100" \ + -q "[.[] | select(.pull_request == null) | select(.title == \"$TITLE\" or any(.labels[]?; .name == \"$LABEL\"))] | .[0].number // empty" } case "$action" in @@ -34,6 +39,11 @@ case "$action" in run_id="${2:?usage: $0 open }" run_url="https://github.com/$REPO/actions/runs/$run_id" num="$(existing)" + for _ in 1 2 3 4 5; do + [[ -n "$num" ]] && break + sleep 3 + num="$(existing)" + done if [[ -n "$num" ]]; then gh api "repos/$REPO/issues/$num/comments" -f body="Still failing: $run_url" >/dev/null echo "ci-alert: commented on existing #$num" >&2