Skip to content

Commit b7b4f2f

Browse files
committed
ci: retry Lychee label lookups and fall back to the default policy
Read current PR labels once in the shared composite action. Retry failed or malformed lookups three times with 5/10-second delays, then warn and retain the normal link policy. An unconfirmed label never enables the override. Expose the early label decision to the authored pre-commit job so other hooks still run after an ordinary labeled link failure. Nightly and default-branch calls do not query PR labels. Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
1 parent 7f14d10 commit b7b4f2f

4 files changed

Lines changed: 56 additions & 40 deletions

File tree

‎.github/actions/lychee-links/action.yml‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,51 @@ inputs:
1717
refresh:
1818
description: "Check links afresh and publish the successful results as the new baseline"
1919
default: "false"
20+
pr-number:
21+
description: "PR whose current maintainer override label should be read; empty skips the lookup"
22+
default: ""
23+
24+
outputs:
25+
allow-429:
26+
description: "Whether the current PR label explicitly enables the HTTP 429 override"
27+
value: ${{ steps.lychee-policy.outputs.allow-429 }}
2028

2129
# Callers provide Python and the checked-out repository; the build of any
2230
# rendered documentation must already be complete.
2331
runs:
2432
using: composite
2533
steps:
34+
- name: Read the PR's Lychee rate-limit override
35+
id: lychee-policy
36+
shell: bash --noprofile --norc -euo pipefail {0}
37+
env:
38+
GH_TOKEN: ${{ github.token }}
39+
GH_REPO: ${{ github.repository }}
40+
PR_NUMBER: ${{ inputs.pr-number }}
41+
run: |
42+
allow_429=false
43+
if [[ -n "$PR_NUMBER" ]]; then
44+
# Reruns keep the original event's labels, so query the current decision.
45+
# Only an exact boolean response can enable the maintainer override.
46+
lookup_ok=false
47+
for attempt in 1 2 3; do
48+
if result="$(gh pr view "$PR_NUMBER" --json labels --jq '.labels | any(.name == "ci: lychee-non-blocking")')"; then
49+
case "$result" in
50+
true|false) allow_429="$result"; lookup_ok=true; break ;;
51+
esac
52+
fi
53+
if (( attempt < 3 )); then
54+
sleep $((attempt * 5))
55+
fi
56+
done
57+
if [[ "$lookup_ok" != true ]]; then
58+
echo "::warning::Could not read a valid PR label decision; using the default link policy. Rerun to apply ci: lychee-non-blocking."
59+
elif [[ "$allow_429" == true ]]; then
60+
echo "::notice::ci: lychee-non-blocking permits only HTTP 429 failures after retries."
61+
fi
62+
fi
63+
echo "allow-429=$allow_429" >> "$GITHUB_OUTPUT"
64+
2665
- name: Describe the link cache
2766
id: cache
2867
shell: bash --noprofile --norc -euo pipefail {0}
@@ -58,7 +97,7 @@ runs:
5897
shell: bash --noprofile --norc -euo pipefail {0}
5998
env:
6099
KIND: ${{ inputs.kind }}
61-
POLICY: ${{ inputs.policy }}
100+
POLICY: ${{ steps.lychee-policy.outputs.allow-429 == 'true' && 'allow-429' || inputs.policy }}
62101
GITHUB_TOKEN: ${{ github.token }}
63102
run: |
64103
# Install into the interpreter that runs the driver, whatever shell

‎.github/workflows/build-docs.yml‎

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -295,28 +295,14 @@ jobs:
295295
with:
296296
python-version: "3.14"
297297

298-
# Full CI runs on a pull-request/N mirror. Use its PR number to query
299-
# current labels, including when rerunning an older workflow attempt.
300-
- name: Read the PR's Lychee rate-limit override
301-
if: ${{ !inputs.is-release && startsWith(github.ref_name, 'pull-request/') }}
302-
id: lychee-policy
303-
env:
304-
GH_TOKEN: ${{ github.token }}
305-
GH_REPO: ${{ github.repository }}
306-
run: |
307-
allow_429="$(gh pr view "$PR_NUMBER" --json labels --jq '.labels | any(.name == "ci: lychee-non-blocking")')"
308-
echo "allow-429=$allow_429" >> "$GITHUB_OUTPUT"
309-
if [[ "$allow_429" == true ]]; then
310-
echo "::notice::ci: lychee-non-blocking permits only HTTP 429 failures after retries."
311-
fi
312-
313298
- name: Check rendered documentation links through pre-commit
314299
if: ${{ !inputs.is-release && startsWith(github.ref_name, 'pull-request/') }}
315300
timeout-minutes: 60
316301
uses: ./.github/actions/lychee-links
317302
with:
318303
kind: rendered
319-
policy: ${{ steps.lychee-policy.outputs.allow-429 == 'true' && 'allow-429' || 'check' }}
304+
# Full CI's pull-request/N mirror supplies the PR number.
305+
pr-number: ${{ env.PR_NUMBER }}
320306

