Quality checks

One shared workflow runs the same checks on every project, on each change, against its live preview. A leaked private name or key blocks the change; everything else is reported. It runs as one short job so it stays cheap.

iPhone layout

Opens each page in Safari's engine at iPhone sizes 390×844 and 390×664 (the smaller one is Safari with its toolbar showing) and checks the first screen:

Header overlapNo text hidden under a fixed or sticky header.
Safari's bottom barNo small buttons or links sitting in the bottom 100px, where the toolbar covers them.
Sideways scrollNo page wider than the screen.
Empty gapsNo blank band taller than 200px on the first screen.
ScreenshotsSaves a screenshot of every page at both sizes.

Page health

ErrorsNo console errors, script errors, failed requests or security-policy (CSP) violations.
AccessibilityNo serious or critical problems, such as missing image text, unlabeled fields or low contrast.
Page weightEach page stays under its download budget.
Security headersCSP, HSTS, nosniff, frame protection and referrer policy are set; robots.txt and every sitemap page answer.

Safety (blocks the change)

Private-name scanWhole-word search of public files, every live page, its headers and scripts for names that must stay private.
Leaked-key scanScans each change and the live pages and scripts for passwords and API keys. Findings are logged without the key itself.
Preview is upWaits until the preview is serving this exact change before testing it.

Also checked

Links and assetsEvery same-site link, image and script; outside links are checked once a week.
Icon cache safetyA changed icon needs a new filename so phones pick it up.
Typecheck and lintRuns the repo's own scripts, if it has them.

Add it to a repo

Copy this to .github/workflows/qa.yml and fill in the <…> values. No token or secret is needed.

name: QA
on:
  pull_request:
  push: { branches: [main] }
  workflow_dispatch:
permissions: { contents: write, actions: read }
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
  qa:
    uses: dpztxzx9nf-lab/ThinkCore/.github/workflows/qa-site.yml@v3
    with:
      # Main: production URL. PRs: '' (web checks n/a), or set branch_preview_template.
      preview_url: ${{ github.head_ref == '' && 'https://<prod-domain>' || '' }}
      public_paths: "<public files/dirs, e.g. *.html public>"
      # version_path: /version.txt
      # link_paths: "/ /legal/"

No website? Set preview_url: "" and the web checks report n/a.