forked from ChelseaKR/tods-validate
-
Notifications
You must be signed in to change notification settings - Fork 0
108 lines (103 loc) · 5.08 KB
/
Copy pathpages.yml
File metadata and controls
108 lines (103 loc) · 5.08 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
name: Deploy playground
# Publishes web/ (the in-browser Pyodide validator) to GitHub Pages.
# One-time setup: Settings -> Pages -> Source: "GitHub Actions".
#
# Runs as the last stage of a release, called from pypi-publish.yml after
# `verify-published` has confirmed the released wheel is really on PyPI. It
# used to run on `release: published` directly, which raced the very upload it
# depends on: the page micropip-installs `tods-validate==<pinned>` from PyPI,
# and on v0.8.0 and v0.9.0 the guard below fired seconds after the release was
# published -- correctly refusing a page whose wheel did not exist yet -- so
# the live playground stayed on the previous release. Sequencing the deploy
# after the publish removes the race; the guard stays, so a wheel PyPI never
# serves still fails this workflow loudly instead of deploying anyway or
# silently skipping. workflow_dispatch stays for out-of-band fixes (deploys
# main, whose pin the guard checks against PyPI the same way).
#
# The verify job below then checks that the deployment actually took effect and
# that the live page passes WCAG 2.1 AA -- a deploy is not done because a job
# went green, it is done when the page people open is the page that was built.
# .github/workflows/playground-deployment.yml re-runs both checks weekly.
on:
workflow_call:
workflow_dispatch:
# Least-privilege default; the deploy job escalates only what it needs
# (CICD-04: write scopes job-level only).
permissions:
contents: read
jobs:
deploy:
# Serialize page deploys. Job-level rather than workflow-level so the
# group holds both when this workflow is called from pypi-publish.yml and
# when it is dispatched directly.
concurrency:
group: pages
cancel-in-progress: false
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
permissions:
pages: write # publish the built site to GitHub Pages
id-token: write # OIDC to prove this workflow run produced the artifact
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
- name: Refuse to publish a page pinned to a wheel PyPI does not have
env:
ATTEMPTS: "20" # x 30s: 10 minutes for the index to settle
run: |
set -euo pipefail
pin="$(sed -n 's/.*TODS_VALIDATE_VERSION = "\([^"]*\)".*/\1/p' web/index.html | head -1)"
test -n "$pin"
echo "playground pins tods-validate==$pin"
# The retry absorbs index propagation right after a publish (the
# release path has already re-downloaded the wheel in
# verify-published, but this workflow can also be dispatched on its
# own). A wheel that never appears still fails, loudly, after the
# window -- never deploy a page that cannot install itself, and
# never skip quietly.
for attempt in $(seq 1 "$ATTEMPTS"); do
if curl -fsSL -o /dev/null "https://pypi.org/pypi/tods-validate/$pin/json"; then
echo "PyPI serves tods-validate==$pin (attempt $attempt/$ATTEMPTS)"
exit 0
fi
echo "attempt $attempt/$ATTEMPTS: PyPI does not serve tods-validate==$pin yet; waiting 30s"
sleep 30
done
echo "::error::PyPI has no tods-validate==$pin after $ATTEMPTS attempts, so the deployed page could not install itself. Publish the wheel first (pypi-publish.yml), then re-run this deploy."
exit 1
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: web
- id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
# Confirms the deployment against the live URL: the served page must be the
# tree that was just uploaded, and it must pass the same WCAG 2.1 AA runners
# ci.yml applies to the repository copy.
verify:
needs: deploy
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
# Deliberately no actions/setup-node: this workflow deploys as part of
# a release publish, and zizmor's cache-poisoning audit blocks a
# cache-capable setup action in that context. The runner's preinstalled
# Node runs pa11y-ci fine, and `npm ci` installs from the committed
# lockfile either way.
- run: node --version
- run: npm ci --ignore-scripts
- name: Check the deployed page is the tree that was just published
run: ./scripts/check-deployed-playground.sh web/index.html
- name: Select the hosted Chrome binary
run: |
a11y_chrome="$(command -v google-chrome)"
test -x "$a11y_chrome"
echo "PUPPETEER_EXECUTABLE_PATH=$a11y_chrome" >> "$GITHUB_ENV"
- name: Audit the deployed page (WCAG 2.1 AA)
run: ./node_modules/.bin/pa11y-ci --config scripts/pa11y-ci-live.cjs