From 4839f5955b5760b7b8d6ee8394d4f3d8ce49e136 Mon Sep 17 00:00:00 2001 From: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> Date: Thu, 10 Sep 2026 08:46:17 +1200 Subject: [PATCH 1/3] ci: validate newly added documentation links Signed-off-by: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> --- .github/workflows/pr-preview-links.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/pr-preview-links.yml b/.github/workflows/pr-preview-links.yml index 291ec3ad2b..18c6960f67 100644 --- a/.github/workflows/pr-preview-links.yml +++ b/.github/workflows/pr-preview-links.yml @@ -17,6 +17,21 @@ jobs: documentation-links: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Extract links added by the pull request + run: | + git diff --unified=0 "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" -- '*.md' '*.rst' \ + | grep -Eo 'https?://[^ )>]+' | sort -u > added-links.txt || true + + - name: Check links added by the pull request + uses: lycheeverse/lychee-action@v2 + with: + args: --verbose --no-progress --exclude-mail added-links.txt + fail: true + - uses: readthedocs/actions/preview@b8bba1484329bda1a3abe986df7ebc80a8950333 # v1.5 with: project-slug: "python-packaging-user-guide" From 2966f6bd761c3cb59ff1096eaf8f544b474e8211 Mon Sep 17 00:00:00 2001 From: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> Date: Thu, 10 Sep 2026 10:24:33 +1200 Subject: [PATCH 2/3] fix: validate added pull request links safely Signed-off-by: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> --- .github/workflows/pr-preview-links.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-preview-links.yml b/.github/workflows/pr-preview-links.yml index 18c6960f67..ed8131a74b 100644 --- a/.github/workflows/pr-preview-links.yml +++ b/.github/workflows/pr-preview-links.yml @@ -4,6 +4,8 @@ on: pull_request_target: types: - opened + - reopened + - synchronize permissions: contents: read @@ -17,17 +19,19 @@ jobs: documentation-links: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - fetch-depth: 0 + fetch-depth: 2 + ref: refs/pull/${{ github.event.pull_request.number }}/merge - name: Extract links added by the pull request run: | - git diff --unified=0 "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" -- '*.md' '*.rst' \ + git diff --unified=0 HEAD^1 HEAD^2 -- '*.md' '*.rst' \ + | grep '^+' | grep -v '^+++' \ | grep -Eo 'https?://[^ )>]+' | sort -u > added-links.txt || true - name: Check links added by the pull request - uses: lycheeverse/lychee-action@v2 + uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 with: args: --verbose --no-progress --exclude-mail added-links.txt fail: true From a118a58127d3a36eaf9bbe3de26218acfd1f4365 Mon Sep 17 00:00:00 2001 From: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> Date: Thu, 10 Sep 2026 18:29:28 +1200 Subject: [PATCH 3/3] ci: isolate new-link checks from privileged previews Signed-off-by: John Finnerty <297514060+johnfinnerty-nz@users.noreply.github.com> --- .github/workflows/pr-linkcheck.yml | 59 ++++++++++++++++++++++++++ .github/workflows/pr-preview-links.yml | 19 --------- 2 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/pr-linkcheck.yml diff --git a/.github/workflows/pr-linkcheck.yml b/.github/workflows/pr-linkcheck.yml new file mode 100644 index 0000000000..8f474018a8 --- /dev/null +++ b/.github/workflows/pr-linkcheck.yml @@ -0,0 +1,59 @@ +name: Check new documentation links + +on: + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + new-links: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 2 + persist-credentials: false + + - name: Collect added documentation lines + shell: python + run: | + import os + from pathlib import Path + import subprocess + + # Compare the merge result with its base parent, not the PR parent. + diff = subprocess.check_output( + ["git", "diff", "--no-ext-diff", "--no-textconv", "--unified=0", + "HEAD^1", "HEAD", "--", "*.md", "*.rst"], + text=True, encoding="utf-8", + ) + added = [] + in_hunk = False + for line in diff.splitlines(): + if line.startswith("diff --git "): + in_hunk = False + elif line.startswith("@@ "): + in_hunk = True + elif in_hunk and line.startswith("+"): + added.append(line[1:]) + + # Never load configuration or write results inside the PR checkout. + directory = Path(os.environ["RUNNER_TEMP"]) / "new-links" + directory.mkdir() + (directory / "added-lines.txt").write_text("\n".join(added), encoding="utf-8") + (directory / "lychee.toml").write_text("", encoding="utf-8") + + - name: Check links in added lines + uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 + with: + workingDirectory: ${{ runner.temp }}/new-links + args: --config lychee.toml --verbose --no-progress --scheme http --scheme https --exclude-all-private added-lines.txt + token: "" + fail: true + failIfEmpty: false diff --git a/.github/workflows/pr-preview-links.yml b/.github/workflows/pr-preview-links.yml index ed8131a74b..291ec3ad2b 100644 --- a/.github/workflows/pr-preview-links.yml +++ b/.github/workflows/pr-preview-links.yml @@ -4,8 +4,6 @@ on: pull_request_target: types: - opened - - reopened - - synchronize permissions: contents: read @@ -19,23 +17,6 @@ jobs: documentation-links: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 2 - ref: refs/pull/${{ github.event.pull_request.number }}/merge - - - name: Extract links added by the pull request - run: | - git diff --unified=0 HEAD^1 HEAD^2 -- '*.md' '*.rst' \ - | grep '^+' | grep -v '^+++' \ - | grep -Eo 'https?://[^ )>]+' | sort -u > added-links.txt || true - - - name: Check links added by the pull request - uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 - with: - args: --verbose --no-progress --exclude-mail added-links.txt - fail: true - - uses: readthedocs/actions/preview@b8bba1484329bda1a3abe986df7ebc80a8950333 # v1.5 with: project-slug: "python-packaging-user-guide"