Deploy the attendee site
The attendee app is static HTML, CSS, JavaScript, and the presentation PDF. It can run on GitHub Pages or another HTTPS static host. The presenter remains on the speaker computer.
Export
confquiz validate quiz.yml
confquiz export quiz.yml --output siteThe output includes .nojekyll and uses relative asset paths, so it works under a GitHub Pages repository path. The export contains the Firebase web configuration and attendee-safe presentation data. It does not contain the Admin credential, answer keys, or the complete question schedule.
Update an existing deployment
Upgrade the presenter, Firestore rules, and exported attendee site in the same maintenance window, before opening an event room. The voting protocol includes a question generation to reject delayed answers after a reset. Older rules reject this field, and older attendee bundles cannot submit after a reset.
- Update the presenter installation to the version used for the export.
- Compare the presentation repository’s
firestore.ruleswith the updated packaged rules and deploy the updated rules to its Firebase project. - Re-export and redeploy the entire attendee site, then reload attendee pages.
- Rehearse a vote, close/reveal, reset, and a fresh vote after reset.
Keep any deliberate project access restrictions when reviewing rule changes. Opening Firestore access is not required. Site exports include content versions for the runtime configuration and PDF so new exports bypass stale browser caches.
Publish a presentation repository
Set the final address in quiz.yml:
presentation:
public_url: "https://your-account.github.io/my-talk/"In the presentation repository, create an Actions secret named FIREBASE_WEB_CONFIG and paste the complete JSON object from your own Firebase web app. The workflow creates the ignored firebase.web.json only on the build runner.
Add this workflow as .github/workflows/pages.yml in the presentation repository:
name: Deploy attendee site
on:
workflow_dispatch:
push:
branches: [main]
paths:
- "quiz.yml"
- "slides.pdf"
- "uv.lock"
- "pyproject.toml"
- ".github/workflows/pages.yml"
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: attendee-pages
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- uses: astral-sh/setup-uv@v7
- run: uv sync --locked
- name: Write speaker Firebase web config
env:
FIREBASE_WEB_CONFIG: ${{ secrets.FIREBASE_WEB_CONFIG }}
run: |
test -n "$FIREBASE_WEB_CONFIG"
printf '%s' "$FIREBASE_WEB_CONFIG" > firebase.web.json
- run: uv run confquiz export quiz.yml --output site
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v5
with:
path: site
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v5In the GitHub repository, open Settings → Pages and choose GitHub Actions as the source.
The secret prevents the Firebase configuration from being committed or reused by another presentation repository. It is not a substitute for Firestore Rules or App Check: the exported attendee site necessarily contains these browser identifiers.
Check the homepage before the event
Open the deployed URL without a room code. It should show PDF page 1 as the main content and a short note that the page becomes interactive when the speaker opens a room.
Start confquiz present, reload the deployed page, and confirm that:
- the join panel appears above the slide;
- the QR code opens the deployed URL with
?code=...; - an attendee can submit one answer; and
- closing voting updates results on both screens as configured.
The presenter writes a short-lived presentation heartbeat. If the presenter process disappears, the public homepage stops advertising the room after the heartbeat expires. The browser measures the heartbeat window from receipt of a server snapshot, so a wrong phone clock cannot hide the join form. A newly opened page can advertise an old heartbeat for up to two minutes; the room-code lookup still validates the session against Firebase’s clock.
Local network check
You may serve an export on the conference network:
python -m http.server 8766 --bind 0.0.0.0 --directory siteUse the computer’s LAN address in presentation.public_url, not 127.0.0.1. Some Firebase and App Check features require HTTPS, so GitHub Pages is the safer final rehearsal target.