Repository navigation
feat(cli): --dry-run, --base-url, --timeout, and the load report in the artifact #72
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Site | |
| # The site at tmhsdigital.github.io/plumbline carries a JavaScript | |
| # reimplementation of the calibration floor. If it disagrees with the Python, | |
| # the site misreports the tool, which is worse than having no site. This | |
| # workflow holds the two together, checks the assembled site as a visitor would | |
| # meet it, and only then deploys. Pull requests run both checks and never | |
| # deploy; a push to main or a manual run deploys only if both pass. A stale | |
| # site is the better failure. | |
| # | |
| # It is deliberately separate from ci.yml and release.yml: it shares no jobs, | |
| # no concurrency group, and no permissions with either. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| # A newer push to a pull request makes its older run pointless. On main, a run | |
| # is never cancelled part way, so a deploy is never cut off. | |
| concurrency: | |
| group: site-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| parity: | |
| name: the site's floor agrees with the Python | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0 | |
| with: | |
| python-version: "3.13" | |
| enable-cache: true | |
| - name: Sync dependencies | |
| run: uv sync --locked | |
| # Without this, a change to the Python floor would leave the JavaScript | |
| # agreeing with an old answer and the check below passing. | |
| - name: The committed fixture is what the Python produces today | |
| run: uv run python scripts/floor_golden.py --check | |
| # Regenerates the worked example from the mock adapter, by the command | |
| # docs/example-report.md records, and refuses if any line of the report | |
| # differs from what that command prints today. Renders the repository's | |
| # docs from this commit, and refuses on a broken link or anchor, or raw | |
| # HTML outside the allowlist. | |
| - name: Assemble the site | |
| run: uv run python scripts/build_site.py --out _site | |
| # The runner's own Node, with no setup action and no package install. | |
| # The check uses the standard library only. Given the built example, it | |
| # also requires the page to derive the report's ECE line exactly. | |
| - name: floor.js reproduces the fixture and the example report | |
| run: | | |
| node --version | |
| node scripts/check_floor_parity.mjs _site/example-run.json | |
| # search.js against cases that say what a reader should find first, and | |
| # every search-index.json entry against the page and id it names. Also | |
| # the files the page scripts fetch, which the link check cannot see. | |
| - name: Search ranks as it should, and every index entry resolves | |
| run: node scripts/check_search.mjs _site | |
| # The exact bytes the deploy job publishes. On a pull request this is | |
| # also a downloadable preview of the site. | |
| - name: Keep the assembled site | |
| uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 | |
| with: | |
| path: _site | |
| docs: | |
| name: the assembled site's links, anchors, and meta tags resolve | |
| needs: parity | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # The renderer's refusals (raw HTML off the allowlist, broken links and | |
| # anchors, remote images, a modified vendored file) each have a case. | |
| - name: The doc renderer refuses what it should | |
| run: node scripts/render_docs.mjs --self-test | |
| - name: Fetch the assembled site | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: github-pages | |
| path: artifact | |
| # Checked as published, not as built: the same archive the deploy job | |
| # serves, unpacked. | |
| - name: Every link, anchor, and meta tag resolves, and nothing loads from another origin | |
| run: | | |
| mkdir site-as-published | |
| tar -xf artifact/artifact.tar -C site-as-published | |
| node scripts/check_site_links.mjs site-as-published | |
| # The runner's own Chrome, driven over the DevTools protocol by the | |
| # runner's own Node; nothing is installed. It fails on a broken flow (the | |
| # calculator, a shared link, search) and on any console error or CSP | |
| # violation, on every page. | |
| - name: The pages work in a real browser | |
| run: node scripts/smoke_site.mjs site-as-published | |
| deploy: | |
| name: deploy to GitHub Pages | |
| needs: [parity, docs] | |
| if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| # One deploy at a time; a queued one waits rather than cancelling. | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: false | |
| steps: | |
| - name: Publish the checked site | |
| id: deployment | |
| uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 | |
| live: | |
| name: the live site resolves as the checked one did | |
| needs: deploy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # What Pages actually serves, including a real 404 for a missing path, | |
| # which only a request to the live site can show. The CDN can take a | |
| # moment to serve the new build, so a failure is retried once. | |
| - name: Every link, anchor, meta tag, and policy resolves on the live site | |
| run: | | |
| node scripts/check_site_links.mjs https://tmhsdigital.github.io/plumbline/ || { | |
| sleep 60 | |
| node scripts/check_site_links.mjs https://tmhsdigital.github.io/plumbline/ | |
| } |