Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 29 additions & 36 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,46 +148,39 @@ jobs:
links:
name: every external link resolves
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
# linkcheck (go-fleettools/fleettools, pinned): retries with exponential
# backoff that honours Retry-After, github.com repo and path links decided
# through the REST API rather than the HTML page, a DEAD link told apart
# from a FLAKY host. It already skips img.shields.io, example domains
# and localhost.
#
# --skip: this site's own pages exist only once this workflow has
# deployed them (the offline check above proves every link inside the
# site), and this repository's own files (figures/), on a pull request
# that adds them, are not on main yet.
#
# THE ONE DELIBERATE EXCEPTION to "no secret on a command line or in the
# environment": the job's ephemeral, read-only github.token (permissions:
# contents: read, for this job alone) reaches the tool as a 0600 file in
# RUNNER_TEMP, written by the shell builtin printf (no process argument,
# no environment variable) and removed on exit. It is sent to
# api.github.com only and never printed.
- name: Check
run: |
set -uo pipefail
# The character class matters: an extractor stopping only at ) and "
# carries a closing > or < into the request.
urls=$(grep -rhoE 'https?://[^)">< [:space:]]+' content/ README.md | sed -E 's/[.,`]+$//' | sort -u)
test -n "$urls" || { echo "::error::no links found; are the pages still there?"; exit 1; }
echo "checking $(printf '%s\n' "$urls" | wc -l) distinct URLs"
fail=0
while read -r u; do
case "$u" in
# Renders whatever it is asked for; proves nothing.
*img.shields.io*) continue ;;
# Documented placeholders, not hosts.
*example.com*|*example.org*|*example.net*|*localhost*|*127.0.0.1*|*.invalid*) continue ;;
# This site's own pages: they exist only once this workflow
# has deployed them, and the offline check above already
# proves every link inside the site.
*go-plot.github.io/docs*) continue ;;
# This repository's own files (figures/): on a pull request
# that adds them, they are not on main yet.
*github.com/go-plot/docs/*) continue ;;
esac
# Three attempts: one is a flake detector rather than a link
# checker, and a lane that fails at random gets ignored.
code=000
for _ in 1 2 3; do
code=$(curl -sS -o /dev/null -w '%{http_code}' -L --max-time 25 "$u" 2>/dev/null) || true
code=${code:-000}
case "$code" in 2*|3*) break ;; esac
sleep 3
done
case "$code" in
2*|3*) printf ' ok %s %s\n' "$code" "$u" ;;
*) printf ' FAIL %s %s\n' "$code" "$u"; fail=1 ;;
esac
done <<< "$urls"
test "$fail" -eq 0 || { echo "::error::at least one link does not resolve"; exit 1; }
umask 077
token="${RUNNER_TEMP}/linkcheck-token"
trap 'rm -f "${token}"' EXIT
printf '%s' '${{ github.token }}' > "${token}"
go run github.com/go-fleettools/fleettools/cmd/linkcheck@v0.74.0 \
--token-file "${token}" \
--skip go-plot.github.io/docs \
--skip github.com/go-plot/docs/ \
content/ README.md

deploy:
# Only main publishes. A pull request stops after build above: it has no
Expand Down
Loading