|
| 1 | +name: Deploy legacy snapshot worker |
| 2 | +on: |
| 3 | + workflow_dispatch: |
| 4 | + inputs: |
| 5 | + promote: |
| 6 | + description: "false = candidate only; true = promote to production worker" |
| 7 | + type: boolean |
| 8 | + default: false |
| 9 | + force_pdf_refresh: |
| 10 | + description: "true = re-fetch + re-upload the 1.3 PDF even if it already exists in R2" |
| 11 | + type: boolean |
| 12 | + default: false |
| 13 | +permissions: |
| 14 | + contents: read |
| 15 | +# Never cancel a mid-flight deploy — queue behind it instead (fleet parity). |
| 16 | +concurrency: |
| 17 | + group: legacy-deploy |
| 18 | + cancel-in-progress: false |
| 19 | +jobs: |
| 20 | + deploy: |
| 21 | + runs-on: ubuntu-latest |
| 22 | + steps: |
| 23 | + - uses: actions/checkout@v4 |
| 24 | + with: { persist-credentials: false } |
| 25 | + - uses: actions/checkout@v4 |
| 26 | + with: { repository: vyos/vyos-documentation, ref: rolling, path: docsrepo, persist-credentials: false } |
| 27 | + - uses: actions/setup-node@v4 |
| 28 | + with: { node-version: 22 } |
| 29 | + # Runs BEFORE the Worker deploy (fail fast): if the PDF can't be fetched, validated, |
| 30 | + # and secured in R2, no Worker goes live — otherwise a promote=true run could leave |
| 31 | + # production serving HTML whose legacy-PDF link 404s, violating the spec §5 site+PDF |
| 32 | + # consistency invariant the main pipeline enforces. |
| 33 | + - name: Upload legacy 1.3 PDF to R2 (apex §5 fallback source) |
| 34 | + env: |
| 35 | + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN_DOCS }} |
| 36 | + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
| 37 | + run: | |
| 38 | + set -eu |
| 39 | + cd docsrepo/workers && npm ci # the Deploy step's own npm ci re-run is a fast no-op |
| 40 | +
|
| 41 | + R2_KEY="vyos-docs-artifacts/legacy/1.3/vyos-documentation.pdf" |
| 42 | + # 1.2/1.3 are frozen (spec §15a) — once the PDF is seeded in R2 it never |
| 43 | + # changes, and after RTD sunsets, docs.vyos.io/_/downloads/... is gone, so |
| 44 | + # re-dispatching this workflow must not depend on re-fetching it. Probe |
| 45 | + # existence first (wrangler r2 has no head-only verb; `get --pipe` is the |
| 46 | + # cheapest existence check the CLI exposes) and skip fetch+upload on a hit. |
| 47 | + if [ '${{ inputs.force_pdf_refresh }}' != 'true' ] && \ |
| 48 | + npx wrangler r2 object get "$R2_KEY" --remote --pipe >/dev/null 2>/tmp/r2-probe.log; then |
| 49 | + echo "PDF already present at $R2_KEY — skipping fetch+upload (force_pdf_refresh=false)" |
| 50 | + exit 0 |
| 51 | + fi |
| 52 | +
|
| 53 | + # r2-staging/ (tools/snapshot.sh's local output) is gitignored, so CI re-fetches |
| 54 | + # from the pre-sunset RTD source directly. Browser-UA + retry added defensively: |
| 55 | + # tools/snapshot.sh's wget mirror crawl needed a browser UA to pass Cloudflare's |
| 56 | + # managed challenge, while its own PDF curl needed neither locally — but CI's |
| 57 | + # IP/request pattern differs, so both guards are cheap insurance here. |
| 58 | + # 29.2 MiB > the 25 MiB Worker per-asset cap, so this artifact never lands in |
| 59 | + # the deploy's dist/assets/ below — it goes straight to the shared |
| 60 | + # vyos-docs-artifacts R2 bucket the apex Worker's DOCS_PDFS binding reads |
| 61 | + # (workers/apex/wrangler.jsonc in vyos-documentation, both envs). |
| 62 | + curl -fL --retry 5 --retry-delay 5 \ |
| 63 | + --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36" \ |
| 64 | + "https://docs.vyos.io/_/downloads/en/1.3/pdf/" -o /tmp/vyos-documentation-1.3.pdf |
| 65 | +
|
| 66 | + size=$(stat -c%s /tmp/vyos-documentation-1.3.pdf) |
| 67 | + min=$((25*1024*1024)); max=$((35*1024*1024)) |
| 68 | + if [ "$size" -le "$min" ] || [ "$size" -ge "$max" ]; then |
| 69 | + echo "PDF size sanity check FAILED: got $size bytes, expected strictly between $min and $max bytes (25-35 MiB)" |
| 70 | + exit 1 |
| 71 | + fi |
| 72 | + echo "PDF size OK: $size bytes" |
| 73 | +
|
| 74 | + header=$(head -c 5 /tmp/vyos-documentation-1.3.pdf) |
| 75 | + if [ "$header" != "%PDF-" ]; then |
| 76 | + echo "PDF content validation FAILED: file does not start with %PDF- (got: $header)" |
| 77 | + exit 1 |
| 78 | + fi |
| 79 | + echo "PDF content OK: %PDF- header present" |
| 80 | +
|
| 81 | + npx wrangler r2 object put "$R2_KEY" \ |
| 82 | + --file /tmp/vyos-documentation-1.3.pdf --remote |
| 83 | + - name: Deploy |
| 84 | + env: |
| 85 | + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN_DOCS }} |
| 86 | + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
| 87 | + run: | |
| 88 | + set -eu |
| 89 | + mkdir -p docsrepo/dist/assets && cp -r snapshot/. docsrepo/dist/assets/ |
| 90 | + cd docsrepo/workers && npm ci |
| 91 | + name="vyos-docs-legacy$( [ '${{ inputs.promote }}' = 'true' ] || echo '-candidate' )" |
| 92 | + envv="$( [ '${{ inputs.promote }}' = 'true' ] && echo production || echo canary )" |
| 93 | + npx wrangler deploy --config branch/wrangler.legacy.jsonc \ |
| 94 | + --name "$name" --var DOCS_BUILD_SHA:'${{ github.sha }}' --var DOCS_ENV:"$envv" |
0 commit comments