From ef4f27fb5e2e2d42c082d01504820dc0badf8dd7 Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 15 May 2026 00:17:36 -0500 Subject: [PATCH 1/3] chore(ci): make wrangler env target explicit on deploy + pre-push (#86) ## Summary Address the wrangler 4.x "Multiple environments are defined ... but no target environment was specified" warning that appears in production-deploy logs and in every pre-push run. The fix is to pass `--env=""` explicitly on production (which means "use the top-level config") and to mirror the dual-env pattern in the pre-push hook so both production and staging configurations are validated on every push. No behavior change. Wrangler was already using the top-level config on bare `wrangler deploy`; this just makes the intent explicit and removes the cosmetic warning. Surfaced during the post-deploy log review for release PR #85. ## Changelog ## Type of Change - [x] `chore`: Maintenance tasks (dependencies, config, etc.) ## Related Issues/Stories - Story: Cleanup item from the post-deploy log audit of release PR #85. - Issue: None. - Architecture: None. - Related PRs: #85. ## Files Modified **Modified:** - `.github/workflows/deploy.yml`: production-step `command:` now reads `deploy --env=""` with a brief inline comment explaining why. - `scripts/hooks/pre-push`: replaces the single bare `wrangler deploy --dry-run` with two dry-runs, one per environment (`--env=""` and `--env staging`). The hook now catches binding mistakes in either environment before push instead of only validating the top-level config. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Testing - [x] Manual testing completed - [x] All tests passing **Test Summary:** - Local `bun x wrangler deploy --dry-run --env=""`: clean, binding list matches the production-side `anc-score-cache` R2 bucket. - Local `bun x wrangler deploy --dry-run --env staging`: clean, binding list matches the staging-side `anc-score-cache-staging` R2 bucket. - Pre-push hook fired both dry-runs in succession when pushing this branch and passed. - The next production deploy (via a release PR to `main` later) will exercise the `deploy.yml` change; the warning should be absent from the run log. --- .github/workflows/deploy.yml | 6 +++++- scripts/hooks/pre-push | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 29d65f2..af403b1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -134,4 +134,8 @@ jobs: with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} - command: deploy + # --env="" tells wrangler explicitly to use the top-level config + # (the production environment in this repo's multi-env shape). + # Without it, wrangler 4.x warns about ambiguity even though + # bare `deploy` does the right thing. + command: deploy --env="" diff --git a/scripts/hooks/pre-push b/scripts/hooks/pre-push index d85cbb8..aebd449 100755 --- a/scripts/hooks/pre-push +++ b/scripts/hooks/pre-push @@ -58,8 +58,11 @@ bun run build bold '==> bun test' bun test -bold '==> bun x wrangler deploy --dry-run' -bun x wrangler deploy --dry-run +bold '==> bun x wrangler deploy --dry-run (production env)' +bun x wrangler deploy --dry-run --env="" + +bold '==> bun x wrangler deploy --dry-run (staging env)' +bun x wrangler deploy --dry-run --env staging bold '==> Pack-README drift check' bun scripts/generate-pack-readme.mjs site --check Date: Fri, 15 May 2026 00:27:22 -0500 Subject: [PATCH 2/3] fix(registry): correct cf entry by dropping wrong workers-sdk repo for npm URL (#87) ## Summary Correct the `cf` entry in `registry.yaml`. The previous entry claimed `repo: cloudflare/workers-sdk`, but `cf` is not in that repo. I enumerated all 29 packages in `cloudflare/workers-sdk` and none has `bin: cf`. The npm `cf` package itself (currently v0.0.5) ships pre-bundled and declares no `repository`, `homepage`, `bugs`, or `author` fields. Cloudflare's Technical Preview is published to npm without disclosing the source repository. The wrong `repo:` had two downstream effects: 1. The build's registry-index emitted a deterministic but incorrect mapping from `cloudflare/workers-sdk` to `cf` (overwriting wrangler in YAML order). A user pasting `github.com/cloudflare/workers-sdk` into the future live-scoring form would land on `/score/cf` instead of `/score/wrangler`. The build's "duplicate owner/repo" warning was a symptom of this. 2. The `/score/cf` page linked to the wrong upstream repository. Replace `repo:` with `url: https://www.npmjs.com/package/cf` (the canonical distribution surface for `cf` today) and add an inline comment explaining why there is no GitHub repo. The registry schema treats `url:` as the fallback when `repo:` is absent, so the scorecard page still renders. Surfaced during the post-deploy log review for release PR #85. ## Changelog ### Fixed - `/score/cf` and the registry-index now reflect `cf`'s actual distribution surface: no GitHub source repo is publicly declared, so the project link is the npm package page. The reverse-lookup map for `cloudflare/workers-sdk` now resolves correctly to `wrangler`. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Story: Cleanup item from the post-deploy log audit of release PR #85. - Issue: None. - Architecture: None. - Related PRs: #85, #86. ## Files Modified **Modified:** - `registry.yaml`: `cf` entry replaces `repo: cloudflare/workers-sdk` with `url: https://www.npmjs.com/package/cf` and adds an inline comment explaining the rationale. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Testing - [x] Manual testing completed - [x] All tests passing **Test Summary:** - `bun run build`: clean output. The previous "duplicate owner/repo cloudflare/workers-sdk" warning is gone. `cf` now joins `make` and `nvidia-smi` in the "no parseable owner/repo, owner/repo entry skipped" bucket (legitimate; these tools have no canonical source repository). - Build stats unchanged: 8 principles, 112 HTML pages, 112 MD pages, 97 scorecard pages, 96 badges. - `dist/score/cf.html` and `dist/score/cf.md` still emit. The fallback from `repo:` to `url:` does not break scorecard rendering. - Pre-push hook passed both wrangler dry-runs (production and staging environments). **Evidence for the upstream claim:** - Enumerated all 29 packages under `cloudflare/workers-sdk/packages/`: `chrome-devtools-patches`, `cli`, `codemod`, `containers-shared`, `create-cloudflare`, `devprod-status-bot`, `edge-preview-authenticated-proxy`, `format-errors`, `kv-asset-handler`, `lint-config-shared`, `local-explorer-ui`, `miniflare`, `mock-npm-registry`, `pages-shared`, `playground-preview-worker`, `quick-edit-extension`, `quick-edit`, `solarflare-theme`, `turbo-r2-archive`, `unenv-preset`, `vite-plugin-cloudflare`, `vitest-pool-workers`, `workers-editor-shared`, `workers-playground`, `workers-shared`, `workers-tsconfig`, `workers-utils`, `workflows-shared`, `wrangler`. None has `bin: cf` in package.json. The package named `cli` is `@cloudflare/cli-shared-helpers` (internal helpers, no executable). - npm registry metadata for `cf`: `repository: null`, `homepage: null`, `bugs: null`, `author: null`. Tarball contents are entirely pre-bundled JavaScript under `cf-dist/` (bundler output, no source files). --- registry.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/registry.yaml b/registry.yaml index c78d4c6..0229c56 100644 --- a/registry.yaml +++ b/registry.yaml @@ -552,7 +552,11 @@ tools: description: CLI for Cloudflare Workers - name: cf - repo: cloudflare/workers-sdk + # The Tech Preview npm package ships pre-bundled and declares no + # `repository` field. `cf` is NOT in cloudflare/workers-sdk despite + # being from the same team. Until Cloudflare discloses the source + # repo, the project link points at the npm distribution page. + url: https://www.npmjs.com/package/cf binary: cf language: TypeScript tier: workhorse From fb3a55b9c51a8f67f61da6cfeba358366bc52538 Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 15 May 2026 01:47:05 -0500 Subject: [PATCH 3/3] fix(deploy): override routes + triggers in env.staging to prevent inheritance from top-level (#90) ## Summary Explicitly override two inheritable keys in `env.staging` so they stop silently inheriting destructive values from the top-level config: `routes` (which has been quietly stealing anc.dev's custom-domain binding away from production on every dev push since the 2026-04-30 v0.1 launch) and `triggers` (prophylactic; no current scheduled triggers, but the same trap shape). The "routing-drift bug" we have been chasing for two weeks turns out to be documented Wrangler behavior. Per the [Inheritable keys list](https://developers.cloudflare.com/workers/wrangler/configuration/), `routes` is an inheritable key. The top-level config declares `routes: [{ pattern: "anc.dev", custom_domain: true }]`. `env.staging` had no `routes` field, so it silently inherited that array. Every `wrangler deploy --env staging` ran with `routes: [{anc.dev}]` in scope and re-attached anc.dev to `agentnative-site-staging`, transferring the custom-domain binding away from `agentnative-site`. The deployment log includes a `Deployed agentnative-site-staging triggers ... anc.dev (custom domain)` line on every staging deploy that nobody had read as "the prod custom domain just moved". Explicit empty arrays break the inheritance without changing any other behavior. Today's filed-then-retracted upstream issue at [cloudflare/workers-sdk#13925](https://github.com/cloudflare/workers-sdk/issues/13925) (rewritten to describe this trap honestly) suggests Wrangler add a deploy-time warning when an env block inherits a `routes` array containing custom domains. ## Changelog ### Fixed - Stop staging deploys from re-attaching `anc.dev` to the staging Worker on every dev push. The "routing-drift bug" tracked since 2026-04-30 was caused by `env.staging` silently inheriting the top-level `routes` array. Explicit `routes: []` override on `env.staging` makes the staging Worker's deployment stop asserting ownership of `anc.dev`. ### Changed - Added explicit `triggers: { crons: [] }` override on `env.staging` as a prophylactic against the same inheritance pattern firing on a future scheduled-trigger addition. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Story: Closes the chronic routing-drift bug. anc.dev should now stay on the production Worker across staging deploys. - Issue: [cloudflare/workers-sdk#13925](https://github.com/cloudflare/workers-sdk/issues/13925) (rewritten to document the actual inheritance trap). - Architecture: None. - Related PRs: #85 (manual routing-drift fix that this PR addresses structurally), #88 (asset-sharing fix that was reverted by #89 once the routes-inheritance explanation surfaced), #89 (the revert of #88). ## Files Modified **Modified:** - `wrangler.jsonc`: two explicit overrides added on `env.staging` (`routes: []` and `triggers: { crons: [] }`) with inline comments documenting why. No other config changed. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Testing - [x] Unit tests added/updated - [x] All tests passing **Test Summary:** - 315 unit and regression tests pass (unchanged from pre-PR baseline). - `bun x wrangler deploy --dry-run --env=""`: clean. Production-side bindings unchanged. - `bun x wrangler deploy --dry-run --env staging`: clean. Staging-side bindings unchanged. - The deployment log's `Deployed agentnative-site-staging triggers` section is now empty (dry-run output suppresses the section entirely when there are no triggers, which matches the expected post-fix behavior). - Pre-push gate passes end-to-end. **Audit of every inheritable key:** | Key | Top-level | env.staging | Status | |---|---|---|---| | `name` | `agentnative-site` | `agentnative-site-staging` | Explicit override | | `main` | `src/worker/index.ts` | inherited | Safe (same source by design) | | `compatibility_date` | `2026-04-01` | inherited | Safe | | `compatibility_flags` | `["nodejs_compat"]` | inherited | Safe | | `account_id` | via env var | via env var | Same account | | `workers_dev` | `false` | `true` | Explicit override | | `routes` | `[{anc.dev}]` | `[]` | **Explicit override (this PR)** | | `triggers` | not set | `{ crons: [] }` | **Explicit override (this PR, prophylactic)** | | `observability` | `{enabled: true, ...}` | inherited | Safe (same intent) | | `assets` | `{directory: "./dist", ...}` | inherited | Safe (per-Worker asset stores; the "asset overlay" symptoms were routing drift) | | `send_metrics` | `false` | inherited | Safe (both opt out) | | `migrations` | `[{tag: v1, ...}]` | explicitly declared | Already overridden | | `preview_urls`, `route` (singular), `tsconfig`, `rules`, `build`, `no_bundle`, `find_additional_modules`, `base_dir`, `preserve_file_names`, `minify`, `keep_names`, `logpush`, `limits`, `placement` | not set | not set | n/a | If any of the currently-unset inheritable keys gets set at the top level later, re-audit `env.staging` and add an explicit override if the inherited value would be destructive for staging. **Post-merge plan:** After this PR's staging deployment on dev, verify: - Staging deploy log's `Deployed agentnative-site-staging triggers` section is empty (no `anc.dev (custom domain)` line). - CF API: `anc.dev` custom-domain binding stays on `service: agentnative-site` after the deployment completes. - `curl https://anc.dev/` returns 200 from the production Worker (no `X-Robots-Tag` header, content matches main's deployed assets). - `curl https://agentnative-site-staging.brettdavies.workers.dev/` returns 200 with `X-Robots-Tag: noindex`. If anc.dev binding moves to staging after this deployment, the fix is wrong and we need a different mechanism. --- wrangler.jsonc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/wrangler.jsonc b/wrangler.jsonc index 9cd6c7f..f738484 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -127,6 +127,27 @@ // `agentnative-site-sandbox`. "name": "agentnative-site-staging", "workers_dev": true, + // CRITICAL: explicitly override `routes` to an empty array. Per the + // wrangler config docs, `routes` is an INHERITABLE key — if absent + // here, env.staging silently inherits the top-level + // `routes: [{ pattern: "anc.dev", custom_domain: true }]`. That + // inheritance is what produced the routing-drift bug observed since + // 2026-04-30: every `wrangler deploy --env staging` was re-attaching + // anc.dev to the staging Worker because env.staging was inheriting + // the prod route. Explicit empty array breaks the inheritance. + // Removing this line will reintroduce the bug. See the CHANGELOG / + // PR description for the full investigation. + "routes": [], + // PROPHYLACTIC: same inheritance footgun as `routes` above. `triggers` + // (cron) is an INHERITABLE key. If a future change adds cron schedules + // at the top level (e.g., a daily registry refresh on the production + // Worker), env.staging would silently inherit them and double-fire + // every scheduled invocation. We don't currently have any crons, but + // setting `triggers.crons` to an empty array here makes the staging + // override explicit, so a future cron addition forces a deliberate + // decision about whether to mirror to staging. Same audit pattern + // applied to all inheritable keys at top-level. + "triggers": { "crons": [] }, "containers": [ { "class_name": "Sandbox",