Repository navigation
199 lines (181 loc) · 7.89 KB
/
Copy pathdocs.yml
File metadata and controls
199 lines (181 loc) · 7.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
name: docs
# Every documentation version is a separate Hugo build, published under
# https://go-ndarray.github.io/docs/<version>/ on the gh-pages branch, where
# <version> is the minor version of ndarray the pages describe
# (params.ndarray.version in hugo.yaml: v0.9.1 -> 0.9). main is that
# version's source: each push to main replaces /docs/<version>/, and
# /docs/latest/ follows the newest. Pull requests build and check, and publish
# nothing.
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
# The build needs nothing beyond the source. Write access to the repository
# is granted to the deploy job alone, below, so a pull request build cannot
# push to gh-pages.
permissions:
contents: read
env:
HUGO_VERSION: "0.167.0"
# sha256 of hugo_${HUGO_VERSION}_linux-amd64.tar.gz, from the release's checksums.txt.
HUGO_SHA256: "4d84519b9f619e6d4c3fb45a50157abeabeb724f859c60605f44c23def6e1169"
DOCS_URL: "https://go-ndarray.github.io/docs"
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# themes/hextra (the tannevaled/hextra fork, pinned to a release tag)
# and branding (go-ndarray/brand) are submodules.
submodules: recursive
# The whole history: each page's creation and modification come from git.
fetch-depth: 0
- name: Install Hugo ${{ env.HUGO_VERSION }}
run: |
curl -fsSL -o /tmp/hugo.tar.gz \
"https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
echo "${HUGO_SHA256} /tmp/hugo.tar.gz" | sha256sum -c -
sudo tar -xzf /tmp/hugo.tar.gz -C /usr/local/bin hugo
hugo version
# The version label is ndarray's minor version, read from hugo.yaml,
# and it is the last segment of baseURL: the version selector reads it there.
- name: Version
id: version
run: |
ndarray=$(hugo config --format json | jq -r '.params.ndarray.version')
version=$(printf '%s\n' "${ndarray}" | sed -nE 's/^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/\1.\2/p')
if [ -z "${version}" ]; then
echo "::error::params.ndarray.version in hugo.yaml is \"${ndarray}\", not vMAJOR.MINOR.PATCH"
exit 1
fi
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "ndarray ${ndarray}: documentation version ${version}"
# Each page's creation (first commit, followed across renames) and its
# author, for the page history at its foot (params.page.history).
- name: Page history
run: |
mkdir -p data
sh themes/hextra/scripts/page-history.sh > data/pagehistory.json
# --panicOnWarning: a deprecated setting or a template warning fails the
# build rather than scrolling by. A broken {{< relref >}} is an error.
- name: Build
env:
HUGO_ENVIRONMENT: production
run: >-
hugo --gc --minify --panicOnWarning --printPathWarnings
--baseURL "${DOCS_URL}/${{ steps.version.outputs.version }}/"
# Internal links and anchors, offline, with the site laid out under
# /docs/<version>/ as it is served.
- name: Lay out the site for the link check
run: |
mkdir -p _check/docs
cp -R public "_check/docs/${{ steps.version.outputs.version }}"
- name: Check links
uses: lycheeverse/lychee-action@v2
with:
args: >-
--offline --no-progress --include-fragments
--index-files index.html
--root-dir ${{ github.workspace }}/_check
'_check/docs/**/*.html'
fail: true
- uses: actions/upload-artifact@v7
with:
name: site
path: public
retention-days: 7
# The offline check above proves the site's own links and anchors. An
# https:// URL is text to it: this job fetches each one the pages name.
links:
name: every external link resolves
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- 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 ;;
esac
# github.com answers curl's blob pages with 503 most of the time
# (7 of 8 on 2026-10-10, all 3 attempts on every run), while the
# raw host answers 200 for a file and 404 for a missing one. A blob
# link claims "this file exists at this ref", so ask the raw host.
probe=$u
case "$u" in
https://github.com/*/*/blob/*)
probe=https://raw.githubusercontent.com/$(printf '%s' "${u#https://github.com/}" | sed -E 's#^([^/]+/[^/]+)/blob/#\1/#; s/[?#].*$//') ;;
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 "$probe" 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; }
deploy:
# Only main publishes. A pull request stops after build above: it has no
# business pushing to gh-pages.
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
needs: build
# Never two deploys at once: both would push gh-pages and the second would
# be rejected. cancel-in-progress stays false -- killing a publish half way
# through is worse than making it wait.
concurrency:
group: gh-pages-deploy
cancel-in-progress: false
runs-on: ubuntu-latest
permissions:
contents: write
steps:
# The publishing script, from the commit being published.
- uses: actions/checkout@v7
with:
path: source
# The published site. Only the version being built is replaced; every
# other version (the MkDocs-built 0.1 and 0.2) stays as it is.
- uses: actions/checkout@v7
with:
ref: gh-pages
path: gh-pages
- uses: actions/download-artifact@v8
with:
name: site
path: site
- name: Publish ${{ needs.build.outputs.version }}
run: source/scripts/publish-version.sh "${{ needs.build.outputs.version }}" site gh-pages
- name: Push gh-pages
working-directory: gh-pages
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "nothing changed"
exit 0
fi
git commit -q -m "Deployed ${GITHUB_SHA::7} to ${{ needs.build.outputs.version }} with Hugo ${HUGO_VERSION}"
git push origin HEAD:gh-pages