Skip to content

Commit 1a8088a

Browse files
authored
Enable provisioning by default (#11030)
* Enable provisioning * Create thirty-walls-film.md * remove .only * Update thirty-walls-film.md * Make experimental nature clearer * Make sure we don't write redirected config bindings to the user config file * remove only
1 parent 4bd4c29 commit 1a8088a

File tree

11 files changed

+309
-96
lines changed

11 files changed

+309
-96
lines changed

.changeset/thirty-walls-film.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
Enable automatic resource provisioning by default in Wrangler. This is still an experimental feature, but we're turning on the flag by default to make it easier for people to test it and try it out. You can disable the feature using the `--no-x-provision` flag. It currently works for R2, D1, and KV bindings.
6+
7+
To use this feature, add a binding to your config file _without_ a resource ID:
8+
9+
```jsonc
10+
{
11+
"kv_namespaces": [{ "binding": "MY_KV" }],
12+
"d1_databases": [{ "binding": "MY_DB" }],
13+
"r2_buckets": [{ "binding": "MY_R2" }]
14+
}
15+
```
16+
17+
`wrangler dev` will automatically create these resources for you locally, and when you next run `wrangler deploy` Wrangler will call the Cloudflare API to create the requested resources and link them to your Worker. They'll stay linked across deploys, and you don't need to add the resource IDs to the config file for future deploys to work. This is especially good for shared templates, which now no longer need to include account-specific resource ID when adding a binding.

packages/wrangler/e2e/provision.test.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
2828
const helper = new WranglerE2ETestHelper();
2929

3030
it("can run dev without resource ids", async () => {
31-
const worker = helper.runLongLived("wrangler dev --x-provision");
31+
const worker = helper.runLongLived("wrangler dev");
3232

3333
const { url } = await worker.waitForReady();
3434
await fetch(url);
@@ -76,12 +76,12 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
7676
});
7777

7878
it("can provision resources and deploy worker", async () => {
79-
const worker = helper.runLongLived(`wrangler deploy --x-provision`);
79+
const worker = helper.runLongLived(`wrangler deploy`);
8080
await worker.exitCode;
8181
const output = await worker.output;
8282
expect(normalize(output)).toMatchInlineSnapshot(`
8383
"Total Upload: xx KiB / gzip: xx KiB
84-
The following bindings need to be provisioned:
84+
Experimental: The following bindings need to be provisioned:
8585
Binding Resource
8686
env.KV KV Namespace
8787
env.D1 D1 Database
@@ -131,7 +131,7 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
131131
});
132132

133133
it("can inherit bindings on re-deploy and won't re-provision", async () => {
134-
const worker = helper.runLongLived(`wrangler deploy --x-provision`);
134+
const worker = helper.runLongLived(`wrangler deploy`);
135135
await worker.exitCode;
136136
const output = await worker.output;
137137
expect(normalize(output)).toMatchInlineSnapshot(`
@@ -155,16 +155,14 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
155155
await expect(response.text()).resolves.toEqual("Hello World!");
156156
});
157157
it("can inspect current bindings", async () => {
158-
const versionsRaw = await helper.run(
159-
`wrangler versions list --json --x-provision`
160-
);
158+
const versionsRaw = await helper.run(`wrangler versions list --json`);
161159

162160
const versions = JSON.parse(versionsRaw.stdout) as unknown[];
163161

164162
const latest = versions.at(-1) as { id: string };
165163

166164
const versionView = await helper.run(
167-
`wrangler versions view ${latest.id} --x-provision`
165+
`wrangler versions view ${latest.id}`
168166
);
169167

170168
expect(normalizeOutput(versionView.output)).toMatchInlineSnapshot(`
@@ -198,31 +196,29 @@ describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)(
198196
binding = "KV2"
199197
`,
200198
});
201-
const worker = helper.runLongLived(
202-
`wrangler versions upload --x-provision`
203-
);
199+
const worker = helper.runLongLived(`wrangler versions upload`);
204200
await worker.exitCode;
205201
const output = await worker.output;
206202
expect(normalize(output)).toMatchInlineSnapshot(`
207-
"Total Upload: xx KiB / gzip: xx KiB
208-
The following bindings need to be provisioned:
209-
Binding Resource
210-
env.KV2 KV Namespace
211-
Provisioning KV2 (KV Namespace)...
212-
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv2"...
213-
✨ KV2 provisioned 🎉
214-
🎉 All resources provisioned, continuing with deployment...
215-
Worker Startup Time: (TIMINGS)
216-
Your Worker has access to the following bindings:
217-
Binding Resource
218-
env.KV2 (00000000000000000000000000000000) KV Namespace
219-
env.R2 (inherited) R2 Bucket
220-
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
221-
Worker Version ID: 00000000-0000-0000-0000-000000000000
222-
To deploy this version to production traffic use the command wrangler versions deploy
223-
Changes to non-versioned settings (config properties 'logpush' or 'tail_consumers') take effect after your next deployment using the command wrangler versions deploy
224-
Changes to triggers (routes, custom domains, cron schedules, etc) must be applied with the command wrangler triggers deploy"
225-
`);
203+
"Total Upload: xx KiB / gzip: xx KiB
204+
Experimental: The following bindings need to be provisioned:
205+
Binding Resource
206+
env.KV2 KV Namespace
207+
Provisioning KV2 (KV Namespace)...
208+
🌀 Creating new KV Namespace "tmp-e2e-worker-00000000-0000-0000-0000-000000000000-kv2"...
209+
✨ KV2 provisioned 🎉
210+
🎉 All resources provisioned, continuing with deployment...
211+
Worker Startup Time: (TIMINGS)
212+
Your Worker has access to the following bindings:
213+
Binding Resource
214+
env.KV2 (00000000000000000000000000000000) KV Namespace
215+
env.R2 (inherited) R2 Bucket
216+
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
217+
Worker Version ID: 00000000-0000-0000-0000-000000000000
218+
To deploy this version to production traffic use the command wrangler versions deploy
219+
Changes to non-versioned settings (config properties 'logpush' or 'tail_consumers') take effect after your next deployment using the command wrangler versions deploy
220+
Changes to triggers (routes, custom domains, cron schedules, etc) must be applied with the command wrangler triggers deploy"
221+
`);
226222
const kvMatch = output.match(/env.KV2 \((?<kv>[0-9a-f]{32})/);
227223
assert(kvMatch?.groups);
228224
kvId2 = kvMatch.groups.kv;

packages/wrangler/src/__tests__/deploy.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
mockOAuthFlow,
4040
} from "./helpers/mock-oauth-flow";
4141
import { mockUploadWorkerRequest } from "./helpers/mock-upload-worker";
42+
import { mockGetSettings } from "./helpers/mock-worker-settings";
4243
import {
4344
mockGetWorkerSubdomain,
4445
mockSubDomainRequest,
@@ -105,7 +106,16 @@ describe("deploy", () => {
105106
mockLastDeploymentRequest();
106107
mockDeploymentsListRequest();
107108
mockPatchScriptSettings();
109+
mockGetSettings();
108110
msw.use(...mswListNewDeploymentsLatestFull);
111+
// Pretend all R2 buckets exist for the purposes of deployment testing.
112+
// Otherwise, wrangler deploy would try to provision them. The provisioning
113+
// behaviour is tested in provision.test.ts
114+
msw.use(
115+
http.get("*/accounts/:accountId/r2/buckets/:bucketName", async () => {
116+
return HttpResponse.json(createFetchResult({}));
117+
})
118+
);
109119
});
110120

111121
afterEach(() => {
@@ -1104,6 +1114,7 @@ describe("deploy", () => {
11041114
});
11051115

11061116
await runWrangler("deploy index.js --env some-env --legacy-env false");
1117+
11071118
expect(std.out).toMatchInlineSnapshot(`
11081119
"
11091120
⛅️ wrangler x.x.x
@@ -14364,6 +14375,7 @@ export default{
1436414375
msw.use(...mswListNewDeploymentsLatestFull);
1436514376

1436614377
mockSubDomainRequest();
14378+
mockGetSettings();
1436714379
writeWorkerSource();
1436814380
setIsTTY(false);
1436914381
});

packages/wrangler/src/__tests__/dev/remote-bindings.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,10 +729,13 @@ describe("dev with remote bindings", { sequential: true }, () => {
729729
),
730730
"index.js": `export default { fetch() { return new Response("hello") } }`,
731731
});
732-
const wranglerStopped = runWrangler("dev --port=0 --inspector-port=0");
732+
const wranglerStopped = runWrangler(
733+
"dev --x-provision=false --port=0 --inspector-port=0"
734+
);
733735
await vi.waitFor(() => expect(std.out).toMatch(/Ready/), {
734736
timeout: 2_000,
735737
});
738+
736739
expect(sessionOptions).toEqual({
737740
auth: {
738741
accountId: "mock-account-id",
@@ -743,7 +746,9 @@ describe("dev with remote bindings", { sequential: true }, () => {
743746
complianceRegion: undefined,
744747
workerName: "worker",
745748
});
749+
746750
await stopWrangler();
751+
747752
await wranglerStopped;
748753
});
749754
});

