summaryrefslogtreecommitdiff
path: root/.github/workflows/docs-canary-qa.yml
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 }