321307
- name: Upload docs GitHub Pages artifact
322308
if: ${{ inputs.deploy-docs }}

‎.github/workflows/pre-commit.yml‎

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,6 @@ jobs:
140140
LYCHEE_SMOKE_DIR: ${{ steps.lychee-smoke.outputs.directory }}
141141
run: python ci/tools/smoke_test_lychee_precommit.py --cleanup "$LYCHEE_SMOKE_DIR"
142142

143-
# Query current labels so applying or removing the override takes effect
144-
# on a rerun, which otherwise keeps the original event's label snapshot.
145-
- name: Read the PR's Lychee rate-limit override
146-
if: github.event_name == 'pull_request'
147-
id: lychee-policy
148-
env:
149-
GH_TOKEN: ${{ github.token }}
150-
GH_REPO: ${{ github.repository }}
151-
PR_NUMBER: ${{ github.event.pull_request.number }}
152-
run: |
153-
allow_429="$(gh pr view "$PR_NUMBER" --json labels --jq '.labels | any(.name == "ci: lychee-non-blocking")')"
154-
echo "allow-429=$allow_429" >> "$GITHUB_OUTPUT"
155-
if [[ "$allow_429" == true ]]; then
156-
echo "::notice::ci: lychee-non-blocking permits only HTTP 429 failures after retries."
157-
fi
158-
159143
# Warm only Lychee from the shared nightly baseline, retaining successful
160144
# checks between up to three attempts. The full suite below runs once:
161145
# formatter changes must remain failures. A missing baseline is supported;
@@ -166,17 +150,18 @@ jobs:
166150
uses: ./.github/actions/lychee-links
167151
with:
168152
kind: authored
169-
policy: ${{ steps.lychee-policy.outputs.allow-429 == 'true' && 'allow-429' || 'cache-warm' }}
153+
policy: cache-warm
154+
pr-number: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || '' }}
170155

171156
- name: Run pre-commit
172157
# Run the remaining hooks even if the override's link gate fails.
173158
# That earlier failure still makes the job fail.
174-
if: ${{ !cancelled() && (success() || (steps.lychee-policy.outputs.allow-429 == 'true' && steps.lychee-check.outcome == 'failure')) }}
159+
if: ${{ !cancelled() && (success() || (steps.lychee-check.outputs.allow-429 == 'true' && steps.lychee-check.outcome == 'failure')) }}
175160
env:
176161
GITHUB_TOKEN: ${{ github.token }}
177162
# The override uses the reported link result above. All other hooks
178163
# still run once; normal runs also invoke Lychee in the full suite.
179-
SKIP: ${{ steps.lychee-policy.outputs.allow-429 == 'true' && 'check-precommit-installed,lychee' || 'check-precommit-installed' }}
164+
SKIP: ${{ steps.lychee-check.outputs.allow-429 == 'true' && 'check-precommit-installed,lychee' || 'check-precommit-installed' }}
180165
run: pre-commit run --all-files --show-diff-on-failure
181166

182167
- name: Save pre-commit cache

‎ci/README.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,14 @@ suite skips its duplicate Lychee invocation. Every other hook still runs once.
5757
When rate limiting persists, maintainers can apply `ci: lychee-non-blocking`
5858
to the PR and rerun the affected Linux/Windows pre-commit jobs or rendered
5959
documentation job. Applying or removing the label does not itself start a
60-
new workflow run. Each job queries the PR's current labels, so a rerun sees
61-
the current decision rather than the original event's label snapshot.
60+
new workflow run. The shared link-check action queries the PR's current labels,
61+
so a rerun sees the current decision rather than the original event's snapshot.
62+
The lookup makes up to three attempts, waiting 5 and 10 seconds between them.
63+
If every attempt fails or returns an invalid response, the action warns and
64+
keeps the caller's default policy without enabling the override: authored
65+
checks remain strict in the full pre-commit suite, and rendered checks keep
66+
their allowance for at most ten distinct HTTP 429 URLs. Rerun the affected job
67+
to retry the lookup and apply the label; other pre-commit hooks still run.
6268

6369
The label selects the driver's `allow-429` policy for both authored and
6470
rendered checks. Lychee still runs and retries normally; only a final report
@@ -69,8 +75,8 @@ Successful checks retain their usual cache behavior; failures are never cached.
6975

7076
Any other failure still blocks, including a mixture of HTTP 429s and other
7177
errors, broken local files or fragments, timeouts, and HTTP 403, 404, or 5xx
72-
responses. Hook setup, invalid or missing reports, failed label lookups, and
73-
the offline smoke checks remain blocking. Other exceptional failures require
78+
responses. Hook setup, invalid or missing reports, and the offline smoke
79+
checks remain blocking. Other exceptional failures require
7480
the normal admin-merge decision.
7581

7682
The label applies only to PR checks. Local pre-commit runs, default-branch

0 commit comments

Comments
 (0)