# Build the served web-root and publish it to GitHub Pages. # # public/ is committed, but the bundles inside it are not: public// is # regenerated on every push so what ships always matches source. The rest of the # folder — the shell and the pre-generated posters the app fetches at runtime — # comes straight from the checkout. # # MAPBOX_TOKEN is a repository secret. The build turns it into the static token # endpoint at public/api/maps/token.json, which is gitignored, so the credential # reaches the deployed site without ever entering git history. Rotating it means # changing the secret and re-running this workflow. name: Deploy to GitHub Pages on: push: branches: [main] workflow_dispatch: # Read the repo, write a Pages deployment, and mint the OIDC token Pages requires. permissions: contents: read pages: write id-token: write # Never let two deploys race; let a newer push supersede an in-flight one. concurrency: group: pages cancel-in-progress: true jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: oven-sh/setup-bun@v2 with: bun-version: latest - run: bun install --frozen-lockfile # Emits public// plus the token endpoint, then runs the build guards # (drop-portability, inline-parse, bundles-shipped and the rest). A guard # failure fails the deploy, which is the point of having them. - name: Build # BUILD_ALLOW=1: build-lock.sh refuses an unannounced build (exit 75) so two agents on one box # cannot build at once; a CI runner is the only builder on its machine, so it opts in. env: MAPBOX_TOKEN: ${{ secrets.MAPBOX_TOKEN }} BUILD_ALLOW: '1' run: bun run build # Fail loudly rather than publishing a site whose maps cannot draw. - name: Assert the token endpoint exists run: | test -s public/api/maps/token.json || { echo "::error::public/api/maps/token.json is missing or empty — set the MAPBOX_TOKEN repository secret, or every basemap will render blank." exit 1 } # A public web-root must never carry the local staging credential. - name: Assert no local credential is being published run: | if [ -e public/token.local.js ]; then echo "::error::public/token.local.js is present in the web-root and must not be published." exit 1 fi # Artefact checks cannot tell whether the site WORKS. This boots the built # public/ in a real browser and fails if the shell cannot resolve a token, # no bundle registers its element, or any same-origin request 404s. - name: Install the browser the smoke test drives run: bunx playwright install --with-deps chromium - name: Smoke-test the built site run: bun run smoke - uses: actions/configure-pages@v6 - uses: actions/upload-pages-artifact@v5 with: path: public deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v5