-
-
Notifications
You must be signed in to change notification settings - Fork 8
199 lines (192 loc) 路 8.91 KB
/
Copy pathdocs.yaml
File metadata and controls
199 lines (192 loc) 路 8.91 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
"on":
workflow_call:
workflow_dispatch:
push:
branches:
- main
# Only rebuild docs when something the docs actually depend on changes:
# Sphinx sources, Python (autodoc), pyproject (project metadata + docs
# group deps), `uv.lock` (resolved env), the docs workflow itself, and
# the top-level Markdown / data files that the docs include or link to.
paths:
- .github/workflows/docs.yaml
- changelog.md
- citation.cff
- docs/**
- pyproject.toml
- readme.md
- uv.lock
- "**/*.py"
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ !startsWith(github.event.head_commit.message, '[changelog] Release') }}
# Supply-chain cooldown: no package published within the window can be resolved by
# any command in this workflow. Set here, not per command, so it also covers the
# `metadata` bootstrap and any step added later; a workflow-level `env:` cannot
# reference `needs`, so the window is a literal kept equal to `[tool.repomatic]
# minimum-release-age`. repomatic's own test suite enforces that upstream; a
# synced copy is kept in step by hand. Deliberate bypasses are per-package CLI
# flags (`--exclude-newer-package`, `--min-release-age-exclude`).
# See claude.md for the rationale.
env:
NPM_CONFIG_MIN_RELEASE_AGE: 7
UV_EXCLUDE_NEWER: "1 week"
jobs:
metadata:
name: 馃К Project metadata
runs-on: ubuntu-slim
outputs:
metadata: ${{ steps.metadata.outputs.metadata }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.1"
- name: Run repomatic metadata
id: metadata
run: >
uv --no-progress run --frozen -- repomatic metadata
--format github-json --output "$GITHUB_OUTPUT"
is_python_project is_sphinx doc_files
deploy-docs:
name: 馃摉 Deploy Sphinx doc
needs:
- metadata
if: >-
fromJSON(needs.metadata.outputs.metadata).is_python_project
&& fromJSON(needs.metadata.outputs.metadata).is_sphinx
runs-on: ubuntu-slim
permissions:
id-token: write
pages: write
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.1"
- name: Install Graphviz and mandoc
# Graphviz: backs the sphinx.ext.graphviz directive.
# See: https://www.sphinx-doc.org/en/master/usage/extensions/graphviz.html
# mandoc: renders the roff `.1` files written by the
# click_extra.sphinx.manpages hook into the browser-viewable
# `.html` siblings the docs site links to. Skipped silently when
# the hook is not opted in.
# fonts-liberation is graphviz's only Recommends (via the transitional
# fonts-liberation2), and "ubuntu-slim" does not ship it: naming it here
# keeps diagram labels rendering exactly as before while
# --no-install-recommends stops apt pulling anything else unasked.
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends \
fonts-liberation graphviz mandoc
- name: Build documentation
# Install --all-extras so documentation can covers all features of the project, including the optional ones.
run: uv --no-progress run --frozen --all-extras --group docs -- sphinx-build -b html ./docs ./docs/_build
- name: Upload artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ./docs/_build
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
check-broken-links:
name: 馃挃 Check broken links
needs:
- metadata
permissions:
issues: write
# Skip all PRs as we won't have permissions to create issues.
# Skip the prepare-release branch as it contains URLs pointing to tags that don't exist yet.
# Skip any push containing a post-release bump commit as a precautionary measure.
if: >
github.event_name != 'pull_request'
&& github.ref != 'refs/heads/prepare-release'
&& (! contains(toJSON(github.event.commits.*.message), '[changelog] Post-release bump'))
&& (fromJSON(needs.metadata.outputs.metadata).doc_files
|| (fromJSON(needs.metadata.outputs.metadata).is_python_project
&& fromJSON(needs.metadata.outputs.metadata).is_sphinx))
# Not ubuntu-slim: its 15-minute job cap kills the whole crawl, whose
# runtime is dominated by remote servers' throttling and grows with every
# release (each adds a dozen URLs to the binaries page). Measured runs
# already peaked past the cap.
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.1"
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.cache/repomatic/bin
key: >-
repomatic-${{ runner.os }}-${{ runner.arch }}-lychee-${{
github.job_workflow_sha || hashFiles('repomatic/tool_registry.py') }}
restore-keys: |
repomatic-${{ runner.os }}-${{ runner.arch }}-lychee-
- name: Install Graphviz
if: >
fromJSON(needs.metadata.outputs.metadata).is_python_project
&& fromJSON(needs.metadata.outputs.metadata).is_sphinx
# So we can use the sphinx.ext.graphviz plugin.
# See: https://www.sphinx-doc.org/en/master/usage/extensions/graphviz.html
# fonts-liberation named explicitly: see the deploy-docs job above.
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends fonts-liberation graphviz
- name: Run Sphinx linkcheck
if: >
fromJSON(needs.metadata.outputs.metadata).is_python_project
&& fromJSON(needs.metadata.outputs.metadata).is_sphinx
# Do not use -W: we parse output.json directly instead of relying on exit codes.
# GitHub throttles anonymous crawls to ~1 request/minute, enough to blow the
# "ubuntu-slim" job budget on link-heavy repos (the runner kills the whole job,
# bypassing continue-on-error). Exposing the token lets a repo's conf.py
# authenticate its github.com checks via linkcheck_request_headers.
env:
GITHUB_TOKEN: ${{ github.token }}
run: >
uv --no-progress run --frozen --all-extras --group docs --
sphinx-build -b linkcheck ./docs ./docs/_linkcheck
continue-on-error: true
- name: Run lychee
if: fromJSON(needs.metadata.outputs.metadata).doc_files
id: lychee_run
env:
GITHUB_TOKEN: ${{ github.token }}
DOC_FILES: ${{ fromJSON(needs.metadata.outputs.metadata).doc_files }}
# xargs splits the list and does nothing else. It must not be what launches
# lychee: xargs answers any child status in 1..125 with 123 of its own, so
# lychee's 2 ("broken links found") reaches `repomatic broken-links` looking
# exactly like a crash, and a real report gets filed as a tool failure and
# dropped. Batching is the second casualty, since each batch writes the same
# --output path and only the last one survives. Handing the split to `printf
# '%s\0'` keeps xargs on an operation that cannot fail, and the single
# invocation below then carries back both the status and the whole report.
#
# The split cannot be `eval "set -- ${DOC_FILES}"`: metadata wraps each path
# in bare double quotes with no escaping, so a filename containing $(...)
# would execute. xargs expands neither that nor backticks.
run: |
exit_code=0
files=()
while IFS= read -r -d '' f; do files+=("$f"); done \
< <(echo "${DOC_FILES}" | xargs printf '%s\0')
uv --no-progress run --frozen -- repomatic run lychee -- \
--format markdown --output ./lychee/out.md \
--hidden --suggest --no-progress --include-fragments --exclude-all-private \
"${files[@]}" \
|| exit_code=$?
echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
- name: Manage broken links issue
env:
GH_TOKEN: ${{ github.token }}
LYCHEE_EXIT_CODE: ${{ steps.lychee_run.outputs.exit_code }}
run: |
uv --no-progress run --frozen -- repomatic broken-links \
${LYCHEE_EXIT_CODE:+--lychee-exit-code "${LYCHEE_EXIT_CODE}"}