Skip to content

Fix the nightly link check: tell a broken runner from a dead link, repair every dead link it found - #21694

Merged
shoumikhin merged 1 commit into
mainfrom
shoumikhin/linkcheck-fewer-false-positives
Aug 10, 2026
Merged

Fix the nightly link check: tell a broken runner from a dead link, repair every dead link it found#21694
shoumikhin merged 1 commit into
mainfrom
shoumikhin/linkcheck-fewer-false-positives

Conversation

@shoumikhin

@shoumikhin shoumikhin commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

The nightly link-check / lint-urls job has been red for weeks. There are two separate problems behind that, and this PR fixes both.

Problem 1: the script cannot tell a dead host from a broken runner

scripts/lint_urls.sh gets 000 back from curl when there is no HTTP response at
all. That happens for two very different reasons: the host is dead, or the runner
has no working egress. The script treated both as WARN and moved on.

That is unsafe in both directions:

  • A genuinely dead host is silently tolerated. The 000 case is exactly the one we
    most want to catch.
  • More importantly it also disables the pull request gate. .github/workflows/lint.yml
    runs this same script in diff mode on every pull request, where the only URLs
    checked are the ones that pull request adds. A new link with a typo in the host
    name gives 000 and passes today. A runner with no egress makes every link WARN
    and the whole job green. Both were reproduced locally.

The fix

On 000, probe one known-good URL, https://api.github.com, which the runner
already depends on:

  • probe also returns 000, so this runner has no egress: WARN, as before.
  • probe returns anything else, so egress works and the problem is the host: retry
    the URL once with a 60 second timeout, then judge it on that result, which for a
    dead host means FAIL.

One deliberate addition worth calling out: the retry with the longer timeout is
more than the minimum needed to close the hole. It is there because the same URLs
were sampled across six nights of nightly logs and a small number of them, one or
two per night out of about 2100, return 000 once and then answer normally. The
default timeout is 10 seconds. Without the retry, this change would turn those
into hard failures and the nightly would stay red for no good reason.

Also removed: the check-host.net fallback

When the first request failed, the script asked check-host.net whether the URL
was reachable from elsewhere and could then overwrite the verdict. That is
removed. Note this makes the script stricter, not more lenient: on a 404 or a 500
the fallback could turn a FAIL into an OK. Dropping it means a real 404 stays a
404, and it also removes a third-party service from the critical path of a lint
job.

Problem 2: eight actually dead links

With problem 1 fixed the nightly would still be red, because there really are dead
links in the tree. The most recent nightly on main
(31350839957)
reported 7 x FAIL 404 and 1 x FAIL 000. All eight are handled here:

file link what happened fix
setup.py pybind/cmake_example blob/master/setup.py that project deleted its setup.py, so a master link cannot work pin to the last revision that still had it
.ci/docker/common/install_openssl.sh pytorch/pytorch blob/main/.ci/docker/common/install_openssl.sh the file moved on main pin to a revision where it exists
.ci/scripts/test_llava.sh Wikimedia basketball photo the photo was renamed on Wikimedia, not deleted point at the same photo under its current name
docs/source/kernel-library-custom-aten-kernel.md pytorch.org/cppdocs/library.html#... page and anchor both gone current cppdocs library index
test/models/export_program.py pytorch.org/cppdocs/notes/tensor_indexing.html gone, and it was only mentioned in a comment drop the URL, keep the sentence
docs/source/success-stories.md an App Store listing app delisted drop the link, keep the text
README.md github.com/pytorch/executorch/stargazers returns 404 to an unauthenticated bot, works fine in a browser @lint-ignore
backends/arm/scripts/toolchain_utils.sh musl.cc toolchain tarball serves fine to developers, has never once answered from a GitHub hosted runner @lint-ignore

Two more URLs are cleaned up along the way: a truncated Qualcomm SDK URL in
backends/qualcomm/scripts/download_qnn_sdk.py that was never a real link, and a
Qwen issue link in examples/models/llama/runner/generation.py pointing at the
old repository name.

On the Wikimedia one specifically: examples/models/llava/README.md already
embeds the renamed photo and documents the caption the model produces for it,
which matches the EXPECTED_PREFIX the script asserts. So this restores the
original input rather than substituting a different picture. Worth knowing, and
the reason this is low risk: no workflow runs .ci/scripts/test_llava.sh. Both
pull.yml and trunk.yml carry the comment "llava gives segfault so not
covering", so llava is not in CI at all right now.

