fastapi-router-lazy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi_router_lazy-0.1.0/.github/actions/ensure-pages-published/action.yml +78 -0
- fastapi_router_lazy-0.1.0/.github/workflows/ci.yml +280 -0
- fastapi_router_lazy-0.1.0/.github/workflows/zensical-develop.yml +43 -0
- fastapi_router_lazy-0.1.0/.github/workflows/zensical-preview.yml +79 -0
- fastapi_router_lazy-0.1.0/.github/workflows/zensical.yml +46 -0
- fastapi_router_lazy-0.1.0/.gitignore +218 -0
- fastapi_router_lazy-0.1.0/.pre-commit-config.yaml +33 -0
- fastapi_router_lazy-0.1.0/CHANGELOG.md +11 -0
- fastapi_router_lazy-0.1.0/LICENSE +21 -0
- fastapi_router_lazy-0.1.0/PKG-INFO +165 -0
- fastapi_router_lazy-0.1.0/README.md +123 -0
- fastapi_router_lazy-0.1.0/codecov.yml +29 -0
- fastapi_router_lazy-0.1.0/docs/api.md +340 -0
- fastapi_router_lazy-0.1.0/docs/extractors.md +187 -0
- fastapi_router_lazy-0.1.0/docs/index.md +160 -0
- fastapi_router_lazy-0.1.0/docs/usage.md +185 -0
- fastapi_router_lazy-0.1.0/hatch_build.py +66 -0
- fastapi_router_lazy-0.1.0/pyproject.toml +159 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/__init__.py +75 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractor.py +56 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractors/__init__.py +41 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractors/abc.py +76 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractors/cached_extractor.py +250 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractors/plain.py +119 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/extractors/sandbox.py +133 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/middleware.py +142 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/py.typed +0 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/route_info.py +71 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/router_loader.py +201 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/variants/__init__.py +14 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/variants/extractor.py +189 -0
- fastapi_router_lazy-0.1.0/src/fastapi_router_lazy/variants/loader.py +66 -0
- fastapi_router_lazy-0.1.0/tests/conftest.py +55 -0
- fastapi_router_lazy-0.1.0/tests/test_cached_extractor.py +337 -0
- fastapi_router_lazy-0.1.0/tests/test_extractor_factory.py +45 -0
- fastapi_router_lazy-0.1.0/tests/test_middleware.py +278 -0
- fastapi_router_lazy-0.1.0/tests/test_performance.py +172 -0
- fastapi_router_lazy-0.1.0/tests/test_plain_extractor.py +118 -0
- fastapi_router_lazy-0.1.0/tests/test_readme.py +69 -0
- fastapi_router_lazy-0.1.0/tests/test_route_info.py +45 -0
- fastapi_router_lazy-0.1.0/tests/test_router_loader.py +290 -0
- fastapi_router_lazy-0.1.0/tests/test_sandbox_extractor.py +125 -0
- fastapi_router_lazy-0.1.0/tests/variants/routers.py +36 -0
- fastapi_router_lazy-0.1.0/tests/variants/test_extractor.py +60 -0
- fastapi_router_lazy-0.1.0/tests/variants/test_loader.py +74 -0
- fastapi_router_lazy-0.1.0/uv.lock +1872 -0
- fastapi_router_lazy-0.1.0/zensical.toml +79 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Ensure Pages published
|
|
2
|
+
description: >-
|
|
3
|
+
Wait for GitHub's auto "pages build and deployment" of the current gh-pages
|
|
4
|
+
HEAD and rerun it (with backoff) if it fails with a transient error.
|
|
5
|
+
|
|
6
|
+
runs:
|
|
7
|
+
using: composite
|
|
8
|
+
steps:
|
|
9
|
+
- shell: bash
|
|
10
|
+
env:
|
|
11
|
+
GH_TOKEN: ${{ github.token }}
|
|
12
|
+
REPO: ${{ github.repository }}
|
|
13
|
+
ATTEMPTS: "5"
|
|
14
|
+
run: |
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
target_sha="$(gh api "repos/$REPO/branches/gh-pages" --jq '.commit.sha')"
|
|
18
|
+
echo "Ensuring Pages is published for gh-pages@$target_sha"
|
|
19
|
+
|
|
20
|
+
find_run() {
|
|
21
|
+
gh run list --repo "$REPO" --workflow "pages-build-deployment" \
|
|
22
|
+
--commit "$target_sha" --limit 1 \
|
|
23
|
+
--json databaseId,status,conclusion \
|
|
24
|
+
--jq '.[0] // empty | "\(.databaseId) \(.status) \(.conclusion // "")"' 2>/dev/null || true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Block until a run for this SHA reaches "completed"; echo "id conclusion".
|
|
28
|
+
await_completed() {
|
|
29
|
+
for _ in $(seq 1 60); do
|
|
30
|
+
local info id status conclusion
|
|
31
|
+
info="$(find_run)"
|
|
32
|
+
id="$(printf '%s' "$info" | awk '{print $1}')"
|
|
33
|
+
status="$(printf '%s' "$info" | awk '{print $2}')"
|
|
34
|
+
conclusion="$(printf '%s' "$info" | awk '{print $3}')"
|
|
35
|
+
if [ -n "$id" ] && [ "$status" = "completed" ]; then
|
|
36
|
+
printf '%s %s\n' "$id" "$conclusion"
|
|
37
|
+
return 0
|
|
38
|
+
fi
|
|
39
|
+
sleep 10
|
|
40
|
+
done
|
|
41
|
+
return 1
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for attempt in $(seq 1 "$ATTEMPTS"); do
|
|
45
|
+
echo "::group::Pages publish check (attempt $attempt/$ATTEMPTS)"
|
|
46
|
+
if ! result="$(await_completed)"; then
|
|
47
|
+
echo "Timed out waiting for the pages-build-deployment run." >&2
|
|
48
|
+
echo "::endgroup::"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
run_id="${result%% *}"
|
|
52
|
+
conclusion="${result##* }"
|
|
53
|
+
echo "pages-build-deployment run $run_id -> $conclusion"
|
|
54
|
+
echo "::endgroup::"
|
|
55
|
+
|
|
56
|
+
if [ "$conclusion" = "success" ]; then
|
|
57
|
+
echo "Pages published for gh-pages@$target_sha."
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
if [ "$attempt" -lt "$ATTEMPTS" ]; then
|
|
62
|
+
# Progressive backoff: transient failures are usually account-level
|
|
63
|
+
# Pages throttling under concurrent deploys — give it room to clear.
|
|
64
|
+
backoff=$((attempt * 30))
|
|
65
|
+
echo "Transient failure; waiting ${backoff}s before rerunning run $run_id…"
|
|
66
|
+
sleep "$backoff"
|
|
67
|
+
gh run rerun "$run_id" --repo "$REPO" || true
|
|
68
|
+
# Let the rerun leave the "completed" state before we poll again.
|
|
69
|
+
for _ in $(seq 1 12); do
|
|
70
|
+
status="$(find_run | awk '{print $2}')"
|
|
71
|
+
[ "$status" != "completed" ] && break
|
|
72
|
+
sleep 5
|
|
73
|
+
done
|
|
74
|
+
fi
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
echo "Pages deployment still failing after $ATTEMPTS attempts for gh-pages@$target_sha." >&2
|
|
78
|
+
exit 1
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
on:
|
|
3
|
+
push: ~
|
|
4
|
+
pull_request: ~
|
|
5
|
+
jobs:
|
|
6
|
+
ci:
|
|
7
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
name: Python ${{ matrix.python-version }}
|
|
14
|
+
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: [ "3.12", "3.13", "3.14" ]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- name: Checkout
|
|
22
|
+
uses: actions/checkout@v7
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
enable-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Install Dependencies (core only, no variants extra)
|
|
31
|
+
run: uv sync --locked --no-dev --group test
|
|
32
|
+
|
|
33
|
+
- name: Test
|
|
34
|
+
# The wall-clock startup benchmark runs once in the dedicated
|
|
35
|
+
# `benchmark` job, without coverage, so instrumentation and the matrix
|
|
36
|
+
# do not distort its timings.
|
|
37
|
+
run: uv run --no-sync pytest -m "not benchmark" --cov=fastapi_router_lazy --cov-report=xml
|
|
38
|
+
|
|
39
|
+
- name: Codecov
|
|
40
|
+
# Core-only coverage; a single matrix leg uploads (the report is
|
|
41
|
+
# identical across versions). Combined with the variants job's upload.
|
|
42
|
+
if: matrix.python-version == '3.14'
|
|
43
|
+
uses: codecov/codecov-action@v7
|
|
44
|
+
with:
|
|
45
|
+
use_oidc: true
|
|
46
|
+
flags: core
|
|
47
|
+
|
|
48
|
+
variants:
|
|
49
|
+
# The variant/version-aware extractors live behind the optional `variants`
|
|
50
|
+
# extra. The dev group pulls fastapi-router-variants (git source, see
|
|
51
|
+
# pyproject [tool.uv.sources]) so the variant integration tests actually run.
|
|
52
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
53
|
+
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
|
|
56
|
+
name: Variants integration
|
|
57
|
+
|
|
58
|
+
permissions:
|
|
59
|
+
contents: read
|
|
60
|
+
id-token: write # OIDC token for Codecov upload
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v7
|
|
64
|
+
|
|
65
|
+
- name: Install uv
|
|
66
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
67
|
+
with:
|
|
68
|
+
python-version: "3.12"
|
|
69
|
+
|
|
70
|
+
- name: Install (with fastapi-router-variants from git)
|
|
71
|
+
run: uv sync
|
|
72
|
+
|
|
73
|
+
- name: Test
|
|
74
|
+
run: uv run --no-sync pytest -m "not benchmark" --cov=fastapi_router_lazy --cov-report=xml
|
|
75
|
+
|
|
76
|
+
- name: Codecov
|
|
77
|
+
# Covers the variant-aware subpackage, which is skipped in the core job.
|
|
78
|
+
uses: codecov/codecov-action@v7
|
|
79
|
+
with:
|
|
80
|
+
use_oidc: true
|
|
81
|
+
flags: variants
|
|
82
|
+
|
|
83
|
+
fastapi-compat:
|
|
84
|
+
# Core lazy loading only needs plain FastAPI routing/middleware. Validate
|
|
85
|
+
# against the supported floor (0.115) up to latest.
|
|
86
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
87
|
+
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
|
|
90
|
+
name: FastAPI ${{ matrix.fastapi-version }}
|
|
91
|
+
|
|
92
|
+
strategy:
|
|
93
|
+
fail-fast: false
|
|
94
|
+
matrix:
|
|
95
|
+
fastapi-version:
|
|
96
|
+
- "0.115.0" # floor
|
|
97
|
+
- "0.120.2"
|
|
98
|
+
- "0.129.0"
|
|
99
|
+
- "0.139.0" # latest
|
|
100
|
+
|
|
101
|
+
steps:
|
|
102
|
+
- uses: actions/checkout@v7
|
|
103
|
+
|
|
104
|
+
- name: Install uv
|
|
105
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
106
|
+
with:
|
|
107
|
+
python-version: "3.12"
|
|
108
|
+
|
|
109
|
+
- name: Install (core + test deps)
|
|
110
|
+
run: uv sync --no-dev --group test
|
|
111
|
+
|
|
112
|
+
- name: Force FastAPI ${{ matrix.fastapi-version }}
|
|
113
|
+
run: uv pip install "fastapi==${{ matrix.fastapi-version }}"
|
|
114
|
+
|
|
115
|
+
- name: Test
|
|
116
|
+
run: uv run --no-sync pytest -m "not benchmark"
|
|
117
|
+
|
|
118
|
+
benchmark:
|
|
119
|
+
# Startup benchmark: fails (and fails the pipeline) if a warm cache does not
|
|
120
|
+
# defer imports and speed app startup up by at least the required factor
|
|
121
|
+
# over the default extractor. Run without coverage so instrumentation does
|
|
122
|
+
# not distort the timings.
|
|
123
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
124
|
+
|
|
125
|
+
runs-on: ubuntu-latest
|
|
126
|
+
|
|
127
|
+
steps:
|
|
128
|
+
- uses: actions/checkout@v7
|
|
129
|
+
|
|
130
|
+
- name: Install uv
|
|
131
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
132
|
+
with:
|
|
133
|
+
python-version: "3.12"
|
|
134
|
+
enable-cache: true
|
|
135
|
+
|
|
136
|
+
- name: Install (core + test deps)
|
|
137
|
+
run: uv sync --no-dev --group test
|
|
138
|
+
|
|
139
|
+
- name: Benchmark (fails if cached startup speedup < 3x)
|
|
140
|
+
run: uv run --no-sync pytest -m benchmark
|
|
141
|
+
|
|
142
|
+
pre-commit:
|
|
143
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
144
|
+
|
|
145
|
+
runs-on: ubuntu-latest
|
|
146
|
+
|
|
147
|
+
steps:
|
|
148
|
+
- uses: actions/checkout@v7
|
|
149
|
+
|
|
150
|
+
- name: Install uv
|
|
151
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
152
|
+
with:
|
|
153
|
+
python-version: "3.14"
|
|
154
|
+
|
|
155
|
+
- name: Install dependencies (incl. fastapi-router-variants from git)
|
|
156
|
+
run: uv sync
|
|
157
|
+
|
|
158
|
+
- name: Run pre-commit
|
|
159
|
+
run: uv run pre-commit run --all-files --show-diff-on-failure
|
|
160
|
+
|
|
161
|
+
commitizen:
|
|
162
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
163
|
+
|
|
164
|
+
runs-on: ubuntu-latest
|
|
165
|
+
|
|
166
|
+
steps:
|
|
167
|
+
- uses: actions/checkout@v7
|
|
168
|
+
with:
|
|
169
|
+
fetch-depth: 0
|
|
170
|
+
|
|
171
|
+
- name: Install uv
|
|
172
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
173
|
+
with:
|
|
174
|
+
python-version: "3.14"
|
|
175
|
+
|
|
176
|
+
- name: Check commit messages
|
|
177
|
+
run: |
|
|
178
|
+
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
179
|
+
RANGE="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
|
|
180
|
+
elif [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ] \
|
|
181
|
+
|| ! git cat-file -e "${{ github.event.before }}^{commit}" 2>/dev/null; then
|
|
182
|
+
RANGE="HEAD~1..HEAD"
|
|
183
|
+
else
|
|
184
|
+
RANGE="${{ github.event.before }}..${{ github.event.after }}"
|
|
185
|
+
fi
|
|
186
|
+
echo "Checking commit range: ${RANGE}"
|
|
187
|
+
uv run cz check --rev-range "${RANGE}"
|
|
188
|
+
|
|
189
|
+
build:
|
|
190
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
|
191
|
+
needs: [ ci ]
|
|
192
|
+
|
|
193
|
+
runs-on: ubuntu-latest
|
|
194
|
+
|
|
195
|
+
steps:
|
|
196
|
+
- name: Checkout
|
|
197
|
+
uses: actions/checkout@v7
|
|
198
|
+
with:
|
|
199
|
+
fetch-depth: 0
|
|
200
|
+
|
|
201
|
+
- name: Install uv
|
|
202
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
203
|
+
with:
|
|
204
|
+
python-version: "3.14"
|
|
205
|
+
enable-cache: true
|
|
206
|
+
|
|
207
|
+
- name: Git User config
|
|
208
|
+
run: |
|
|
209
|
+
git config --global user.email "action@github.com"
|
|
210
|
+
git config --global user.name "github-actions"
|
|
211
|
+
|
|
212
|
+
- name: Bump version
|
|
213
|
+
run: uvx --from python-semantic-release semantic-release version --no-commit --no-tag --no-push
|
|
214
|
+
env:
|
|
215
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
216
|
+
|
|
217
|
+
- name: Build
|
|
218
|
+
run: uv build
|
|
219
|
+
|
|
220
|
+
- uses: actions/upload-artifact@v7
|
|
221
|
+
with:
|
|
222
|
+
name: fastapi-router-lazy-python
|
|
223
|
+
path: ./dist
|
|
224
|
+
|
|
225
|
+
release:
|
|
226
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
227
|
+
needs: [ pre-commit, commitizen, build ]
|
|
228
|
+
|
|
229
|
+
runs-on: ubuntu-latest
|
|
230
|
+
|
|
231
|
+
environment: pypi
|
|
232
|
+
|
|
233
|
+
permissions:
|
|
234
|
+
contents: write # semantic-release pushes the version bump commit + tag + GitHub release
|
|
235
|
+
id-token: write # OIDC token for PyPI Trusted Publishing (no API token needed)
|
|
236
|
+
|
|
237
|
+
steps:
|
|
238
|
+
- name: Checkout
|
|
239
|
+
uses: actions/checkout@v7
|
|
240
|
+
with:
|
|
241
|
+
fetch-depth: 0
|
|
242
|
+
|
|
243
|
+
- name: Install uv
|
|
244
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
245
|
+
with:
|
|
246
|
+
python-version: "3.14"
|
|
247
|
+
enable-cache: true
|
|
248
|
+
|
|
249
|
+
- name: Git User config
|
|
250
|
+
run: |
|
|
251
|
+
git config --global user.email "action@github.com"
|
|
252
|
+
git config --global user.name "github-actions"
|
|
253
|
+
|
|
254
|
+
- name: Bump version
|
|
255
|
+
run: uvx --from python-semantic-release semantic-release version
|
|
256
|
+
env:
|
|
257
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
258
|
+
|
|
259
|
+
- name: Build
|
|
260
|
+
run: uv build
|
|
261
|
+
|
|
262
|
+
- name: Upload to pypi
|
|
263
|
+
# Trusted Publishing via the job's OIDC token (see permissions above);
|
|
264
|
+
# requires a trusted publisher configured on PyPI for this repo + ci.yml.
|
|
265
|
+
run: uv publish --trusted-publishing always dist/*.tar.gz dist/*.whl
|
|
266
|
+
|
|
267
|
+
- name: Publish release
|
|
268
|
+
run: uvx --from python-semantic-release semantic-release publish
|
|
269
|
+
env:
|
|
270
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
271
|
+
|
|
272
|
+
- name: Merge main to develop
|
|
273
|
+
uses: robotology/gh-action-nightly-merge@v1.5.2
|
|
274
|
+
with:
|
|
275
|
+
stable_branch: 'main'
|
|
276
|
+
development_branch: 'develop'
|
|
277
|
+
allow_ff: true
|
|
278
|
+
user_name: github-actions
|
|
279
|
+
env:
|
|
280
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: zensical-develop
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- develop
|
|
6
|
+
# Per-target group: coalesce rapid develop pushes to the latest build, without
|
|
7
|
+
# cancelling the main/preview deploys. Concurrent pushes to disjoint gh-pages
|
|
8
|
+
# folders are handled by the deploy action's fetch+rebase+retry.
|
|
9
|
+
concurrency:
|
|
10
|
+
group: gh-pages-develop
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
actions: write
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v7
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.13"
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- run: uv run --only-group docs zensical build --strict
|
|
27
|
+
|
|
28
|
+
# GitHub Pages would otherwise run Jekyll on the static site; disable it.
|
|
29
|
+
|
|
30
|
+
- run: touch site/.nojekyll
|
|
31
|
+
|
|
32
|
+
- name: Deploy develop preview 🚀
|
|
33
|
+
uses: JamesIves/github-pages-deploy-action@v4
|
|
34
|
+
with:
|
|
35
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
36
|
+
branch: gh-pages
|
|
37
|
+
folder: site
|
|
38
|
+
# Publish the develop build under /dev/ without touching the stable site at the root.
|
|
39
|
+
target-folder: dev
|
|
40
|
+
clean: true
|
|
41
|
+
|
|
42
|
+
- name: Ensure Pages published (retry ×3)
|
|
43
|
+
uses: ./.github/actions/ensure-pages-published
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: zensical-preview
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
types: [opened, synchronize, reopened, closed]
|
|
5
|
+
# Per-PR group: a new push (or the close/cleanup) supersedes an in-flight build
|
|
6
|
+
# for the same PR, without touching other PRs' or the main/develop deploys.
|
|
7
|
+
# Concurrent pushes to disjoint gh-pages folders are handled by the deploy
|
|
8
|
+
# action's fetch+rebase+retry.
|
|
9
|
+
concurrency:
|
|
10
|
+
group: gh-pages-preview-${{ github.head_ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
actions: write
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
# Same-repo docs/* PRs only: fork PRs get a read-only token and cannot push to gh-pages.
|
|
18
|
+
if: >-
|
|
19
|
+
github.event.action != 'closed'
|
|
20
|
+
&& github.event.pull_request.head.repo.full_name == github.repository
|
|
21
|
+
&& startsWith(github.head_ref, 'docs/')
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
- name: Compute preview slug
|
|
26
|
+
id: slug
|
|
27
|
+
run: |
|
|
28
|
+
name="${GITHUB_HEAD_REF#docs/}"
|
|
29
|
+
name="$(printf '%s' "$name" | tr '/' '-' | tr -cd '[:alnum:]._-')"
|
|
30
|
+
echo "name=$name" >> "$GITHUB_OUTPUT"
|
|
31
|
+
- name: Install uv
|
|
32
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
33
|
+
with:
|
|
34
|
+
python-version: "3.13"
|
|
35
|
+
enable-cache: true
|
|
36
|
+
|
|
37
|
+
- run: uv run --only-group docs zensical build --strict
|
|
38
|
+
|
|
39
|
+
# GitHub Pages would otherwise run Jekyll on the static site; disable it.
|
|
40
|
+
|
|
41
|
+
- run: touch site/.nojekyll
|
|
42
|
+
|
|
43
|
+
- name: Deploy MR preview 🚀
|
|
44
|
+
uses: JamesIves/github-pages-deploy-action@v4
|
|
45
|
+
with:
|
|
46
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
47
|
+
branch: gh-pages
|
|
48
|
+
folder: site
|
|
49
|
+
# Publish under preview/<branch-without-docs>/ without touching the rest of gh-pages.
|
|
50
|
+
target-folder: preview/${{ steps.slug.outputs.name }}
|
|
51
|
+
clean: true
|
|
52
|
+
|
|
53
|
+
- name: Ensure Pages published (retry ×3)
|
|
54
|
+
uses: ./.github/actions/ensure-pages-published
|
|
55
|
+
|
|
56
|
+
cleanup:
|
|
57
|
+
# When a docs/* PR is merged or closed, remove its preview folder.
|
|
58
|
+
if: >-
|
|
59
|
+
github.event.action == 'closed'
|
|
60
|
+
&& github.event.pull_request.head.repo.full_name == github.repository
|
|
61
|
+
&& startsWith(github.head_ref, 'docs/')
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v7
|
|
65
|
+
with:
|
|
66
|
+
ref: gh-pages
|
|
67
|
+
- name: Remove preview folder
|
|
68
|
+
run: |
|
|
69
|
+
name="${GITHUB_HEAD_REF#docs/}"
|
|
70
|
+
name="$(printf '%s' "$name" | tr '/' '-' | tr -cd '[:alnum:]._-')"
|
|
71
|
+
if [ -d "preview/$name" ]; then
|
|
72
|
+
git config user.name "github-actions[bot]"
|
|
73
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
74
|
+
git rm -r "preview/$name"
|
|
75
|
+
git commit -m "chore(docs): remove MR preview for ${name}"
|
|
76
|
+
git push
|
|
77
|
+
else
|
|
78
|
+
echo "No preview folder preview/${name} to remove."
|
|
79
|
+
fi
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: zensical
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
# Per-target group: a release deploy is never cancelled by the develop/preview
|
|
7
|
+
# workflows. Concurrent pushes to disjoint gh-pages folders are handled by the
|
|
8
|
+
# deploy action's fetch+rebase+retry.
|
|
9
|
+
concurrency:
|
|
10
|
+
group: gh-pages-main
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
actions: write
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v7
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.13"
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- run: uv run --only-group docs zensical build --strict
|
|
27
|
+
|
|
28
|
+
# GitHub Pages would otherwise run Jekyll on the static site; disable it.
|
|
29
|
+
|
|
30
|
+
- run: touch site/.nojekyll
|
|
31
|
+
|
|
32
|
+
- name: Deploy 🚀
|
|
33
|
+
uses: JamesIves/github-pages-deploy-action@v4
|
|
34
|
+
with:
|
|
35
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
36
|
+
branch: gh-pages
|
|
37
|
+
folder: site
|
|
38
|
+
clean: true
|
|
39
|
+
# Preserve the develop preview (dev/) and the docs/* MR previews (preview/)
|
|
40
|
+
# published by the zensical-develop and zensical-preview workflows.
|
|
41
|
+
clean-exclude: |
|
|
42
|
+
dev
|
|
43
|
+
preview
|
|
44
|
+
|
|
45
|
+
- name: Ensure Pages published (retry ×3)
|
|
46
|
+
uses: ./.github/actions/ensure-pages-published
|