Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/commands/audience/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default class AudiencePush extends BaseCommand<typeof AudiencePush> {
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down Expand Up @@ -102,6 +103,7 @@ export default class AudiencePush extends BaseCommand<typeof AudiencePush> {
type: "static" | "dynamic";
},
},
{ query: flags.force ? { force: true } : undefined },
);

// Update the audience directory with the successfully pushed audience
Expand Down
1 change: 1 addition & 0 deletions src/commands/guide/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default class GuidePush extends BaseCommand<typeof GuidePush> {
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
1 change: 1 addition & 0 deletions src/commands/layout/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default class EmailLayoutPush extends BaseCommand<
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
1 change: 1 addition & 0 deletions src/commands/message-type/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class MessageTypePush extends BaseCommand<
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
1 change: 1 addition & 0 deletions src/commands/partial/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default class PartialPush extends BaseCommand<typeof PartialPush> {
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
2 changes: 2 additions & 0 deletions src/commands/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default class Push extends BaseCommand<typeof Push> {
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

async run(): Promise<void> {
Expand Down Expand Up @@ -75,6 +76,7 @@ export default class Push extends BaseCommand<typeof Push> {
...(flags["commit-message"]
? ["--commit-message", flags["commit-message"]]
: []),
...(flags.force ? ["--force"] : []),
];

// Note: Because we're pushing the different resource types sequentially,
Expand Down
1 change: 1 addition & 0 deletions src/commands/translation/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class TranslationPush extends BaseCommand<
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
1 change: 1 addition & 0 deletions src/commands/workflow/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default class WorkflowPush extends BaseCommand<typeof WorkflowPush> {
char: "m",
dependsOn: ["commit"],
}),
force: CustomFlags.force,
};

static args = {
Expand Down
6 changes: 6 additions & 0 deletions src/lib/api-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export default class ApiV1 {
annotate: flags.annotate,
commit: flags.commit,
commit_message: flags["commit-message"],
force: flags.force,
});
const data = { workflow };

Expand Down Expand Up @@ -253,6 +254,7 @@ export default class ApiV1 {
commit: flags.commit,
commit_message: flags["commit-message"],
namespace: translation.namespace,
force: flags.force,
});

return this.put(
Expand Down Expand Up @@ -318,6 +320,7 @@ export default class ApiV1 {
annotate: flags.annotate,
commit: flags.commit,
commit_message: flags["commit-message"],
force: flags.force,
});
const data = { email_layout: layout };

Expand Down Expand Up @@ -379,6 +382,7 @@ export default class ApiV1 {
annotate: flags.annotate,
commit: flags.commit,
commit_message: flags["commit-message"],
force: flags.force,
});
const data = { partial };

Expand Down Expand Up @@ -452,6 +456,7 @@ export default class ApiV1 {
annotate: flags.annotate,
commit: flags.commit,
commit_message: flags["commit-message"],
force: flags.force,
});
const data = { message_type: messageType };

Expand Down Expand Up @@ -529,6 +534,7 @@ export default class ApiV1 {
annotate: flags.annotate,
commit: flags.commit,
commit_message: flags["commit-message"],
force: flags.force,
});
const data = { guide };

Expand Down
6 changes: 6 additions & 0 deletions src/lib/helpers/flag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,9 @@ export const branch = slug({
// Using lodash's once avoids unnecessarily reading the branch file multiple times.
default: once(readSlugFromBranchFile),
});

export const force = Flags.boolean({
summary:
"Force pushes the resource or resources to Knock, overwriting whatever is currently stored. " +
"If you're using this on a non-development environment, you should also ensure you `commit` the changes.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this feel actionable enough as an instruction? Are we leaving it up to the users to do this or do we have some kind of guard around not messing this up?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so? You can run knock push --force without commit then you'd just need to commit the changes in your non dev env, like you have to already in dev.

});
21 changes: 21 additions & 0 deletions test/commands/audience/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,27 @@ describe("commands/audience/push", () => {
);
});

setupWithStub()
.stdout()
.command(["audience push", "default", "--force"])
.it("calls apiV1 upsertAudience with force flag, if provided", () => {
sinon.assert.calledWith(
KnockMgmt.Audiences.prototype.upsert as sinon.SinonStub,
"default",
sinon.match({
environment: "development",
annotate: true,
audience: sinon.match({
name: "Default",
type: "static",
}),
}),
sinon.match({
query: { force: true },
}),
);
});

