Skip to content

fix(ci): unbreak Validate and Security, and stop a 429 masking a dead link - #8

Closed
napetrov wants to merge 1 commit into
mainfrom
fix/ci-link-check-imports-and-pages-audit
Closed

fix(ci): unbreak Validate and Security, and stop a 429 masking a dead link#8
napetrov wants to merge 1 commit into
mainfrom
fix/ci-link-check-imports-and-pages-audit

Conversation

@napetrov

@napetrov napetrov commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What this changes

main is red on two jobs and every open pull request inherits the first of them. This
fixes both, plus the dependabot config gap that makes CodeQL unpassable on PRs #5 and #6.

Validate / Link check. skills/vllm-xpu-run/SKILL.md points at
docs.vllm.ai/en/latest/getting_started/xpu-installation.html. docs.vllm.ai dropped the
.html URL scheme, so it now redirects to a path that 404s. The link really is dead — but
the file is an import pinned to intel/gpu-ai-skills, and editing it here would move the
failure one step down to sync_external.py --check, which byte-compares the copy against
its pin. Check 8 already resolves this exact tension by warning on an imported body rather
than failing it; the link check now does the same, and the warning says where the fix has
to land. A link this repository wrote still fails, and so does a pinned commit that has
gone missing — that one is our claim, not upstream's.

Link check, second defect. The same tree passed and failed three seconds apart this
morning: PR #3's run got HTTP 429 from docs.vllm.ai and went green, PR #4's got the real
404 and went red.

04:48:39  WARN ... xpu-installation.html was not reachable (HTTP 429)   ← pass
04:48:42  FAIL ... xpu-installation.html is gone (HTTP 404)             ← fail

Rate limiting maps to unknown, which warns. That is right for someone else's outage and
wrong here, because 429 is the one answer a host gives instead of the real one — eight
workers over ~100 URLs concentrated on a few hosts is enough to trigger it. It is now
retried with backoff, honouring Retry-After when it is in seconds, before it may become
a warning. A throttled run can no longer report a dead link as reachable.

Validate step order. Imported skills match their pinned upstream runs after the link
check with no if: always(), so it has never executed on a commit with a dead link — the
state of the imports was unknown for as long as main was red. It now always runs, and it
passes.

Security / zizmor — 5 high, all from the Pages workflow added in #7:

finding fix
pages: write, id-token: write at workflow level moved to the deploy job. build is where third-party code runs (npm ci, npm run build) and is the job that should not hold a token that can publish the site or mint an OIDC identity
actions/configure-pages@v5 unpinned @983d7736 (v5.0.0)
actions/upload-pages-artifact@v3 unpinned @56afc609 (v3.0.1)
actions/deploy-pages@v5 unpinned @368f8252 (v5.0.1)

Each SHA is the one behind the tag that was already resolving, so nothing about what runs
changes. Newer majors exist (configure-pages v6, upload-pages-artifact v5) and are
deliberately left to dependabot, which will propose them with a CI run attached.

CodeQL on dependabot PRs #5 and #6. codeql-action/init and codeql-action/analyze
are two entry points into one action, and it refuses a version split between its halves:

PR #5: Loaded a configuration file for version '4.37.9', but running version '4.36.2'
PR #6: Loaded a configuration file for version '4.36.2', but running version '4.37.9'

Ungrouped, dependabot opens one pull request per path, so each bumps half the pair and
neither can pass its own CI. .github/dependabot.yml now groups github/codeql-action*.
#5 and #6 need closing so the grouped pull request can replace them.

Verified locally

All four gates, plus both linters from the same digest-pinned images security.yml uses:

validate_skills.py                 OK 33 skill(s)
validate_skills.py --check-links   link check: 99 URL(s), 1 gone, 1 of them only in
                                   imported bodies (warned)          exit 0
run_evals.py --validate            OK 10 eval file(s), 30 case(s)
sync_external.py --check           OK, every import matches its pin
actionlint                         clean
zizmor                             No findings to report (12 suppressed)   was 5 high

The imported-body path was unit-checked in both directions: a dead link in a body this
repository wrote still errors, and a rewritten external-commit still errors. The 429
path was checked against a stubbed opener — 429 → 429 → … → warn, and critically
429 → 404 → dead, which is the case that used to buy a green run.

Not in this change

