Skip to content

Commit

Permalink
fix: require worker name for rollback (#4588)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbbot authored Dec 22, 2023
1 parent 4864013 commit 4e5ed0b
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 43 deletions.
7 changes: 7 additions & 0 deletions .changeset/tasty-experts-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

fix: require worker name for rollback

Previously, Wrangler would fail with a cryptic error if you tried to run `wrangler rollback` outside of a directory containing a Wrangler configuration file with a `name` defined. This change validates that a worker name is defined, and allows you to set it from the command line using the `--name` flag.
91 changes: 71 additions & 20 deletions packages/wrangler/src/__tests__/deployments.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from "node:fs";
import { rest } from "msw";
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
import { mockConsoleMethods } from "./helpers/mock-console";
Expand All @@ -16,6 +17,12 @@ import { runInTempDir } from "./helpers/run-in-tmp";
import { runWrangler } from "./helpers/run-wrangler";
import writeWranglerToml from "./helpers/write-wrangler-toml";

function isFileNotFound(e: unknown) {
return (
typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT"
);
}

describe("deployments", () => {
const std = mockConsoleMethods();
runInTempDir();
Expand All @@ -35,6 +42,13 @@ describe("deployments", () => {
...mswSuccessDeploymentDetails
);
});
afterEach(() => {
try {
fs.unlinkSync("wrangler.toml");
} catch (e) {
if (!isFileNotFound(e)) throw e;
}
});

it("should log a help message for deployments command", async () => {
await runWrangler("deployments --help");
Expand Down Expand Up @@ -71,24 +85,24 @@ describe("deployments", () => {
"🚧\`wrangler deployments\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Deployment ID: Constitution-Class
Deployment ID: Constitution-Class-tag:test-name
Created on: 2021-01-01T00:00:00.000000Z
Author: [email protected]
Source: Upload from Wrangler 🤠
Deployment ID: Intrepid-Class
Deployment ID: Intrepid-Class-tag:test-name
Created on: 2021-02-02T00:00:00.000000Z
Author: [email protected]
Source: Rollback from Wrangler 🤠
Rollback from: MOCK-DEPLOYMENT-ID-1111
Message: Rolled back for this version
Deployment ID: 3mEgaU1T-Intrepid-someThing
Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Created on: 2021-02-03T00:00:00.000000Z
Author: [email protected]
Source: Wrangler 🤠
Deployment ID: Galaxy-Class
Deployment ID: Galaxy-Class-tag:test-name
Created on: 2021-01-04T00:00:00.000000Z
Author: [email protected]
Source: Rollback from Wrangler 🤠
Expand All @@ -103,24 +117,24 @@ describe("deployments", () => {
"🚧\`wrangler deployments\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Deployment ID: Constitution-Class
Deployment ID: Constitution-Class-tag:something-else
Created on: 2021-01-01T00:00:00.000000Z
Author: [email protected]
Source: Upload from Wrangler 🤠
Deployment ID: Intrepid-Class
Deployment ID: Intrepid-Class-tag:something-else
Created on: 2021-02-02T00:00:00.000000Z
Author: [email protected]
Source: Rollback from Wrangler 🤠
Rollback from: MOCK-DEPLOYMENT-ID-1111
Message: Rolled back for this version
Deployment ID: 3mEgaU1T-Intrepid-someThing
Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:something-else
Created on: 2021-02-03T00:00:00.000000Z
Author: [email protected]
Source: Wrangler 🤠
Deployment ID: Galaxy-Class
Deployment ID: Galaxy-Class-tag:something-else
Created on: 2021-01-04T00:00:00.000000Z
Author: [email protected]
Source: Rollback from Wrangler 🤠
Expand Down Expand Up @@ -220,8 +234,8 @@ describe("deployments", () => {
rest.put(
"*/accounts/:accountID/workers/scripts/:scriptName",
(req, res, ctx) => {
expect(req.url.searchParams.get("rollback_to")).toBe(
"3mEgaU1T-Intrepid-someThing"
expect(req.url.searchParams.get("rollback_to")).toMatch(
/^3mEgaU1T-Intrepid-someThing-tag:/
);

requests.count++;
Expand Down Expand Up @@ -266,12 +280,13 @@ describe("deployments", () => {
result: "",
});

await runWrangler("rollback 3mEgaU1T-Intrepid-someThing");
writeWranglerToml();
await runWrangler("rollback 3mEgaU1T-Intrepid-someThing-tag:test-name");
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Current Deployment ID: galactic_mission_alpha"
`);

Expand All @@ -284,7 +299,8 @@ describe("deployments", () => {
result: false,
});

await runWrangler("rollback 3mEgaU1T-Intrpid-someThing");
writeWranglerToml();
await runWrangler("rollback 3mEgaU1T-Intrpid-someThing-tag:test-name");
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
"
Expand All @@ -296,7 +312,8 @@ describe("deployments", () => {
it("should skip prompt automatically in rollback if in a non-TTY environment", async () => {
setIsTTY(false);

await runWrangler("rollback 3mEgaU1T-Intrepid-someThing");
writeWranglerToml();
await runWrangler("rollback 3mEgaU1T-Intrepid-someThing-tag:test-name");
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Expand All @@ -305,37 +322,39 @@ describe("deployments", () => {
? Please provide a message for this rollback (120 characters max)
🤖 Using default value in non-interactive context:
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Current Deployment ID: galactic_mission_alpha"
`);

expect(requests.count).toEqual(1);
});

it("should skip prompt automatically in rollback if message flag is provided", async () => {
writeWranglerToml();
await runWrangler(
`rollback 3mEgaU1T-Intrepid-someThing --message "test"`
`rollback 3mEgaU1T-Intrepid-someThing-tag:test-name --message "test"`
);
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Current Deployment ID: galactic_mission_alpha"
`);

expect(requests.count).toEqual(1);
});

it("should skip prompt automatically in rollback with empty message", async () => {
writeWranglerToml();
await runWrangler(
`rollback 3mEgaU1T-Intrepid-someThing --message "test"`
`rollback 3mEgaU1T-Intrepid-someThing-tag:test-name --message "test"`
);
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Current Deployment ID: galactic_mission_alpha"
`);

Expand All @@ -353,12 +372,44 @@ describe("deployments", () => {
result: "",
});

writeWranglerToml();
await runWrangler("rollback");
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:test-name
Current Deployment ID: galactic_mission_alpha"
`);

expect(requests.count).toEqual(1);
});

it("should require a worker name", async () => {
await expect(runWrangler("rollback")).rejects.toMatchInlineSnapshot(
`[Error: Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with \`--name\`]`
);

expect(requests.count).toEqual(0);
});

it("should automatically rollback to previous deployment with specified name", async () => {
mockConfirm({
text: "This deployment 3mEgaU1T will immediately replace the current deployment and become the active deployment across all your deployed routes and domains. However, your local development environment will not be affected by this rollback. Note: Rolling back to a previous deployment will not rollback any of the bound resources (Durable Object, R2, KV, etc.).",
result: true,
});

mockPrompt({
text: "Please provide a message for this rollback (120 characters max)",
result: "",
});

await runWrangler("rollback --name something-else");
expect(std.out).toMatchInlineSnapshot(`
"🚧\`wrangler rollback\` is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose
Successfully rolled back to Deployment ID: 3mEgaU1T-Intrepid-someThing-tag:something-else
Current Deployment ID: galactic_mission_alpha"
`);

Expand Down
36 changes: 20 additions & 16 deletions packages/wrangler/src/__tests__/helpers/msw/handlers/deployments.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { rest } from "msw";
import { createFetchResult } from "../index";

const latestDeployment = {
id: "Galaxy-Class",
const latestDeployment = (scriptTag: string) => ({
id: `Galaxy-Class-${scriptTag}`,
number: "1701-E",
annotations: {
"workers/triggered_by": "rollback",
Expand All @@ -16,21 +16,22 @@ const latestDeployment = {
modified_on: "2021-01-04T00:00:00.000000Z",
},
resources: {
script: "MOCK-TAG",
script: scriptTag,
bindings: [],
},
};
});
export const mswSuccessDeployments = [
rest.get(
"*/accounts/:accountId/workers/deployments/by-script/:scriptTag",
(_, response, context) =>
response.once(
(request, response, context) => {
const scriptTag = String(request.params["scriptTag"]);
return response.once(
context.json(
createFetchResult({
latest: latestDeployment,
latest: latestDeployment(scriptTag),
items: [
{
id: "Constitution-Class",
id: `Constitution-Class-${scriptTag}`,
number: "1701-E",
annotations: {
"workers/triggered_by": "upload",
Expand All @@ -44,7 +45,7 @@ export const mswSuccessDeployments = [
},
},
{
id: "Intrepid-Class",
id: `Intrepid-Class-${scriptTag}`,
number: "NCC-74656",
annotations: {
"workers/triggered_by": "rollback",
Expand All @@ -60,7 +61,7 @@ export const mswSuccessDeployments = [
},
},
{
id: "3mEgaU1T-Intrepid-someThing",
id: `3mEgaU1T-Intrepid-someThing-${scriptTag}`,
number: "NCC-74656",
metadata: {
author_id: "Kathryn-Jane-Gamma-6-0-7-3",
Expand All @@ -70,23 +71,25 @@ export const mswSuccessDeployments = [
modified_on: "2021-02-03T00:00:00.000000Z",
},
},
latestDeployment,
latestDeployment(scriptTag),
],
})
)
)
);
}
),
];

export const mswSuccessDeploymentScriptMetadata = [
rest.get(
"*/accounts/:accountId/workers/services/:scriptName",
(_, res, ctx) => {
(req, res, ctx) => {
const tag = `tag:${req.params["scriptName"]}`;
return res.once(
ctx.json(
createFetchResult({
default_environment: {
script: { last_deployed_from: "wrangler", tag: "MOCK-TAG" },
script: { last_deployed_from: "wrangler", tag },
},
})
)
Expand All @@ -98,12 +101,13 @@ export const mswSuccessDeploymentScriptMetadata = [
export const mswSuccessDeploymentScriptAPI = [
rest.get(
"*/accounts/:accountId/workers/services/:scriptName",
(_, res, ctx) => {
(req, res, ctx) => {
const tag = `tag:${req.params["scriptName"]}`;
return res.once(
ctx.json(
createFetchResult({
default_environment: {
script: { last_deployed_from: "api", tag: "MOCK-TAG" },
script: { last_deployed_from: "api", tag },
},
})
)
Expand Down
13 changes: 6 additions & 7 deletions packages/wrangler/src/deployments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ export async function deployments(
scriptName: string | undefined,
{ send_metrics: sendMetrics }: { send_metrics?: Config["send_metrics"] } = {}
) {
if (!scriptName) {
throw new Error(
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name`"
);
}

await metrics.sendMetricsEvent(
"view deployments",
{ view: scriptName ? "single" : "all" },
Expand Down Expand Up @@ -162,7 +156,7 @@ export async function rollbackDeployment(

if (deploys.length < 2) {
throw new Error(
"Cannot rollback to previous deployment since there are less than 2 deployemnts"
"Cannot rollback to previous deployment since there are less than 2 deployments"
);
}

Expand Down Expand Up @@ -341,6 +335,11 @@ export async function commonDeploymentCMDSetup(
);

logger.log(`${deploymentsWarning}\n`);
if (!scriptName) {
throw new Error(
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name`"
);
}

return { accountId, scriptName, config };
}
Expand Down
4 changes: 4 additions & 0 deletions packages/wrangler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,10 @@ export function createCLIParser(argv: string[]) {
type: "string",
default: undefined,
})
.option("name", {
describe: "The name of your worker",
type: "string",
})
.epilogue(rollbackWarning),
async (rollbackYargs) => {
const { accountId, scriptName, config } = await commonDeploymentCMDSetup(
Expand Down

0 comments on commit 4e5ed0b

Please sign in to comment.