Repository navigation
226 lines (212 loc) · 8.5 KB
/
Copy pathdocs.yml
File metadata and controls
226 lines (212 loc) · 8.5 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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
name: Docs
on:
push:
branches: ["main", "claude/**"]
paths:
- "docs/**"
- "js/**"
- "python/**"
- "src/**"
- "Cargo.lock"
- "Cargo.toml"
- "hatch_build.py"
- "pyproject.toml"
- "scripts/verify_docs_quickstart.py"
- ".pre-commit-config.yaml"
- ".github/workflows/docs.yml"
pull_request:
paths:
- "docs/**"
- "js/**"
- "python/**"
- "src/**"
- "Cargo.lock"
- "Cargo.toml"
- "hatch_build.py"
- "pyproject.toml"
- "scripts/verify_docs_quickstart.py"
- ".pre-commit-config.yaml"
- ".github/workflows/docs.yml"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: docs-${{ github.ref }}
cancel-in-progress: true
jobs:
quality:
name: Docs tests and lint
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history and tags: the distribution version is derived
# from the latest `v*` tag, and a shallow clone has none.
fetch-depth: 0
- uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: "3.12"
enable-cache: true
cache-dependency-glob: docs/app/uv.lock
# `uv sync` builds the editable xy dependency, whose hatch hook builds the
# render client from source (generated, not committed; §33). The docs
# tests build real reflex_xy components, which link that client out of the
# installed xy package. Pin Node so the build uses a vite-compatible one.
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install docs dependencies
run: uv sync --project docs/app --frozen --group dev
- name: Run docs tests
run: uv run --project docs/app --no-sync pytest docs/app/tests -v
- name: Run public docs quickstart against the checkout
run: uv run --project docs/app --no-sync python scripts/verify_docs_quickstart.py
- name: Run docs quality hooks
run: |
uv run --project docs/app --no-sync pre-commit run ruff-format --all-files
uv run --project docs/app --no-sync pre-commit run ruff-check --all-files
uv run --project docs/app --no-sync pre-commit run docs-app-codespell --all-files
production:
name: Production docs (Python ${{ matrix.python-version }})
needs: [quality]
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history and tags: the distribution version is derived
# from the latest `v*` tag, and a shallow clone has none.
fetch-depth: 0
- uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-dependency-glob: docs/app/uv.lock
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install docs dependencies
run: uv sync --project docs/app --frozen --group dev
- name: Initialize docs frontend
working-directory: docs/app
env:
REFLEX_TELEMETRY_ENABLED: "false"
run: uv run --no-sync reflex init
- name: Install Chromium for the production-DOM accessibility check
if: matrix.python-version == '3.12'
working-directory: docs/app
run: uv run --no-sync playwright install --with-deps chromium
- name: Run production docs and check the public route
working-directory: docs/app
shell: bash
env:
DOCS_PYTHON_VERSION: ${{ matrix.python-version }}
REFLEX_TELEMETRY_ENABLED: "false"
run: |
set -euo pipefail
server_log="$RUNNER_TEMP/xy-docs.log"
response="$RUNNER_TEMP/xy-docs-index.html"
nested_response="$RUNNER_TEMP/xy-docs-data.html"
stage="starting the production server"
# Every failure below is otherwise invisible in CI ("exit code 1" and
# nothing else), so dump the server log and the fetched responses on
# any non-zero exit — a local run has these on the terminal, CI does not.
dump_file() {
local label="$1" path="$2" limit="${3:-400}"
echo "::group::${label} (${path})"
if [[ -s "$path" ]]; then
tail -n "$limit" "$path" | sed 's/^::/:: /'
elif [[ -e "$path" ]]; then
echo "(file is empty)"
else
echo "(file was never created)"
fi
echo "::endgroup::"
}
dump_diagnostics() {
echo "XY docs production check failed while ${stage}"
dump_file "reflex server log" "$server_log" 2000
dump_file "response: /docs/xy/" "$response"
dump_file "response: /docs/xy/core-concepts/data/" "$nested_response"
echo "::group::listening sockets"
ss -ltnp 2>/dev/null || netstat -ltnp 2>/dev/null || echo "(no socket tool)"
echo "::endgroup::"
}
setsid uv run --no-sync reflex run --env prod --loglevel debug >"$server_log" 2>&1 &
server_pid=$!
cleanup() {
local status=$?
trap - EXIT INT TERM
if (( status != 0 )); then
dump_diagnostics || true
fi
kill -TERM -- "-$server_pid" 2>/dev/null || true
for _ in {1..10}; do
kill -0 "$server_pid" 2>/dev/null || break
sleep 1
done
kill -KILL -- "-$server_pid" 2>/dev/null || true
wait "$server_pid" 2>/dev/null || true
exit "$status"
}
trap cleanup EXIT
trap 'exit 130' INT TERM
stage="waiting for http://127.0.0.1:3000/docs/xy/ to serve"
deadline=$((SECONDS + 300))
while (( SECONDS < deadline )); do
if ! kill -0 "$server_pid" 2>/dev/null; then
stage="waiting for the server (it exited early)"
exit 1
fi
if curl --fail --location --silent \
--connect-timeout 2 --max-time 10 \
http://127.0.0.1:3000/docs/xy/ --output "$response"; then
test -s "$response"
break
fi
sleep 2
done
if [[ ! -s "$response" ]]; then
echo "XY docs did not become ready within 300 seconds"
exit 1
fi
stage="fetching /docs/xy/core-concepts/data/"
curl --fail --location --silent \
--connect-timeout 2 --max-time 10 \
http://127.0.0.1:3000/docs/xy/core-concepts/data/ \
--output "$nested_response"
stage="checking the title of /docs/xy/core-concepts/data/"
grep -Fq '<title>Data and Columns · XY</title>' "$nested_response"
if [[ "$DOCS_PYTHON_VERSION" == "3.12" ]]; then
stage="running the production-DOM accessibility checks"
XY_DOCS_BASE_URL=http://127.0.0.1:3000/docs/xy/ \
uv run --no-sync pytest \
tests/test_code_copy.py::test_production_copy_buttons_have_accessible_names \
tests/test_code_copy.py::test_production_copy_button_stays_icon_only \
-v
fi
stage="scanning the server log for runtime errors"
if grep -Eiq "traceback|uncaught|unhandled|fatal error" "$server_log"; then
echo "XY docs emitted a production runtime error"
exit 1
fi
- name: Validate Markdown links against the generated sitemap
working-directory: docs/app
run: |
uv run --no-sync pytest --runxfail \
tests/test_docs_site.py::test_xy_markdown_docs_links_match_exported_sitemap \
-v
- name: Validate generated sitemap
working-directory: docs/app
run: uv run --no-sync python scripts/check_sitemap.py
- name: Validate generated Markdown assets
working-directory: docs/app
run: uv run --no-sync python scripts/check_markdown_assets.py
- name: Validate generated HTML routes and previews
working-directory: docs/app
run: uv run --no-sync python scripts/check_html_routes.py