blob: 59fc58499a882635cc2d7dd256fbcd06509dc848 (
plain)
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
|
name: Docs canary QA (nightly per-entry sweep + parity)
on:
schedule:
- cron: "45 2 * * *"
workflow_dispatch: {}
permissions:
contents: read
jobs:
qa:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Per-entry sweep (one page + PDF per versions.json entry, §3.4 gate c)
env:
# CF Access service token goes through the environment, NEVER through argv: a secret
# on the command line is readable from the process table for the life of the process
# and is captured verbatim by `set -x` traces and crash dumps. These environment
# variables are the ONLY supported way to pass the token: the --access-id /
# --access-secret flags were removed, and argparse now rejects them outright
# rather than ignoring them and leaving every probe to 403.
CF_ACCESS_CLIENT_ID: ${{ secrets.CF_ACCESS_CLIENT_ID }}
CF_ACCESS_CLIENT_SECRET: ${{ secrets.CF_ACCESS_CLIENT_SECRET }}
run: |
set -eu
# Capture-first (not pipe/process-substitution-into-while): a malformed
# versions.json must fail this step loudly. Piping/process-substituting jq
# directly into the while loop hides a jq failure from `set -e` (the loop just
# sees empty stdin and "passes" with zero iterations) — capture the output into
# a variable first so a non-zero jq exit trips `set -e` before the loop runs.
versions=$(jq -ce '.versions[]' workers/versions.json)
fail=0
while read -r v; do
slug=$(echo "$v" | jq -r .slug); pdf=$(echo "$v" | jq -r '.pdf // empty')
if ! python -m scripts.docs_gates.smoke --host docs-next.vyos.io --slug "$slug" \
--expect-sha SKIP ${pdf:+--pdf "$pdf"}; then
echo "sweep-fail=$slug" | tee -a "$GITHUB_STEP_SUMMARY"
fail=1
fi
done <<< "$versions"
exit $fail # a broken advertised version MUST fail nightly QA (§3.4 gate c)
# --expect-sha SKIP = presence-only assert; implemented in smoke.docs_build_ok (Task 3.2).
- name: URL parity vs RTD (pre-cutover truth)
env:
# Same argv-secret rule as the sweep step above; parity.py reads these by default.
CF_ACCESS_CLIENT_ID: ${{ secrets.CF_ACCESS_CLIENT_ID }}
CF_ACCESS_CLIENT_SECRET: ${{ secrets.CF_ACCESS_CLIENT_SECRET }}
run: |
# --slugs pinned to CF-built versions: 1.3/1.2 have no RTD sitemaps (§15a.5);
# legacy parity is the snapshot repo's crawl-inventory job (defense in depth
# alongside the matching parity.py DEFAULT_SLUGS)
python -m scripts.docs_gates.parity \
--sitemap-host docs.vyos.io --probe-host docs-next.vyos.io \
--slugs rolling,1.5,1.4
- uses: actions/upload-artifact@v4
if: always()
with: { name: parity-report, path: parity-report.json }
|