Skip to content

CI: guard against reading data-lectures over the LFS media host - #830

Merged
mmcky merged 1 commit into
mainfrom
ci/data-url-guard
Aug 10, 2026
Merged

CI: guard against reading data-lectures over the LFS media host#830
mmcky merged 1 commit into
mainfrom
ci/data-url-guard

Conversation

@mmcky

@mmcky mmcky commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Gate 2 of QuantEcon/workspace-lectures#23 step 3. One new workflow, no lecture changes.

The failure it catches

media.githubusercontent.com is the LFS media endpoint. It routes per path, not per repo — it serves a file only where that path is LFS-tracked in the repo the URL names, and 404s otherwise. Everything QuantEcon/data-lectures publishes is plain git, so that host never resolves for it:

URL Result
raw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/mpd2020.xlsx 200
media.githubusercontent.com/media/QuantEcon/data-lectures/main/lectures/mpd2020.xlsx 404

Both hosts send access-control-allow-origin: *, so this is host routing, not CORS — a different failure from repoint rule 5, and unlike rule 5 it hits CPython consumers too.

This matters right now because the six high_dim_data datasets are LFS-tracked there, so this repo reads them from the media host today. When they land in data-lectures as plain git, a mechanical org/repo swap that preserves the host breaks every one of them.

Why here, and why a separate workflow

The check that would otherwise catch it is the data-audit dashboard in QuantEcon/data-lectures — but that workflow triggers on pushes to that repo, a weekly Monday cron, and PRs touching its paths. No event in this repo reaches it, so its detection lag after a bad repoint merges is up to seven days. This runs pre-merge, in the repo being changed.

grep -r over lectures/ also walks lectures/_static/**/*.ipynb. That matters: the audit deliberately excludes _static/ from its scan, and lectures/_config.yml excludes it from execution, so _static/lecture_specific/inequality/data.ipynb is invisible to every other mechanism. This guard is the only thing that sees it.

Scope and honesty about what it is

It matches zero lines today — verified, grep exits 1 in a clean tree — so it goes green on merge and is armed before the fold rather than landing alongside it.

It is a literal host-string check. It cannot see a wrong ref, a preserved source subdirectory, or a repoint that lands before the bytes do; those are asserted post-merge by the strict audit in QuantEcon/data-lectures#55. The two are complements.

And it is an alarm, not a gate: main's required_status_checks has contexts: [], so this will show as a failed check on the PR without blocking the merge. Adding it as a required context is a separate, deliberate decision.

The companion assertion — that no high_dim_data URL remains anywhere — matches 7 lines here today, so it belongs in the repoint PR itself, not this one.

🤖 Generated with Claude Code

A dataset URL on the wrong host fails in the reader's notebook, not in CI.
media.githubusercontent.com is the LFS *media* endpoint and routes per path,
serving a file only where that path is LFS-tracked in the repo the URL names.
Everything data-lectures publishes is plain git, so that host never resolves
for it — and the datasets folded in from high_dim_data are read from it
today, which means a mechanical org/repo swap that preserves the host breaks
every one of them.

Nothing in this repo would catch that. The data-audit dashboard that does
lives in QuantEcon/data-lectures and never runs on a pull request here — its
detection lag is up to seven days. This runs pre-merge, in the repo being
changed, and `grep -r` also walks lectures/_static/**/*.ipynb, which the
audit deliberately does not scan and this repo's build never executes.

Matches zero lines today (verified: exit 1), so it goes green on merge and is
armed before the fold rather than alongside it.

Gate 2 of QuantEcon/workspace-lectures#23 step 3. See QuantEcon/data-lectures
PLAN.md, repoint rule 6.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 9, 2026 22:57
@netlify

netlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Deploy Preview for taupe-gaufre-c4e660 ready!

Name Link
🔨 Latest commit e7e9478
🔍 Latest deploy log https://app.netlify.com/projects/taupe-gaufre-c4e660/deploys/6a7905cbe8abd4000843bb0c
😎 Deploy Preview https://deploy-preview-830--taupe-gaufre-c4e660.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

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.

Pull request overview

Adds a lightweight GitHub Actions workflow to proactively detect any lecture content that references QuantEcon/data-lectures via the Git LFS media host (media.githubusercontent.com), which would 404 for that repo and fail only at runtime in notebooks.

Changes:

  • Introduces a new workflow that greps lectures/ (including _static/**/*.ipynb) for media.githubusercontent.com/media/QuantEcon/data-lectures.
  • Emits a GitHub Actions error and fails the job when a match is found; otherwise prints an OK message.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

@github-actions
github-actions Bot temporarily deployed to pull request August 9, 2026 23:05 Inactive
@github-actions
github-actions Bot temporarily deployed to pull request August 9, 2026 23:10 Inactive
@mmcky
mmcky merged commit fdcf0b7 into main Aug 10, 2026
9 checks passed
@mmcky
mmcky deleted the ci/data-url-guard branch August 10, 2026 02:32
mmcky added a commit that referenced this pull request Aug 10, 2026
* CI: least-privilege token for the data URL guard

The job greps a checkout and writes nothing, but this repo's default
workflow permission is `write`, so it was receiving a token that could
also approve pull requests.

Raised by Copilot on the wasm twin, QuantEcon/lecture-wasm#58, which
carries the same one-line change; it left no inline comments on
#830, so this landed here unflagged.

Scoped to this workflow. cache.yml, ci.yml and collab.yml have the same
gap and are left alone — linkcheck.yml, publish.yml and
sync-translations-zh-cn.yml already scope theirs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

2 participants