ci: repository hygiene — pin actions, Dependabot, link check - #55
Open
sstruzik wants to merge 2 commits into
Open
ci: repository hygiene — pin actions, Dependabot, link check#55sstruzik wants to merge 2 commits into
sstruzik wants to merge 2 commits into
Conversation
|
The preview workflow's action references floated on major tags, so the code CI runs was decided by wherever the upstream maintainers last moved those tags, not by anything in this repository. That is not hypothetical here: the preview job's post-deploy step `lib/get-deployed-commit.sh` did not exist in pr-preview-action until 52a1f7b1 (2025-12-24, "Add option to wait for deploy to finish"). It arrived in our CI, and later failed a run, without a single line changing in this repo. Each `uses:` in build-preview.yml is now a commit SHA, which is content-addressed and cannot be repointed, with the version in a trailing comment. No behaviour change — every SHA is exactly what the tags resolved to on the last green run. Pinning alone would stop upstream fixes arriving, so `.github/dependabot.yml` adds the other half: each new release becomes a reviewable pull request rather than a silent tag move. It is scoped to github-actions; a pip block is left for a separate decision since requirements.txt here is the union of six components' docs dependencies. build-deploy.yml is deliberately NOT pinned here. #54 rewrites that workflow for versioned deploys, so pinning it on main would only have to be re-applied on merge; it is pinned in that PR instead. To be clear about what this does NOT do: it would not have prevented the recent preview failure. That run and the passing re-run used the identical action SHA; the cause was a transient GitHub API response in a step that has no retry. This change addresses a different problem — not being able to tell what code CI is executing. Note the pins freeze versions that are already behind: actions/checkout v3.7.0 (latest v7.0.1) and actions/setup-python v4.9.1 (latest v7.0.0), both of which the runner now warns about for targeting Node.js 20. That is deliberate — this commit is pure hardening with no behaviour change, and Dependabot will raise those major upgrades as separate pull requests that can be validated on their own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sstruzik
force-pushed
the
ci/pin-action-shas
branch
from
August 18, 2026 08:47
09f0222 to
b5649f6
Compare
sstruzik
added a commit
that referenced
this pull request
Aug 18, 2026
Companion to #55, which pins build-preview.yml and adds Dependabot on main. This workflow is rewritten here for versioned deploys, so pinning it on main would only have to be re-applied when this merges — it belongs in this PR instead. actions/checkout -> 11d5960a # v4.4.0 actions/setup-python -> a26af69b # v5.6.0 JamesIves/github-pages-deploy-action -> fa247745 # v4.9.0 A commit SHA is content-addressed and cannot be repointed, so the code CI runs is fixed by this repository rather than by wherever an upstream major tag was last moved. No behaviour change: every SHA is what the floating tag resolves to today. This workflow publishes the real site to OasisLMF.github.io with BUILD_DEPLOY_TOKEN, so it is the more valuable of the two to hold still. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sstruzik
added a commit
that referenced
this pull request
Aug 19, 2026
The link check (d8d362b, plus the reason-reporting improvement in 7d920f8) belongs with the other repository hygiene rather than in the restructure: #55 is the cleanup PR — action pinning, Dependabot, and now this — and it merges after this one. Only the tooling moves. The content fix from 7d920f8 stays here: FAQs.rst had an email address wrapped in http://, which is a docs bug this PR should carry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Gathers the repository hygiene here rather than in #54, which is the restructure. Both arrive with the action pinning already in this PR. **Link check over the assembled site** (`check_links.py` + a weekly workflow). Two checks, because they are different problems: internal every in-site link resolves to a file in the tree. Offline, deterministic, 0.9s over 55k links, so it FAILS the run. This is the case that matters: the orchestrator rewrites cross-component links to page-relative paths, so a page renamed in one component silently breaks links from another. It is also what replaces the build-time verification dropped in ODS_Tools#289. external every distinct http(s) URL still answers. 135 URLs, ~20s. Reports but does not fail by default: third-party rate limits and bot blocking are not our bugs, and a check that goes red for someone else's outage is one people learn to ignore. Weekly plus a button, deliberately NOT on pull requests — 100+ third-party requests per PR invites the 429/503 failures this repo hit twice, and link rot is a chore, not a merge gate. Sphinx's own linkcheck builder runs per project against source and cannot see the assembled tree, hence a script. It has already earned its place: the first run found 3 broken in-site links and 15 dead external ones across four repositories, all since fixed or triaged. **Dependabot for pip.** requirements.txt is generated by pip-compile and carries its header, so Dependabot regenerates it with pip-compile rather than hand-editing pinned lines. Grouped into one weekly PR because almost everything is transitive — only requests and jinja2 are direct entries in requirements.in — so a bump means a recompile either way, and one recompile is easier to review than a PR per package. Worth recording why this is hygiene and not urgent: the 43 alerts on the default branch describe main's stale 89-line pin set, and #54 already recompiled it to 122 lines. That merge alone clears the critical advisory (h11 0.14.0 -> 0.16.0, the patched version) and 13 of the alerts (mistune is no longer a dependency at all). Nothing here ships to users; this repository only builds documentation. MERGE ORDER: after #54, and rebase on main once it lands. The link check builds the aggregated site via ./build.sh, and orchestrate.py / modules.json do not exist on main yet — on today's main that script builds the old flat site instead. The workflow is schedule/dispatch-only so it cannot fail this PR's checks, but the weekly job would be checking the wrong tree if this merged first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The repository-hygiene PR, kept separate from the restructure in #54 so that one stays about documentation. Merges after #54 — see Merge order below.
Three things: pin the actions, let Dependabot propose updates instead of them arriving silently, and actually check the links in the published site.
1. Actions pinned to commit SHAs
Every
uses:in the preview workflow floated on a major tag, so the code CI runs was decided by wherever the upstream maintainers last moved that tag rather than by anything here.Not hypothetical: while diagnosing a preview failure on #54 I traced it to
lib/get-deployed-commit.shinpr-preview-action— a script that did not exist until upstream commit52a1f7b1(2025-12-24). It started running in our CI, and later failed a run, without a line changing in this repo.actions/checkouta37ce912…— v3.7.0actions/setup-python7f4fc3e2…— v4.9.1rossjrw/pr-preview-actionffa7509e…— v1.8.1No behaviour change — every SHA is what the tag resolved to on the last green run.
What is actually being pinned
Not Python dependencies — GitHub Actions, a different layer. An action is reusable CI automation living in someone else's repository: when a workflow says
uses: actions/checkout@v3, the runner clones that repository and executes the code inside.actions/checkoutandactions/setup-pythonare bundled Node.js;pr-preview-actionis a composite of 11 YAML steps that internally callsJamesIves/github-pages-deploy-actionand its own shell scripts. That nesting is why the recent failure was hard to place: one "Deploy preview" step is eleven deep.Two properties make it worth holding still: the code executes with our secrets in scope (
BUILD_PREVIEW_TOKENhas write access toOasisLMF/PreviewDocs), and a major tag is a mutable pointer.build-deploy.ymlis not pinned here — #54 rewrites that workflow for versioned deploys, so it is pinned in that PR instead (ed9c4d8). Between the two, every action reference ends up pinned.2. Dependabot
github-actions, so pinning does not mean stagnation: each upstream release becomes a reviewable pull request instead of a silent tag move.Plus
pip, for the docs toolchain.requirements.txtis generated bypip-compileand carries its header, so Dependabot regenerates it withpip-compilerather than hand-editing pinned lines. Grouped into one weekly PR: almost everything alerted is transitive — onlyrequestsandjinja2are direct entries inrequirements.in— so a bump means a recompile either way, and one recompile reviews better than a PR per package.Why this is hygiene rather than urgent: the 43 alerts on the default branch describe
main's stale 89-line pin set, and #54 already recompiled it to 122 lines. That merge alone clears the critical advisory (h110.14.0 → 0.16.0, the patched version) and 13 of the alerts, sincemistuneis no longer a dependency at all. Nothing here ships to users — this repository only builds documentation.3. Link check over the assembled site
check_links.py, run weekly. Two checks, because they are different problems:http(s)URL answers--fail-on-externalopts in)The internal check is the important half: the orchestrator rewrites cross-component links to page-relative paths, so a page renamed in one component silently breaks links from another. It is also what replaces the build-time verification dropped in ODS_Tools#289.
Weekly plus a button, deliberately not on pull requests — 100+ third-party requests per PR invites the 429/503 failures this repo hit twice, and link rot is a maintenance chore, not a merge gate. Sphinx's own
linkcheckbuilder runs per project against source and cannot see the assembled tree, hence a script rather than a builder.It has already earned its place. The first run found 3 broken in-site links and 15 dead external ones across four repositories — a deleted
platform-2.0branch, a goneOasisAPIClientrepo, the pre-split ODS path, an email address wrapped inhttp://— since fixed or triaged. The ignore list covers what is not checkable rather than what is inconvenient:localhostservice UIs in deployment examples,*.example.complaceholders, Stack Overflow / Stack Exchange (which 403 anything automated), anddocs.precisely.com, whose TLS chain does not verify from a plain runner though the pages are fine in a browser.Merge order
After #54, and rebase on
mainonce it lands. The link check builds the aggregated site via./build.sh, andorchestrate.py/modules.jsondo not exist onmainyet — on today'smainthat script builds the old flat site. The workflow is schedule/dispatch-only so it cannot fail this PR's checks, but the weekly job would check the wrong tree if this merged first.Also expect the two PRs to conflict once in
build-preview.yml: #54 changes the Python version there while this pins theuses:line directly above it. I trial-merged both orders — each hits the same two-line conflict, so the order only decides where it lands. Resolution is #54's step name with the pin from here:Deliberately left
The pins freeze versions already behind —
actions/checkoutv3.7.0 (latest v7.0.1) andactions/setup-pythonv4.9.1 (latest v7.0.0), both of which the runner warns about for targeting Node.js 20. That keeps this a pure no-behaviour-change hardening; Dependabot will raise those major upgrades as separate pull requests that can be validated on their own.requirements.txthas 122 exact==pins but 0 hash pins, so the build trusts whatever sits at that version on PyPI.pip-compile --generate-hasheswould close that, and is the more valuable follow-up.Pin GitHub Actions to commit SHAs, add Dependabot for actions and the docs toolchain, and add a weekly link check over the published site.