The three stale docs.vllm.ai URLs themselves. They live in imported bodies, so they need a
pull request against intel/gpu-ai-skills and then a pin move here, which is a follow-up
PR. Two of the three are worse than the one CI caught:

file link actually resolves to
vllm-xpu-run/SKILL.md getting_started/xpu-installation.html 404
vllm-xpu-profile/SKILL.md contributing/profiling/profiling_index.html 200 — …/contributing/, the parent page
vllm-xpu-bench/SKILL.md same + #offline-batched-inference-benchmarks 200 — same parent page

Read-the-Docs fuzzy-redirects the latter two, so they answer 200 while pointing an agent at
the wrong page. No status-based link check can see that; it took reading the redirect
chain. Correct targets are
getting_started/installation/gpu.html?device=xpu and contributing/profiling/.

One more thing this change cannot fix: #7 merged with Validate, Security and DCO all
failing, which is how main got here. Worth requiring validate, install, zizmor,
actionlint and signed-off as status checks on main — otherwise every tool above is
advisory.

Checklist

  • I checked description against requests a user would really type — see CONTRIBUTING.md. (no skill text changed)
  • python3 tools/validate_skills.py passes locally.
  • Every commit is signed off with git commit -s (DCO).

@napetrov
napetrov force-pushed the fix/ci-link-check-imports-and-pages-audit branch from a23bac4 to f54bbb7 Compare September 3, 2026 16:00
`main` is red on Validate, and every open pull request inherits it:

    FAIL skills/vllm-xpu-run/SKILL.md: link
      https://docs.vllm.ai/en/latest/getting_started/xpu-installation.html is gone (HTTP 404)

The link really is dead — docs.vllm.ai dropped the `.html` URL scheme, so it now
redirects to a path that 404s. But `skills/vllm-xpu-run/` is an import pinned to
intel/gpu-ai-skills, so editing the URL here would only move the failure one step
down the job, to `sync_external.py --check`, which byte-compares the copy against
its pin. There is no edit to this repository that both satisfies the link check and
keeps the import intact.

Check 8 already resolves exactly this tension. A file a skill ships but never
mentions fails when the skill was written here and warns when it was imported,
because "the only way to satisfy it would be to edit another team's body, and an
edited import no longer matches the text their measurements describe". A dead link
in an imported body is the same shape of finding, so it gets the same treatment,
and the warning says where the repair has to land:

    WARN skills/vllm-xpu-run/SKILL.md: link ... is gone (HTTP 404)
      (imported: upstream's body is kept as it is — fix it upstream, then move
       external-commit)

What still fails: a dead link in a body this repository wrote, and a pinned commit
that has gone missing. The second one shares the mechanism but not the ownership —
`external-commit` is our claim about upstream, not upstream's text, so a SHA
rewritten out of history is our defect to fix and stays an error.

link_targets() now returns a third element saying which origin a URL came from,
rather than check_links() re-deriving it, because the pinned-commit target is
synthesised from .source.json and would otherwise be indistinguishable from a URL
found in the body it sits next to.

MAINTAINERS.md documents the route the warning asks for, and says the thing worth
saying out loud: a warning that outlives a release means the pin is the wrong pin.

Verified locally: the gate passes with the warning, and both error paths were
checked directly — a dead link attributed to a body written here still errors, and
a rewritten external-commit still errors.

The stale docs.vllm.ai URLs themselves are fixed in intel/gpu-ai-skills#12; the pin
move lands here once that merges.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

napetrov commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Superseded — split into five single-purpose pull requests, since the combined change mixed a policy decision, a determinism fix, a step-ordering bug, a workflow-permissions audit and a dependabot config gap under one review.

# scope base
#9 a dead link in an imported body warns instead of failing — unblocks main main
#10 retry a 429 in the link check instead of accepting it #9
#11 run the pinned-upstream check even when the link check failed #9
#12 scope the Pages token to the deploy job and pin its actions — unblocks Security #9
#13 group the codeql-action pins so both halves move together #9

#10 through #13 are stacked on #9 only so their Validate runs are green while main is red; GitHub retargets them to main when #9 merges. All five merge into main cleanly in any order — verified by test-merging the set, then running the full gate plus zizmor and actionlint on the result.

Closing this one.

@napetrov napetrov closed this Sep 3, 2026
@napetrov
napetrov deleted the fix/ci-link-check-imports-and-pages-audit branch September 3, 2026 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant