From 3dd78e66c77a0ac13f8fa20a62d857cb51d01f5c Mon Sep 17 00:00:00 2001 From: Christopher Tauchen Date: Wed, 8 Jul 2026 10:52:18 +0100 Subject: [PATCH 1/2] docs-2977: add weekly link-check workflow Add .github/workflows/link-check-weekly.yml. It runs every Monday and on manual trigger. It builds the site, serves it, and runs the crawler. On failure it opens or updates a GitHub issue with the report, and uploads the full log as an artifact. It does not gate pull requests. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/link-check-weekly.yml | 81 +++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/link-check-weekly.yml diff --git a/.github/workflows/link-check-weekly.yml b/.github/workflows/link-check-weekly.yml new file mode 100644 index 0000000000..248f9e4f69 --- /dev/null +++ b/.github/workflows/link-check-weekly.yml @@ -0,0 +1,81 @@ +name: Weekly link check + +on: + # Weekly schedule: Monday at 07:00 UTC (after the llms.txt job at 06:00). + schedule: + - cron: '0 7 * * 1' + + # Manual trigger via GitHub UI + workflow_dispatch: + +permissions: + contents: read + issues: write + +jobs: + link-check: + name: Build, serve, and crawl the docs + runs-on: ubuntu-latest + timeout-minutes: 180 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Enable Corepack + run: corepack enable + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'yarn' + + - name: Build the site + run: make build + env: + NODE_OPTIONS: '--max-old-space-size=6000' + DOCUSAURUS_IGNORE_SSG_WARNINGS: 'true' + + - name: Install Playwright Chrome + run: yarn playwright install --with-deps chrome + + - name: Serve the site and run the link check + run: make test 2>&1 | tee link-check.log + env: + CI: 'true' + + - name: Upload the link-check log + if: always() + uses: actions/upload-artifact@v4 + with: + name: link-check-log + path: link-check.log + if-no-files-found: ignore + + - name: Open or update an issue on failure + if: failure() + env: + GH_TOKEN: ${{ github.token }} + run: | + TITLE="Weekly link check failed" + BODY_FILE=issue-body.md + RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + { + echo "The weekly link check found broken links or errors." + echo "" + echo "Run: ${RUN_URL}" + echo "" + echo "Last lines of the report (full log is in the run artifact \"link-check-log\"):" + echo "" + echo '```' + tail -n 200 link-check.log 2>/dev/null || echo "(no log captured)" + echo '```' + } > "$BODY_FILE" + NUM=$(gh issue list --repo "$GITHUB_REPOSITORY" --state open \ + --search "\"$TITLE\" in:title" --json number --jq '.[0].number') + if [ -n "$NUM" ]; then + gh issue comment "$NUM" --repo "$GITHUB_REPOSITORY" --body-file "$BODY_FILE" + else + gh issue create --repo "$GITHUB_REPOSITORY" --title "$TITLE" --body-file "$BODY_FILE" + fi From 1e01960de7bf54a03d61446bcd00a48baa8a7f49 Mon Sep 17 00:00:00 2001 From: Christopher Tauchen Date: Wed, 8 Jul 2026 12:11:56 +0100 Subject: [PATCH 2/2] docs-2977: create the issue on first failure Address Copilot review: jq '.[0].number' returns the string 'null' when no open issue matches, so the script took the comment branch and never created the first issue. Use '// empty' so NUM is empty and the create branch runs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/link-check-weekly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/link-check-weekly.yml b/.github/workflows/link-check-weekly.yml index 248f9e4f69..b8def5566b 100644 --- a/.github/workflows/link-check-weekly.yml +++ b/.github/workflows/link-check-weekly.yml @@ -73,7 +73,7 @@ jobs: echo '```' } > "$BODY_FILE" NUM=$(gh issue list --repo "$GITHUB_REPOSITORY" --state open \ - --search "\"$TITLE\" in:title" --json number --jq '.[0].number') + --search "\"$TITLE\" in:title" --json number --jq '.[0].number // empty') if [ -n "$NUM" ]; then gh issue comment "$NUM" --repo "$GITHUB_REPOSITORY" --body-file "$BODY_FILE" else