How this was verified

A whole-tree scan is nightly-only, so a pull request run here would only check the
handful of URLs this PR adds. To get real numbers, _link_check.yml was dispatched
in whole-tree mode against this branch's contents
(31417702080):

main, nightly this branch, whole tree
URLs scanned 2148 2147
OK 2116 2116
WARN 24 31
FAIL 8 0

Reconciling the two totals, since they should not match exactly:

  • 11 URLs leave the scan: 5 replaced by a working equivalent, 4 deleted outright,
    and 2 now marked @lint-ignore.
  • 6 join it: the 5 replacements, plus https://api.github.com, which is now
    written in lint_urls.sh as the probe target and so gets scanned itself.
  • That is 2148 minus 5, which is 2143. The remaining 4 are URLs that landed on main
    during the day, in examples/models/muse-glimmer/, and are unrelated to this
    change. All 4 pass.

The 7 extra WARNs are the same thing that produces the existing 24: sites that
return 403 to an automated client. Between the two runs, cppreference.com,
stackoverflow.com and vulkan.org happened to answer 403 instead of 200.
Those are already treated as warnings and are not affected by this PR.

The 000 handling itself was also exercised directly, in a scratch repository:

  • no egress at all: WARN 000, exit 0, matching a broken runner.
  • egress working, host that does not exist: FAIL 000, exit 1.
  • OK 200, WARN 403 and FAIL 404 all still behave as before.
  • diff mode still only looks at added lines.

Copilot AI lite review requested due to automatic review settings August 8, 2026 23:03
@pytorch-bot

pytorch-bot Bot commented Aug 8, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21694

Note: Links to docs will display an error until the docs builds have been completed.

⏳ No Failures, 114 Pending

As of commit f4bd5e6 with merge base 9cd0c12 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from dbb9910 to 091bebf Compare August 8, 2026 23:33
Copilot AI review requested due to automatic review settings August 8, 2026 23:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from 091bebf to 8ca5333 Compare August 9, 2026 04:39
Copilot AI review requested due to automatic review settings August 9, 2026 04:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin shoumikhin changed the title Make the nightly link check trustworthy: stop failing on no-response, fix the one real dead link Fix the nightly link check: stop failing on no-response, repair every dead link it found Aug 9, 2026
@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from 8ca5333 to 6813118 Compare August 9, 2026 04:51
Copilot AI review requested due to automatic review settings August 9, 2026 04:51
@shoumikhin
shoumikhin requested a review from psiddh as a code owner August 9, 2026 04:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from a6bb414 to 6c4e82c Compare August 9, 2026 05:55
Copilot AI review requested due to automatic review settings August 9, 2026 05:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 10, 2026 05:51
@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from 6c4e82c to 70e4370 Compare August 10, 2026 05:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shoumikhin
shoumikhin force-pushed the shoumikhin/linkcheck-fewer-false-positives branch from 70e4370 to f4bd5e6 Compare August 10, 2026 18:07
Copilot AI review requested due to automatic review settings August 10, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added ciflow/trunk module: arm Issues related to arm backend labels Aug 10, 2026
@shoumikhin shoumikhin changed the title Fix the nightly link check: stop failing on no-response, repair every dead link it found Fix the nightly link check: tell a broken runner from a dead link, repair every dead link it found Aug 10, 2026
@shoumikhin
shoumikhin merged commit 52467d5 into main Aug 10, 2026
689 of 690 checks passed
@shoumikhin
shoumikhin deleted the shoumikhin/linkcheck-fewer-false-positives branch August 10, 2026 19:04
psiddh added a commit to psiddh/executorch that referenced this pull request Aug 12, 2026
The URL, xref, and file size linters diffed base..head, where base is the tip
of the base branch rather than the point the branch left it. A branch cut
before recent commits still carries the lines those commits replaced, so
against the newer tip its old copies read as additions and the branch is
blamed for links someone else already repaired. pytorch#21729 failed exactly that
way, on eight links pytorch#21694 had already fixed or ignored.

The workflow now resolves the merge base and passes it down. That is the half
that matters for branches already open: on a pull request the reusable
workflow resolves from the merge commit, so it carries this fix even though
scripts/ still comes from the branch itself. The scripts switch to three dot
ranges so running them by hand behaves the same way, and the checkouts fetch
real history, without which no merge base exists to compute.

Authored with Claude Code (Claude Opus 5).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/trunk CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: arm Issues related to arm backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants