- commit
- c3a34bffec37de5eaf12ed81a670b10913f08eec
- parent
- c045baa1c964059b39c5f6e84c0061ef9dd0fb29
- author
- Dami <dami.etoile@gmail.com>
| M | .github/ | 8 | +++-- |
| M | AGENTS.md | 2 | +- |
| M | README.md | 6 | ++-- |
| D | docs/ | 58 | ------------------------------ |
| A | docs/ | 58 | ++++++++++++++++++++++++++++++ |
| M | scripts/ | 18 | +++++++++ |
| A | wrangler.jsonc | 8 | ++++ |
@@ -5,12 +5,14 @@ on:
55 paths:66 - website/**77 - scripts/verify-website.sh8+ - wrangler.jsonc89 - .github/workflows/website.yml910 push:1011 branches: [main]1112 paths:1213 - website/**1314 - scripts/verify-website.sh15+ - wrangler.jsonc1416 - .github/workflows/website.yml1517 1618 permissions:@@ -33,7 +35,7 @@ jobs:
3335 run: ./scripts/verify-website.sh3436 3537 deploy:36- name: Cloudflare Pages38+ name: Cloudflare Worker3739 if: github.event_name == 'push'3840 needs: verify3941 runs-on: ubuntu-24.04@@ -50,10 +52,10 @@ jobs:
5052 5153 - name: Deploy production site5254 id: deploy53- uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v355+ uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.05456 with:5557 apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}5658 accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}5759 wranglerVersion: 4.112.058- command: pages deploy website --project-name=goq-sh --branch=main60+ command: deploy5961 gitHubToken: ${{ secrets.GITHUB_TOKEN }}@@ -43,7 +43,7 @@ Sigil host.
4343 AudioWorklet playback, controller-first navigation, input capture, A/V4444 synchronization, window geometry, and client diagnostics.4545 - `website/` is the static goq.sh site. A merge to `main` publishes it through46- Cloudflare Pages after the static-site gate passes.46+ the `goq-sh` Cloudflare Worker after the static-site gate passes.4747 4848 ## Proven baseline4949 @@ -202,9 +202,9 @@ On Linux with NVIDIA:
202202 WEBKIT_DISABLE_DMABUF_RENDERER=1 cargo tauri dev203203 ```204204 205-The static `website/` directory is published through Cloudflare Pages after a206-merge to `main`. See the [Cloudflare Pages release setup](docs/cloudflare-pages.md)207-for the one-time project and GitHub environment configuration.205+The static `website/` directory is published as Cloudflare Worker static assets206+after a merge to `main`. See the [Cloudflare Worker release setup](docs/cloudflare-worker.md)207+for the one-time service and GitHub environment configuration.208208 209209 Portal is distributed as a compiled, signed desktop application; it is never210210 installed through a shell pipe. Sigil uses a separate Bazzite machine bootstrap@@ -1,58 +0,0 @@
1-# Publish goq.sh with Cloudflare Pages2-3-The `website/` directory is a complete static site. GitHub Actions validates it4-without a package install or framework build, then deploys it to Cloudflare5-Pages with Wrangler. In this release process, a push to `main` that changes the6-site or its workflow is the production release.7-8-## One-time dashboard setup9-10-In the Cloudflare dashboard, open **Workers & Pages**, create a Pages project,11-and choose **Direct Upload**. Name the project `goq-sh`. The project must exist12-before the first production workflow runs; use the current `website/` directory13-for the dashboard's required initial upload. GitHub Actions replaces that14-deployment after the first merge.15-16-Do not also connect the Cloudflare Git integration: the repository workflow is17-the sole publisher, which prevents two independent systems from racing to18-deploy the same commit.19-20-In the GitHub repository, the `main` environment must contain these environment21-secrets:22-23-- `CLOUDFLARE_ACCOUNT_ID`24-- `CLOUDFLARE_API_TOKEN`25-26-The API token needs **Account / Cloudflare Pages / Edit** permission for the27-account that owns the project. These secret names are already present in the28-repository's `main` environment.29-30-The **Website / Static site** job validates JavaScript, required assets,31-internal asset references, and security-header configuration on pull requests.32-On a push to `main`, the **Website / Cloudflare Pages** job waits for that check,33-enters the `main` environment, and deploys `website/` to the production branch34-of the `goq-sh` Pages project.35-36-## Domain and release gate37-38-After the first successful deployment, open the Pages project's **Custom39-domains** screen and add `goq.sh`. Complete the DNS prompts in the account that40-owns the zone. Add `www.goq.sh` separately only if it should also serve or41-redirect to the site.42-43-Protect `main` in GitHub and require these checks before merge:44-45-- **CI / Complete demo gate**46-- **Website / Static site** when it is present47-48-The site release path is then:49-50-1. Open a pull request with website changes.51-2. Merge only after the repository checks pass.52-3. The production job deploys the merged `main` commit through the protected53- GitHub environment.54-4. Cloudflare publishes the resulting immutable Pages deployment to `goq.sh`.55-56-This workflow does not publish pull-request previews because environment secrets57-are deliberately unavailable to untrusted PR code. Preview deployments can be58-added later with a separate least-privilege project and credential if needed.@@ -0,0 +1,58 @@
1+# Publish goq.sh with a Cloudflare Worker2+3+The `website/` directory is a complete static site. GitHub Actions validates it4+without a package install or framework build, then deploys it as static assets5+on the existing `goq-sh` Cloudflare Worker with Wrangler. A push to `main` that6+changes the site, its Wrangler configuration, or its workflow is a production7+release.8+9+## One-time dashboard setup10+11+The `goq-sh` Worker must exist in the Cloudflare account used by CI. Attach12+`goq.sh` as its custom domain in **Workers & Pages > goq-sh > Settings >13+Domains & Routes**.14+15+GitHub Actions is the sole production publisher. If the Worker was created by16+importing this GitHub repository, disable automatic production and preview17+deployments under the Worker's **Settings > Build** page so Cloudflare Workers18+Builds does not race the repository workflow.19+20+In the GitHub repository, the `main` environment must contain these environment21+secrets:22+23+- `CLOUDFLARE_ACCOUNT_ID`24+- `CLOUDFLARE_API_TOKEN`25+26+Create the token from Cloudflare's **Edit Cloudflare Workers** template and27+scope it to only the account that owns `goq-sh`. The token must be able to edit28+Workers Scripts. Never commit the token or account ID.29+30+The **Website / Static site** job validates JavaScript, required assets,31+internal asset references, security headers, the fail-closed installer, and the32+assets-only Wrangler configuration. On a push to `main`, the **Website /33+Cloudflare Worker** job waits for that check, enters the protected `main`34+environment, and runs `wrangler deploy` against `wrangler.jsonc`.35+36+The configuration deliberately has no Worker script or assets binding. Requests37+are served directly from Cloudflare's static-asset layer, and `website/_headers`38+supplies the site's security headers and installer content type.39+40+## Release gate41+42+Protect `main` in GitHub and require these checks before merge:43+44+- **CI / Complete demo gate**45+- **Website / Static site** when it is present46+47+The site release path is then:48+49+1. Open a pull request with website or deployment changes.50+2. Merge only after the repository checks pass.51+3. The production job deploys the merged `main` commit through the protected52+ GitHub environment.53+4. Cloudflare promotes the immutable Worker version and assets to `goq.sh`.54+55+This workflow does not publish pull-request previews because environment secrets56+are deliberately unavailable to untrusted PR code. Preview versions can be57+added later with a separate least-privilege credential and explicit promotion58+policy.@@ -4,6 +4,7 @@ set -euo pipefail
44 script_dir="$(CDPATH='' cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"55 repo_dir="$(CDPATH='' cd -- "$script_dir/.." && pwd -P)"66 site_dir="$repo_dir/website"7+wrangler_config="$repo_dir/wrangler.jsonc"78 89 for command_name in bash find grep node; do910 if ! command -v "$command_name" >/dev/null 2>&1; then@@ -19,6 +20,23 @@ for required_file in index.html styles.css dither.js _headers install-sigil; do
1920 fi2021 done2122 23+node - "$wrangler_config" <<'NODE'24+const fs = require('node:fs');25+26+const configPath = process.argv[2];27+const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));28+29+if (config.name !== 'goq-sh') {30+ throw new Error('Wrangler must deploy the existing goq-sh Worker');31+}32+if (config.assets?.directory !== './website') {33+ throw new Error('Wrangler assets.directory must be ./website');34+}35+if ('main' in config || 'binding' in (config.assets ?? {})) {36+ throw new Error('goq.sh must remain an assets-only Worker');37+}38+NODE39+2240 if find "$site_dir" -type l -print -quit | grep -q .; then2341 echo 'website output must not contain symbolic links' >&22442 exit 1