[PR #1404] [MERGED] PR-1: Release-prep safety net (link checking + publish guards + nightly link-rot) #12695

Closed
opened 2026-05-15 04:08:06 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/harvard-edge/cs249r_book/pull/1404
Author: @profvjreddi
Created: 4/19/2026
Status: Merged
Merged: 4/20/2026
Merged by: @profvjreddi

Base: devHead: release-prep/safety-net


📝 Commits (4)

  • 159005d ci(links): add Tier 1 pre-commit internal-link checker
  • a0333d5 ci(links): Tier 2 per-site Lychee validate-dev coverage
  • 92003cd ci(release): publish-live green gate + nightly link rot tracker
  • d239a90 fix(ci): drop --exclude-mail from Lychee args (removed in v0.21)

📊 Changes

24 files changed (+1556 additions, -69 deletions)

View changed files

📝 .github/workflows/book-publish-live.yml (+13 -0)
📝 .github/workflows/book-validate-dev.yml (+20 -1)
📝 .github/workflows/infra-link-check.yml (+89 -26)
.github/workflows/infra-link-rot-nightly.yml (+280 -0)
.github/workflows/infra-publish-guard.yml (+122 -0)
📝 .github/workflows/instructors-publish-live.yml (+9 -0)
📝 .github/workflows/instructors-validate-dev.yml (+11 -33)
📝 .github/workflows/kits-publish-live.yml (+10 -1)
📝 .github/workflows/kits-validate-dev.yml (+22 -2)
📝 .github/workflows/labs-publish-live.yml (+9 -0)
📝 .github/workflows/labs-validate-dev.yml (+21 -2)
📝 .github/workflows/mlsysim-publish-live.yml (+10 -1)
📝 .github/workflows/mlsysim-validate-dev.yml (+15 -0)
📝 .github/workflows/site-publish-live.yml (+9 -0)
.github/workflows/site-validate-dev.yml (+148 -0)
📝 .github/workflows/slides-publish-live.yml (+9 -0)
📝 .github/workflows/slides-validate-dev.yml (+21 -2)
📝 .github/workflows/staffml-publish-live.yml (+9 -0)
.github/workflows/staffml-validate-dev.yml (+239 -0)
📝 .github/workflows/tinytorch-publish-live.yml (+12 -0)

...and 4 more files

📄 Description

Summary

The first of five logical PRs that make up the staged-rollout foundation
for the new mlsysbook.ai ecosystem properties. This PR is the safety
net layer — three tiers of link checking plus a publish-guard so that
no *-publish-live workflow can deploy without a recent green
*-validate-dev run.

Nothing in this PR ships content; everything is plumbing.

What's in this PR

Tier 1 — pre-commit (instant, local). New
shared/scripts/check-internal-links.py runs against staged .md/.qmd
files only, validates internal links + anchors, skips fenced code
blocks and inline code (so TikZ snippets etc. don't false-positive),
and is wired into .pre-commit-config.yaml with an exclude list for
known legacy / auto-generated paths.

Tier 2 — per-subsite CI (every PR + every dev push). Generalized
.github/workflows/infra-link-check.yml to take site-specific args
(include_pattern, lycheeignore_path, accept_status,
fail_on_broken). Every *-validate-dev.yml now invokes it as a
check-links job. Created site-validate-dev.yml and
staffml-validate-dev.yml for the two subsites that lacked validate
workflows. Universal exclusions live in shared/config/.lycheeignore.

Publish guard. New .github/workflows/infra-publish-guard.yml
blocks every *-publish-live.yml from running unless the latest
*-validate-dev.yml run on dev is green and recent (configurable
max_age_minutes, default 60). Wired as the first job of each publish
workflow.

Tier 3 — nightly link-rot tracker. New
.github/workflows/infra-link-rot-nightly.yml sweeps every subsite at
04:30 UTC and aggregates findings into a single sticky GitHub issue
(label link-rot). Each run replaces the issue body and appends a
comment, so the issue is the always-current dashboard.

Risk surface

Tier 1 + Tier 2 are non-blocking by default (fail_on_broken: false)
so existing baseline failures don't immediately gate merges; we can
flip the flag per-subsite as backlogs are cleared. Publish guards
CAN block
on green dev — that's the whole point.

Verification done locally

  • YAML schema validation on every modified/created workflow.
  • python3 .github/scripts/check_workflow_fork_safety.py on all five
    new/modified workflows — clean.
  • check-internal-links.py exercised against a real .qmd file.
  • Pre-commit hook smoke-tested on the script itself (correctly skips
    non-md files).

Verification still pending in this PR's CI

  • The reusable workflows running on a real PR (this one). Specifically
    watching whether:
    • Lychee accepts shared/config/.lycheeignore patterns.
    • The per-site include_pattern globs match what we think they
      match.
    • The publish-guard's GitHub-API query syntax actually works (it's
      only invoked on workflow_dispatch, so this PR exercises everything
      EXCEPT the guard — that gets exercised the first time someone
      clicks "Run" on a *-publish-live workflow).

What this PR does NOT change

  • Nothing under book/, tinytorch/, labs/, kits/, etc. The
    source content is untouched.
  • No publish workflow's deploy logic — only added a guard job before
    existing logic runs.
  • No release-version state.

Test plan

  • CI: book-validate-dev runs to completion, including the new
    check-links job.
  • CI: tinytorch-validate-dev, labs-validate-dev,
    kits-validate-dev, mlsysim-validate-dev all pass with
    check-links.
  • CI: site-validate-dev and staffml-validate-dev (newly
    created) at least start and report.
  • Pre-commit hook installs and runs on a sample staged .qmd
    change without hanging.
  • Read-through of the link-check job summary in Actions UI to
    confirm Lychee output is interpretable.

Followup

Four more PRs on the existing release-prep work. Tracked in
RELEASE-PREP.md (not in this PR — comes with PR-3).


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/harvard-edge/cs249r_book/pull/1404 **Author:** [@profvjreddi](https://github.com/profvjreddi) **Created:** 4/19/2026 **Status:** ✅ Merged **Merged:** 4/20/2026 **Merged by:** [@profvjreddi](https://github.com/profvjreddi) **Base:** `dev` ← **Head:** `release-prep/safety-net` --- ### 📝 Commits (4) - [`159005d`](https://github.com/harvard-edge/cs249r_book/commit/159005dcd753d3c329dbcdd2993cccd0fe1966f8) ci(links): add Tier 1 pre-commit internal-link checker - [`a0333d5`](https://github.com/harvard-edge/cs249r_book/commit/a0333d54c266da394eb01e5e7d35bc3409e63407) ci(links): Tier 2 per-site Lychee validate-dev coverage - [`92003cd`](https://github.com/harvard-edge/cs249r_book/commit/92003cd5bde7174fbe776cc7fdc332549d09baac) ci(release): publish-live green gate + nightly link rot tracker - [`d239a90`](https://github.com/harvard-edge/cs249r_book/commit/d239a905b83f5c8eeda8897e365ce68e4a5f6136) fix(ci): drop --exclude-mail from Lychee args (removed in v0.21) ### 📊 Changes **24 files changed** (+1556 additions, -69 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/book-publish-live.yml` (+13 -0) 📝 `.github/workflows/book-validate-dev.yml` (+20 -1) 📝 `.github/workflows/infra-link-check.yml` (+89 -26) ➕ `.github/workflows/infra-link-rot-nightly.yml` (+280 -0) ➕ `.github/workflows/infra-publish-guard.yml` (+122 -0) 📝 `.github/workflows/instructors-publish-live.yml` (+9 -0) 📝 `.github/workflows/instructors-validate-dev.yml` (+11 -33) 📝 `.github/workflows/kits-publish-live.yml` (+10 -1) 📝 `.github/workflows/kits-validate-dev.yml` (+22 -2) 📝 `.github/workflows/labs-publish-live.yml` (+9 -0) 📝 `.github/workflows/labs-validate-dev.yml` (+21 -2) 📝 `.github/workflows/mlsysim-publish-live.yml` (+10 -1) 📝 `.github/workflows/mlsysim-validate-dev.yml` (+15 -0) 📝 `.github/workflows/site-publish-live.yml` (+9 -0) ➕ `.github/workflows/site-validate-dev.yml` (+148 -0) 📝 `.github/workflows/slides-publish-live.yml` (+9 -0) 📝 `.github/workflows/slides-validate-dev.yml` (+21 -2) 📝 `.github/workflows/staffml-publish-live.yml` (+9 -0) ➕ `.github/workflows/staffml-validate-dev.yml` (+239 -0) 📝 `.github/workflows/tinytorch-publish-live.yml` (+12 -0) _...and 4 more files_ </details> ### 📄 Description ## Summary The first of five logical PRs that make up the staged-rollout foundation for the new mlsysbook.ai ecosystem properties. This PR is the safety net layer — three tiers of link checking plus a publish-guard so that no `*-publish-live` workflow can deploy without a recent green `*-validate-dev` run. Nothing in this PR ships content; everything is plumbing. ### What's in this PR **Tier 1 — pre-commit (instant, local).** New `shared/scripts/check-internal-links.py` runs against staged `.md`/`.qmd` files only, validates internal links + anchors, skips fenced code blocks and inline code (so TikZ snippets etc. don't false-positive), and is wired into `.pre-commit-config.yaml` with an `exclude` list for known legacy / auto-generated paths. **Tier 2 — per-subsite CI (every PR + every dev push).** Generalized `.github/workflows/infra-link-check.yml` to take site-specific args (`include_pattern`, `lycheeignore_path`, `accept_status`, `fail_on_broken`). Every `*-validate-dev.yml` now invokes it as a `check-links` job. Created `site-validate-dev.yml` and `staffml-validate-dev.yml` for the two subsites that lacked validate workflows. Universal exclusions live in `shared/config/.lycheeignore`. **Publish guard.** New `.github/workflows/infra-publish-guard.yml` blocks every `*-publish-live.yml` from running unless the latest `*-validate-dev.yml` run on `dev` is green and recent (configurable `max_age_minutes`, default 60). Wired as the first job of each publish workflow. **Tier 3 — nightly link-rot tracker.** New `.github/workflows/infra-link-rot-nightly.yml` sweeps every subsite at 04:30 UTC and aggregates findings into a single sticky GitHub issue (label `link-rot`). Each run replaces the issue body and appends a comment, so the issue is the always-current dashboard. ### Risk surface Tier 1 + Tier 2 are non-blocking by default (`fail_on_broken: false`) so existing baseline failures don't immediately gate merges; we can flip the flag per-subsite as backlogs are cleared. **Publish guards CAN block** on green dev — that's the whole point. ### Verification done locally - YAML schema validation on every modified/created workflow. - `python3 .github/scripts/check_workflow_fork_safety.py` on all five new/modified workflows — clean. - `check-internal-links.py` exercised against a real `.qmd` file. - Pre-commit hook smoke-tested on the script itself (correctly skips non-md files). ### Verification still pending in this PR's CI - The reusable workflows running on a real PR (this one). Specifically watching whether: - Lychee accepts `shared/config/.lycheeignore` patterns. - The per-site `include_pattern` globs match what we think they match. - The publish-guard's GitHub-API query syntax actually works (it's only invoked on workflow_dispatch, so this PR exercises everything EXCEPT the guard — that gets exercised the first time someone clicks "Run" on a `*-publish-live` workflow). ### What this PR does NOT change - Nothing under `book/`, `tinytorch/`, `labs/`, `kits/`, etc. The source content is untouched. - No publish workflow's deploy logic — only added a `guard` job before existing logic runs. - No release-version state. ### Test plan - [ ] CI: `book-validate-dev` runs to completion, including the new `check-links` job. - [ ] CI: `tinytorch-validate-dev`, `labs-validate-dev`, `kits-validate-dev`, `mlsysim-validate-dev` all pass with check-links. - [ ] CI: `site-validate-dev` and `staffml-validate-dev` (newly created) at least start and report. - [ ] Pre-commit hook installs and runs on a sample staged `.qmd` change without hanging. - [ ] Read-through of the link-check job summary in Actions UI to confirm Lychee output is interpretable. ### Followup Four more PRs on the existing release-prep work. Tracked in `RELEASE-PREP.md` (not in this PR — comes with PR-3). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-15 04:08:06 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/cs249r_book#12695