setupWithStub()
.stdout()
.command([
Expand Down
37 changes: 37 additions & 0 deletions test/commands/guide/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,43 @@ describe("commands/guide/push", () => {
);
});

setupWithStub({ data: { guide: mockGuideData } })
.stdout()
.command(["guide push", "welcome-guide", "--force"])
.it("calls apiV1 upsertGuide with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertGuide as any,
sinon.match(
({ args, flags }) =>
isEqual(args, { guideKey: "welcome-guide" }) &&
isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
annotate: true,
}),
),
sinon.match((guide) =>
isEqual(guide, {
key: "welcome-guide",
name: "Welcome Guide",
description: "A guide to help new users get started",
channel_key: "in-app-guide",
type: "banner",
steps: [
{
ref: "step_1",
name: "Welcome Step",
schema_key: "banner",
schema_variant_key: "default",
fields: [],
},
],
}),
),
);
});

setupWithStub({ data: { guide: mockGuideData } })
.stdout()
.command([
Expand Down
25 changes: 25 additions & 0 deletions test/commands/layout/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,31 @@ describe("commands/layout/push", () => {
});
});

setupWithStub({ data: { email_layout: mockEmailLayoutData } })
.stdout()
.command(["layout push", "default", "--force"])
.it("calls apiV1 upsertEmailLayout with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertEmailLayout as any,
sinon.match(
({ args, flags }) =>
isEqual(args, { emailLayoutKey: "default" }) &&
isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
annotate: true,
}),
),
sinon.match((layout) =>
isEqual(layout, {
key: "default",
name: "Default",
}),
),
);
});

setupWithStub({ data: { email_layout: mockEmailLayoutData } })
.stdout()
.command([
Expand Down
40 changes: 40 additions & 0 deletions test/commands/message-type/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,46 @@ describe("commands/message-type/push", () => {
);
});

setupWithStub({ data: { message_type: mockMessageTypeData } })
.stdout()
.command(["message-type push", "banner", "--force"])
.it("calls apiV1 upsertMessageType with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertMessageType as any,
sinon.match(
({ args, flags }) =>
isEqual(args, { messageTypeKey: "banner" }) &&
isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
annotate: true,
}),
),
sinon.match((messageType) =>
isEqual(messageType, {
key: "banner",
name: "Banner",
description: "My little banner",
variants: [
{
key: "default",
name: "Default",
fields: [
{
type: "text",
key: "title",
label: "Title",
},
],
},
],
preview: "<div>{{ title }}</div>",
}),
),
);
});

setupWithStub({ data: { message_type: mockMessageTypeData } })
.stdout()
.command([
Expand Down
25 changes: 25 additions & 0 deletions test/commands/partial/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,31 @@ describe("commands/partial/push", () => {
);
});

setupWithStub({ data: { partial: mockPartialData } })
.stdout()
.command(["partial push", "default", "--force"])
.it("calls apiV1 upsertPartial with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertPartial as any,
sinon.match(
({ args, flags }) =>
isEqual(args, { partialKey: "default" }) &&
isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
annotate: true,
}),
),
sinon.match((partial) =>
isEqual(partial, {
key: "default",
name: "Default",
}),
),
);
});

setupWithStub({ data: { partial: mockPartialData } })
.stdout()
.command([
Expand Down
22 changes: 22 additions & 0 deletions test/commands/translation/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,28 @@ describe("commands/translation/push", () => {
);
});

setupWithStub()
.stdout()
.command(["translation push", "admin.en", "--force"])
.it("calls apiV1 upsertTranslation with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertTranslation as any,
sinon.match(({ flags }) => {
return isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
});
}),
sinon.match({
content: '{"welcome":"hello!"}',
locale_code: "en",
namespace: "admin",
format: "json",
}),
);
});

setupWithStub()
.stdout()
.command([
Expand Down
25 changes: 25 additions & 0 deletions test/commands/workflow/push.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,31 @@ describe("commands/workflow/push", () => {
);
});

setupWithStub({ data: { workflow: mockWorkflowData } })
.stdout()
.command(["workflow push", "new-comment", "--force"])
.it("calls apiV1 upsertWorkflow with force flag, if provided", () => {
sinon.assert.calledWith(
KnockApiV1.prototype.upsertWorkflow as any,
sinon.match(
({ args, flags }) =>
isEqual(args, { workflowKey: "new-comment" }) &&
isEqual(flags, {
"service-token": "valid-token",
environment: "development",
force: true,
annotate: true,
}),
),
sinon.match((workflow) =>
isEqual(workflow, {
key: "new-comment",
name: "New comment",
}),
),
);
});

setupWithStub({ data: { workflow: mockWorkflowData } })
.stdout()
.command(["workflow push", "new-comment"])
Expand Down
Loading