Skip to content

Commit fa7fd65

Browse files
committed
fix: umami proxy worker deploy steps
Know-Code-Verified: a3b2f9ff460069a4d7af7e462594cf8bd61f0858650731e61c31c3402a805388
1 parent 1b6f281 commit fa7fd65

10 files changed

Lines changed: 1714 additions & 36 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ jobs:
1717
- run: npm install
1818
- run: npm run build
1919
- run: npm test
20+
- name: Umami proxy tests
21+
working-directory: infra/umami-proxy
22+
run: npm ci && npm test
2023
- run: npm run build:docs
2124
- name: CLI smoke (enforcement)
2225
run: npm run smoke

‎.github/workflows/umami-proxy.yml‎

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,61 @@ on:
88
paths:
99
- "infra/umami-proxy/**"
1010
- ".github/workflows/umami-proxy.yml"
11+
pull_request:
12+
paths:
13+
- "infra/umami-proxy/**"
14+
- ".github/workflows/umami-proxy.yml"
1115
workflow_dispatch:
1216

1317
permissions:
1418
contents: read
1519

1620
concurrency:
17-
group: umami-proxy
21+
group: umami-proxy-${{ github.event.pull_request.number || github.ref }}
1822
cancel-in-progress: true
1923

2024
jobs:
21-
deploy:
25+
check:
2226
runs-on: ubuntu-latest
2327
timeout-minutes: 10
2428
steps:
2529
- uses: actions/checkout@v5
30+
- uses: actions/setup-node@v5
31+
with:
32+
node-version: "22"
33+
cache: npm
34+
cache-dependency-path: infra/umami-proxy/package-lock.json
35+
- name: Install Worker deps
36+
working-directory: infra/umami-proxy
37+
run: npm ci
38+
- name: Test
39+
working-directory: infra/umami-proxy
40+
run: npm test
41+
- name: Bundle (dry-run)
42+
working-directory: infra/umami-proxy
43+
run: npx wrangler deploy --dry-run
2644

45+
deploy:
46+
if: github.event_name != 'pull_request'
47+
needs: check
48+
runs-on: ubuntu-latest
49+
timeout-minutes: 10
50+
steps:
51+
- uses: actions/checkout@v5
52+
- name: Require UMAMI_ORIGIN
53+
env:
54+
UMAMI_ORIGIN: ${{ secrets.UMAMI_ORIGIN }}
55+
run: test -n "$UMAMI_ORIGIN"
56+
# wrangler-action's `secrets:` input runs secret bulk BEFORE deploy, which
57+
# fails when the Worker does not exist yet — the route stays in git and
58+
# nothing is provisioned. Deploy the script first, then bind the origin.
2759
- name: Deploy Worker
2860
uses: cloudflare/wrangler-action@v4
2961
with:
3062
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
3163
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
3264
workingDirectory: infra/umami-proxy
33-
secrets: |
34-
UMAMI_ORIGIN
65+
command: deploy
66+
postCommands: printf '%s' "$UMAMI_ORIGIN" | npx wrangler secret put UMAMI_ORIGIN
3567
env:
3668
UMAMI_ORIGIN: ${{ secrets.UMAMI_ORIGIN }}

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Umami proxy provision
6+
- **Deploy the Worker before binding `UMAMI_ORIGIN`.** wrangler-action’s `secrets:` input ran `secret bulk` first, which fails when the Worker does not exist yet — `wrangler.jsonc` still listed the `/s/*` route, so git looked provisioned while nothing was uploaded. CI now deploys, then `secret put`.
7+
- PRs that touch the proxy run unit tests + `wrangler deploy --dry-run`; only `main` / `workflow_dispatch` deploy.
8+
59
### CI verify on push (stacked-run walker)
610
- **`know-code verify --from <oid>`** walks `from..HEAD`, splits by `Know-Code-Verified` hash, and checks each run as a historical tree-pair (parent-of-first tree → last non-merge). Trailerless merges attach to the run but are not the hash tip, so a GitHub merge commit still matches after `main` moved. Linear commits without a trailer fail closed. One-non-merge runs also accept the empty-tree (index) hash of that feature tip.
711
- **Workflow + `init --workflow` + composite action** trigger on `push` to the base branch and pass `github.event.before`. PR verify is unchanged (`head.sha`, no `--from`). All-zeros `before` skips the walk.

‎infra/umami-proxy/README.md‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ so the browser never talks to a third-party analytics host (ad-blocker bypass).
1212
Neutral path names (`/s/x.js`, `/s/e`) avoid EasyPrivacy hits on `umami`,
1313
`analytics`, `script.js`, and `/api/send`. The dashboard is **not** proxied.
1414

15+
`workers_dev` stays off so Cloudflare does not publish
16+
`kc-umami-proxy.<account>.workers.dev` (the hostname would contain `umami`).
17+
Do not attach this Worker as a custom domain on `kc.chtnnhfoundation.org` —
18+
that would steal the host from GitHub Pages. The zone route `/s/*` is enough.
19+
1520
## One-time setup
1621

1722
1. **DNS.** `kc.chtnnhfoundation.org` must be orange-clouded on Cloudflare
@@ -25,20 +30,21 @@ Neutral path names (`/s/x.js`, `/s/e`) avoid EasyPrivacy hits on `umami`,
2530

2631
| Secret | Value |
2732
|--------|--------|
28-
| `CLOUDFLARE_API_TOKEN` | Token with Workers Scripts Edit + Workers Routes Edit on this account |
33+
| `CLOUDFLARE_API_TOKEN` | Account-scoped token with **Workers Scripts Edit** (uploads the Worker) and **Workers Routes Edit** (attaches `/s/*`). Routes Edit alone leaves the route defined and the script missing. |
2934
| `CLOUDFLARE_ACCOUNT_ID` | Cloudflare account ID |
3035
| `UMAMI_ORIGIN` | `https://<your-umami-host>` (no trailing slash) |
3136

3237
First deploy: **Actions → umami-proxy → Run workflow**. Later pushes to
3338
`infra/umami-proxy/**` on `main` deploy automatically
34-
(`.github/workflows/umami-proxy.yml`). The action syncs `UMAMI_ORIGIN` as a
35-
Worker secret on each run.
39+
(`.github/workflows/umami-proxy.yml`). The workflow **deploys the Worker,
40+
then** binds `UMAMI_ORIGIN`. Putting the secret first fails when the Worker
41+
does not exist yet.
3642

37-
Manual fallback:
43+
Manual fallback (same order):
3844

3945
```bash
40-
npx wrangler secret put UMAMI_ORIGIN
4146
npx wrangler deploy
47+
npx wrangler secret put UMAMI_ORIGIN
4248
```
4349

4450
5. **Docs build.** Repo variable `UMAMI_WEBSITE_ID` (Settings → Secrets and
@@ -50,7 +56,14 @@ Neutral path names (`/s/x.js`, `/s/e`) avoid EasyPrivacy hits on `umami`,
5056
JavaScript containing `/s/e`, not `/api/send`. Load a docs page with
5157
ad-blocker on; Umami realtime should show a view.
5258

53-
## Local docs
59+
## Local
60+
61+
```bash
62+
cd infra/umami-proxy
63+
npm install
64+
npm test
65+
npx wrangler deploy --dry-run
66+
```
5467

5568
`docusaurus start` does not inject the script (`data-domains` would also
5669
exclude `localhost`). No events leak from local preview.

0 commit comments

Comments
 (0)