Drop wrangler.toml, and take the account id from .env instead
Pages only honours a wrangler.toml that declares pages_build_output_dir, which a five-language site cannot: every language has its own directory. So Wrangler warned on every deploy that it was ignoring the file, and the deploy script only ever used it as somewhere to keep the account id. Wrangler reads CLOUDFLARE_ACCOUNT_ID from the environment, so the id now lives in .env.dist next to the token placeholder, and `make deploy` exports it from .env like everything else. Run directly, the deploy app now fails with a message naming `make .env` instead of Wrangler's "Failed to automatically retrieve account IDs". prod-server no longer needs to cd to the repo root, since there is nothing left to discover there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
c5710d9 parent: aebf633 modified
.env.dist +3 -0 | @@ -1,3 +1,6 @@ | ||
| 1 | 1 | # Template for .env: `make .env` fills the placeholder in from Bitwarden |
| 2 | 2 | # (the CLOUDFLARE_API_TOKEN field of the "mykiwi.blog" item). |
| 3 | 3 | CLOUDFLARE_API_TOKEN=@CLOUDFLARE_API_TOKEN@ |
| 4 | +# Not a secret, just an identifier - Wrangler reads it from the environment | |
| 5 | +# (same id as infra/variables.tf). | |
| 6 | +CLOUDFLARE_ACCOUNT_ID=d8149974c9ab26867fdc9cd579711d7d | |
| @@ -1,3 +1,6 @@ | |||
| 1 | # Template for .env: `make .env` fills the placeholder in from Bitwarden | 1 | # Template for .env: `make .env` fills the placeholder in from Bitwarden |
| 2 | # (the CLOUDFLARE_API_TOKEN field of the "mykiwi.blog" item). | 2 | # (the CLOUDFLARE_API_TOKEN field of the "mykiwi.blog" item). |
| 3 | CLOUDFLARE_API_TOKEN=@CLOUDFLARE_API_TOKEN@ | 3 | CLOUDFLARE_API_TOKEN=@CLOUDFLARE_API_TOKEN@ |
| 4 | +# Not a secret, just an identifier - Wrangler reads it from the environment | ||
| 5 | +# (same id as infra/variables.tf). | ||
| 6 | +CLOUDFLARE_ACCOUNT_ID=d8149974c9ab26867fdc9cd579711d7d | ||
modified
flake.nix +10 -21 | @@ -100,28 +100,20 @@ | ||
| 100 | 100 | type = "app"; |
| 101 | 101 | program = "${pkgs.writeShellApplication { |
| 102 | 102 | name = "mykiwi-blog-deploy"; |
| 103 | - runtimeInputs = [ wrangler pkgs.git pkgs.gnused ]; | |
| 103 | + runtimeInputs = [ wrangler pkgs.git ]; | |
| 104 | 104 | text = '' |
| 105 | 105 | lang="''${1:?usage: nix run .#deploy -- <lang>}" |
| 106 | 106 | root="$(git rev-parse --show-toplevel)" |
| 107 | 107 | project="mykiwi-blog-$lang" |
| 108 | - # Pages deploy no longer accepts --config pointing at a custom | |
| 109 | - # path ("Pages does not support custom paths for the Wrangler | |
| 110 | - # configuration file"), so cd to where wrangler.toml lives and | |
| 111 | - # let Wrangler auto-discover it instead. | |
| 112 | - cd "$root" | |
| 113 | - # ...except Pages only *honours* a discovered wrangler.toml when it | |
| 114 | - # declares pages_build_output_dir, which ours can't: the directory | |
| 115 | - # differs per language (result/en, result/fr, ...) and is passed | |
| 116 | - # positionally below. So the account_id in wrangler.toml is read by | |
| 117 | - # nobody, and Wrangler falls back to asking the API which accounts | |
| 118 | - # the token can see. An account-scoped token lists none - the call | |
| 119 | - # succeeds and returns [] - and the deploy dies on "Failed to | |
| 120 | - # automatically retrieve account IDs", which reads like an expired | |
| 121 | - # token but isn't. Pass the id explicitly, still sourced from | |
| 122 | - # wrangler.toml so it stays the one place it's written down. | |
| 123 | - CLOUDFLARE_ACCOUNT_ID="$(sed -n 's/^account_id *= *"\(.*\)"/\1/p' "$root/wrangler.toml")" | |
| 124 | - export CLOUDFLARE_ACCOUNT_ID | |
| 108 | + # No wrangler.toml: Pages only honours one that declares | |
| 109 | + # pages_build_output_dir, which can't be a single directory | |
| 110 | + # across languages, so everything is passed explicitly instead. | |
| 111 | + # The account id has to be: an account-scoped token can't list | |
| 112 | + # accounts, and without it Wrangler dies on "Failed to | |
| 113 | + # automatically retrieve account IDs", which reads like an | |
| 114 | + # expired token but isn't. `make .env` puts it in .env, and | |
| 115 | + # `make deploy` exports it from there. | |
| 116 | + : "''${CLOUDFLARE_ACCOUNT_ID:?not set - run 'make .env' and deploy via 'make deploy'}" | |
| 125 | 117 | wrangler pages deploy "$root/result/$lang" --project-name="$project" --branch=main |
| 126 | 118 | ''; |
| 127 | 119 | }}/bin/mykiwi-blog-deploy"; |
| @@ -157,9 +149,6 @@ | ||
| 157 | 149 | echo "$dir does not exist - run 'make build' first." >&2 |
| 158 | 150 | exit 1 |
| 159 | 151 | fi |
| 160 | - # Same reason as deploy above: Pages insists on discovering | |
| 161 | - # wrangler.toml itself rather than being pointed at one. | |
| 162 | - cd "$root" | |
| 163 | 152 | # Pinned so the emulated runtime cannot drift between runs - |
| 164 | 153 | # bump it deliberately, the way you would a dependency. |
| 165 | 154 | wrangler pages dev "$dir" --port "$port" --compatibility-date=2026-09-03 |
| @@ -100,28 +100,20 @@ | |||
| 100 | type = "app"; | 100 | type = "app"; |
| 101 | program = "${pkgs.writeShellApplication { | 101 | program = "${pkgs.writeShellApplication { |
| 102 | name = "mykiwi-blog-deploy"; | 102 | name = "mykiwi-blog-deploy"; |
| 103 | - runtimeInputs = [ wrangler pkgs.git pkgs.gnused ]; | 103 | + runtimeInputs = [ wrangler pkgs.git ]; |
| 104 | text = '' | 104 | text = '' |
| 105 | lang="''${1:?usage: nix run .#deploy -- <lang>}" | 105 | lang="''${1:?usage: nix run .#deploy -- <lang>}" |
| 106 | root="$(git rev-parse --show-toplevel)" | 106 | root="$(git rev-parse --show-toplevel)" |
| 107 | project="mykiwi-blog-$lang" | 107 | project="mykiwi-blog-$lang" |
| 108 | - # Pages deploy no longer accepts --config pointing at a custom | 108 | + # No wrangler.toml: Pages only honours one that declares |
| 109 | - # path ("Pages does not support custom paths for the Wrangler | 109 | + # pages_build_output_dir, which can't be a single directory |
| 110 | - # configuration file"), so cd to where wrangler.toml lives and | 110 | + # across languages, so everything is passed explicitly instead. |
| 111 | - # let Wrangler auto-discover it instead. | 111 | + # The account id has to be: an account-scoped token can't list |
| 112 | - cd "$root" | 112 | + # accounts, and without it Wrangler dies on "Failed to |
| 113 | - # ...except Pages only *honours* a discovered wrangler.toml when it | 113 | + # automatically retrieve account IDs", which reads like an |
| 114 | - # declares pages_build_output_dir, which ours can't: the directory | 114 | + # expired token but isn't. `make .env` puts it in .env, and |
| 115 | - # differs per language (result/en, result/fr, ...) and is passed | 115 | + # `make deploy` exports it from there. |
| 116 | - # positionally below. So the account_id in wrangler.toml is read by | 116 | + : "''${CLOUDFLARE_ACCOUNT_ID:?not set - run 'make .env' and deploy via 'make deploy'}" |
| 117 | - # nobody, and Wrangler falls back to asking the API which accounts | ||
| 118 | - # the token can see. An account-scoped token lists none - the call | ||
| 119 | - # succeeds and returns [] - and the deploy dies on "Failed to | ||
| 120 | - # automatically retrieve account IDs", which reads like an expired | ||
| 121 | - # token but isn't. Pass the id explicitly, still sourced from | ||
| 122 | - # wrangler.toml so it stays the one place it's written down. | ||
| 123 | - CLOUDFLARE_ACCOUNT_ID="$(sed -n 's/^account_id *= *"\(.*\)"/\1/p' "$root/wrangler.toml")" | ||
| 124 | - export CLOUDFLARE_ACCOUNT_ID | ||
| 125 | wrangler pages deploy "$root/result/$lang" --project-name="$project" --branch=main | 117 | wrangler pages deploy "$root/result/$lang" --project-name="$project" --branch=main |
| 126 | ''; | 118 | ''; |
| 127 | }}/bin/mykiwi-blog-deploy"; | 119 | }}/bin/mykiwi-blog-deploy"; |
| @@ -157,9 +149,6 @@ | |||
| 157 | echo "$dir does not exist - run 'make build' first." >&2 | 149 | echo "$dir does not exist - run 'make build' first." >&2 |
| 158 | exit 1 | 150 | exit 1 |
| 159 | fi | 151 | fi |
| 160 | - # Same reason as deploy above: Pages insists on discovering | ||
| 161 | - # wrangler.toml itself rather than being pointed at one. | ||
| 162 | - cd "$root" | ||
| 163 | # Pinned so the emulated runtime cannot drift between runs - | 152 | # Pinned so the emulated runtime cannot drift between runs - |
| 164 | # bump it deliberately, the way you would a dependency. | 153 | # bump it deliberately, the way you would a dependency. |
| 165 | wrangler pages dev "$dir" --port "$port" --compatibility-date=2026-09-03 | 154 | wrangler pages dev "$dir" --port "$port" --compatibility-date=2026-09-03 |
deleted
wrangler.toml +0 -1 | deleted file mode 100644 | ||
| @@ -1 +0,0 @@ | ||
| 1 | -account_id = "d8149974c9ab26867fdc9cd579711d7d" | |
| deleted file mode 100644 | |||
| @@ -1 +0,0 @@ | |||
| 1 | -account_id = "d8149974c9ab26867fdc9cd579711d7d" | ||