packages/wrangler/src/__tests__/experimental-commands-api.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe("experimental_getWranglerCommands", () => {
4141
"alias": Array [
4242
"x-provision",
4343
],
44+
"default": true,
4445
"describe": "Experimental: Enable automatic resource provisioning",
4546
"hidden": true,
4647
"type": "boolean",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { http, HttpResponse } from "msw";
2+
import { msw } from "./msw";
3+
import type { Settings } from "../../deployment-bundle/bindings";
4+
5+
export function mockGetSettings(
6+
options: {
7+
result?: Settings;
8+
assertAccountId?: string;
9+
assertScriptName?: string;
10+
} = {}
11+
) {
12+
msw.use(
13+
http.get(
14+
"*/accounts/:accountId/workers/scripts/:scriptName/settings",
15+
async ({ params }) => {
16+
if (options.assertAccountId) {
17+
expect(params.accountId).toEqual(options.assertAccountId);
18+
}
19+
20+
if (options.assertScriptName) {
21+
expect(params.scriptName).toEqual(options.assertScriptName);
22+
}
23+
24+
if (!options.result) {
25+
return new Response(null, { status: 404 });
26+
}
27+
28+
return HttpResponse.json({
29+
success: true,
30+
errors: [],
31+
messages: [],
32+
result: options.result,
33+
});
34+
}
35+
)
36+
);
37+
}

packages/wrangler/src/__tests__/metrics.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ describe("metrics", () => {
198198
command: "wrangler docs",
199199
args: {
200200
xRemoteBindings: true,
201+
xProvision: true,
201202
xAutoCreate: true,
202203
search: ["<REDACTED>"],
203204
},

0 commit comments

Comments
 (0)