From a0db315ed53aedafa5042c720eff99c7482e1bce Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 2 Oct 2026 11:58:44 +0200 Subject: [PATCH 1/3] Retry check-sources on GitHub 503/429 throttling with backoff --- blink/.gitignore | 2 ++ blink/cmd/check-sources/main.go | 63 +++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 19 deletions(-) create mode 100644 blink/.gitignore diff --git a/blink/.gitignore b/blink/.gitignore new file mode 100644 index 0000000000..17bdc726d6 --- /dev/null +++ b/blink/.gitignore @@ -0,0 +1,2 @@ +/blink +/check-sources diff --git a/blink/cmd/check-sources/main.go b/blink/cmd/check-sources/main.go index f4cb6a2f2c..2bdf4c1f6a 100644 --- a/blink/cmd/check-sources/main.go +++ b/blink/cmd/check-sources/main.go @@ -1,6 +1,7 @@ // Command check-sources verifies that every registered fixer links to a // reachable PHP-CS-Fixer source file on GitHub. It is run in CI so a renamed or -// removed upstream rule fails the build. +// removed upstream rule fails the build. GitHub rate-limits bursts of HEAD +// requests with 503/429, so each URL is retried with backoff before failing. package main import ( @@ -12,34 +13,58 @@ import ( "blink/internal/fixer/rules" ) -func main() { - client := &http.Client{Timeout: 20 * time.Second} - failed := false - - for _, f := range rules.All() { - url := f.SourceURL() +const maxAttempts = 4 +// checkURL returns the final status code (or an error) for url, retrying on a +// 5xx or 429 that GitHub returns when throttling a burst of requests. +func checkURL(client *http.Client, url string) (int, error) { + var lastStatus int + var lastErr error + for attempt := 1; attempt <= maxAttempts; attempt++ { req, err := http.NewRequest(http.MethodHead, url, nil) if err != nil { - fmt.Printf("FAIL %s: %v\n", f.Name(), err) - failed = true - continue + return 0, err } - + req.Header.Set("User-Agent", "blink-check-sources") resp, err := client.Do(req) if err != nil { - fmt.Printf("FAIL %s: %v\n", f.Name(), err) - failed = true - continue + lastErr = err + } else { + _ = resp.Body.Close() + lastStatus, lastErr = resp.StatusCode, nil + if resp.StatusCode == http.StatusOK { + return resp.StatusCode, nil + } + // a 4xx other than 429 is a genuine missing/renamed source, not throttling + if resp.StatusCode != http.StatusTooManyRequests && resp.StatusCode < 500 { + return resp.StatusCode, nil + } } - _ = resp.Body.Close() + if attempt < maxAttempts { + time.Sleep(time.Duration(attempt) * 2 * time.Second) + } + } + return lastStatus, lastErr +} - if resp.StatusCode != http.StatusOK { - fmt.Printf("FAIL %s: %s -> %d\n", f.Name(), url, resp.StatusCode) +func main() { + client := &http.Client{Timeout: 20 * time.Second} + failed := false + + for _, f := range rules.All() { + url := f.SourceURL() + status, err := checkURL(client, url) + switch { + case err != nil: + fmt.Printf("FAIL %s: %v\n", f.Name(), err) + failed = true + case status != http.StatusOK: + fmt.Printf("FAIL %s: %s -> %d\n", f.Name(), url, status) failed = true - continue + default: + fmt.Printf("OK %s\n", url) } - fmt.Printf("OK %s\n", url) + time.Sleep(150 * time.Millisecond) // throttle so GitHub does not rate-limit the burst } if failed { From 7f350cf32d42b4488a626bc8e1278722a89c9c7e Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 2 Oct 2026 11:58:44 +0200 Subject: [PATCH 2/3] Run PHP engine single-process in blink parity gate to avoid NDJSON buffer abort --- .github/workflows/blink_parity_mautic.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/blink_parity_mautic.yaml b/.github/workflows/blink_parity_mautic.yaml index ecb6d490c6..36e32a10ad 100644 --- a/.github/workflows/blink_parity_mautic.yaml +++ b/.github/workflows/blink_parity_mautic.yaml @@ -72,7 +72,10 @@ jobs: common: true, standaloneLine: true, cleanCode: true, - ); + ) + // single process: parallel workers overflow the NDJSON buffer on + // large mautic files and abort the PHP run (blink ignores this) + ->withoutParallel(); PHP cp /tmp/mautic/ecs.php /tmp/mautic/ecs-copy.php From 8a89d14623d43ad4cd58996360e45794485b3001 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 2 Oct 2026 12:01:56 +0200 Subject: [PATCH 3/3] Tighten mautic blink parity gate to 1.6 percent --- .github/workflows/blink_parity_mautic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/blink_parity_mautic.yaml b/.github/workflows/blink_parity_mautic.yaml index 36e32a10ad..9442706a57 100644 --- a/.github/workflows/blink_parity_mautic.yaml +++ b/.github/workflows/blink_parity_mautic.yaml @@ -95,7 +95,7 @@ jobs: - name: Compare the two trees run: | # ratchet gate: fail once the differing share crosses this; lower it as parity improves - MAX_DIFF_PERCENT=1.7 + MAX_DIFF_PERCENT=1.6 total=0 differ=0 differing_files=""