PR #26 added a bespoke linkcheck.yml that wires together three moving parts by hand — wget-mirroring the live site, lycheeverse/lychee-action, and peter-evans/create-issue-from-file. This issue tracks replacing that with QuantEcon's purpose-built composite action, QuantEcon/action-link-checker, so lecture-dp matches the rest of the lecture family (lecture-python-programming already runs it).
Why switch
Current (linkcheck.yml from #26) |
With action-link-checker |
| Three stitched-together steps to maintain |
One maintained org action |
lychee over **/*.html flags local _static/*, JS and image refs as broken (the mirror only pulls .html) |
Scans external web links only — no local-asset false positives |
create-issue-from-file + hand-set labels |
Native create-issue + notify (auto-assigns maintainers) |
| Weekly schedule only |
Also supports mode: changed for PR-level checks later |
Open decision — where the HTML comes from
The action takes an html-path directory (default ./_build/html). lecture-dp has no gh-pages branch (it deploys via the OIDC artifact workflow), which is exactly why #26 reached for wget-mirroring — so the transition still has to answer this. The cleanest option is to build in-workflow behind the existing Jupyter cache (a warm-cache build skips execution and runs fast) and point the action at the build output; the lower-cost alternative is to keep wget-mirroring the live site into a directory and pass that as html-path.
Sketch (build-in-workflow variant)
Pin to a release tag — only v1.0.0 exists today, there is no sliding v1 (lecture-python-programming pins @main). With Dependabot now configured, a tag pin will be kept current automatically.
name: Link Checker
on:
schedule:
- cron: '0 23 * * 0' # Sunday 23:00 UTC
workflow_dispatch:
jobs:
link-check:
runs-on: ubuntu-latest
container:
image: ghcr.io/quantecon/quantecon-build:latest
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: quantecon/actions/restore-jupyter-cache@v0.6.0
- uses: quantecon/actions/build-lectures@v0.6.0
id: build
with:
builder: html
- uses: QuantEcon/action-link-checker@v1.0.0
with:
html-path: ${{ steps.build.outputs.build-path }}
mode: full
fail-on-broken: 'false'
create-issue: 'true'
silent-codes: '403,503'
issue-title: 'Weekly Link Check Report'
notify: 'mmcky'
Acceptance criteria
Part of #22; supersedes the interim linkcheck.yml introduced in #26.
PR #26 added a bespoke
linkcheck.ymlthat wires together three moving parts by hand —wget-mirroring the live site,lycheeverse/lychee-action, andpeter-evans/create-issue-from-file. This issue tracks replacing that with QuantEcon's purpose-built composite action, QuantEcon/action-link-checker, so lecture-dp matches the rest of the lecture family (lecture-python-programming already runs it).Why switch
linkcheck.ymlfrom #26)action-link-checkerlycheeover**/*.htmlflags local_static/*, JS and image refs as broken (the mirror only pulls.html)create-issue-from-file+ hand-set labelscreate-issue+notify(auto-assigns maintainers)mode: changedfor PR-level checks laterOpen decision — where the HTML comes from
The action takes an
html-pathdirectory (default./_build/html). lecture-dp has nogh-pagesbranch (it deploys via the OIDC artifact workflow), which is exactly why #26 reached forwget-mirroring — so the transition still has to answer this. The cleanest option is to build in-workflow behind the existing Jupyter cache (a warm-cache build skips execution and runs fast) and point the action at the build output; the lower-cost alternative is to keepwget-mirroring the live site into a directory and pass that ashtml-path.Sketch (build-in-workflow variant)
Pin to a release tag — only
v1.0.0exists today, there is no slidingv1(lecture-python-programming pins@main). With Dependabot now configured, a tag pin will be kept current automatically.Acceptance criteria
wget-mirror)linkcheck.ymlwithaction-link-checker, pinned to a release tagworkflow_dispatch: confirm a clean run, and that a seeded broken link produces an assigned issuelychee/create-issue-from-filewiringPart of #22; supersedes the interim
linkcheck.ymlintroduced in #26.