Skip to content

Commit

Permalink
DEVPROD-6249: Automatically assign release version to deploy (#409)
Browse files Browse the repository at this point in the history
  • Loading branch information
SupaJoon authored Oct 2, 2024
1 parent 6646bfd commit 0009da0
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 22 deletions.
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DEVPROD-NNNNN
<!-- Does this PR have a minor or major SemVer version change? Include [minor] or [major] in the title ☝️ -->
<!-- Does this PR need a 🔵Spruce or 🟢Parsley label? Add it in the sidebar 👉 -->

### Description
Expand Down
19 changes: 4 additions & 15 deletions packages/deploy-utils/src/prepare-prod-deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
deleteTag,
getLatestTag,
pushTags,
getReleaseVersion,
} from "../utils/git";

/**
Expand Down Expand Up @@ -66,19 +67,7 @@ export const prepareProdDeploy = async () => {

console.log(`Commit messages:\n${commitMessages}`);

const { value: version } = await prompts({
type: "select",
name: "value",
message: "How should this deploy be versioned?",
choices: [
{ title: "Patch", value: "patch" },
{ title: "Minor", value: "minor" },
{ title: "Major", value: "major" },
],
initial: 0,
});

if (version) {
createTagAndPush(version);
}
const version = getReleaseVersion(commitMessages);
console.log(`This deploy is a ${version} release.`);
createTagAndPush(version);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
deleteTag,
getLatestTag,
pushTags,
getReleaseVersion,
ReleaseVersion,
} from "../utils/git";

const mockCommit = "0000011111222223333344444555556666677777";
Expand Down Expand Up @@ -54,13 +56,10 @@ describe("prepareProdDeploy", () => {
vi.mocked(getCurrentlyDeployedCommit).mockResolvedValue(
"0000011111222223333344444555556666677777",
);
vi.mocked(getReleaseVersion).mockReturnValue(ReleaseVersion.Patch);
});

it("creates tag with patch", async () => {
vi.mocked(prompts).mockResolvedValueOnce({
title: "Patch",
value: "patch",
});
const consoleSpy = vi.spyOn(console, "log").mockImplementation(vi.fn());
await prepareProdDeploy();
expect(vi.mocked(getCurrentlyDeployedCommit)).toHaveBeenCalledWith(
Expand All @@ -77,6 +76,12 @@ describe("prepareProdDeploy", () => {
`Commit messages:
my commit messages`,
);
expect(vi.mocked(getReleaseVersion)).toHaveBeenCalledWith(
"my commit messages",
);
expect(consoleSpy).toHaveBeenCalledWith(
"This deploy is a patch release.",
);
expect(vi.mocked(createTagAndPush)).toHaveBeenCalledTimes(1);
expect(vi.mocked(createTagAndPush)).toHaveBeenCalledWith("patch");
});
Expand Down
35 changes: 34 additions & 1 deletion packages/deploy-utils/src/utils/git/tag.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getLatestTag, tagIsValid } from ".";
import { getLatestTag, getReleaseVersion, tagIsValid } from ".";

describe("tagIsValid", () => {
it("should match on a known valid tag", () => {
Expand All @@ -23,3 +23,36 @@ describe("getLatestTag", () => {
expect(tagIsValid(app, latestTag)).toEqual(true);
});
});

describe("getReleaseVersion", () => {
it("major has precedence over minor and patch", () => {
const commitMessages = `
DEVPROD-10186: Add waterfall active version labels [minor] (#399)
DEVPROD-828: Add multisort to TaskDurationTable [major] (#406)
DEVPROD-9268: Remove secrets from .env-cmdrc.json [minor] (#391)
704ef79b DEVPROD-7340 Move ConditionalWrapper to lib and setup vitest for jsdom testing in lib (#398)
`;
const releaseVersion = getReleaseVersion(commitMessages);
expect(releaseVersion).toEqual("major");
});
it("minor has precedence over patch", () => {
const commitMessages = `
DEVPROD-10186: Add waterfall active version labels [minor] (#399)
DEVPROD-828: Add multisort to TaskDurationTable (#406)
DEVPROD-9268: Remove secrets from .env-cmdrc.json [minor] (#391)
704ef79b DEVPROD-7340 Move ConditionalWrapper to lib and setup vitest for jsdom testing in lib (#398)
`;
const releaseVersion = getReleaseVersion(commitMessages);
expect(releaseVersion).toEqual("minor");
});
it("patch is the default value when no version label exists", () => {
const commitMessages = `
DEVPROD-10186: Add waterfall active version labels (#399)
DEVPROD-828: Add multisort to TaskDurationTable (#406)
DEVPROD-9268: Remove secrets from .env-cmdrc.json (#391)
704ef79b DEVPROD-7340 Move ConditionalWrapper to lib and setup vitest for jsdom testing in lib (#398)
`;
const releaseVersion = getReleaseVersion(commitMessages);
expect(releaseVersion).toEqual("patch");
});
});
33 changes: 31 additions & 2 deletions packages/deploy-utils/src/utils/git/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ import { execSync } from "child_process";
import { execTrim, green, underline } from "../shell";
import { DeployableApp } from "../types";

enum ReleaseVersion {
Patch = "patch",
Minor = "minor",
Major = "major",
}

/**
* `createTagAndPush` is a helper function that creates a new tag.
* Pushing occurs in the postversion hook triggered by "yarn version"
* @param version - version indicates the type of upgrade of the new tag.
*/
const createTagAndPush = (version: "patch" | "minor" | "major") => {
const createTagAndPush = (version: ReleaseVersion) => {
console.log("Creating new tag...");
try {
execSync(`yarn version --new-version ${version}`, {
Expand All @@ -28,6 +34,21 @@ const createTagAndPush = (version: "patch" | "minor" | "major") => {
);
};

/**
* `getReleaseVersion` is a helper function that gets the release version from commit messages.
* @param commitMessages - commit messages to parse
* @returns - the release version
*/
const getReleaseVersion = (commitMessages: string): ReleaseVersion => {
let version = ReleaseVersion.Patch;
if (/\[major\]/i.test(commitMessages)) {
version = ReleaseVersion.Major;
} else if (/\[minor\]/i.test(commitMessages)) {
version = ReleaseVersion.Minor;
}
return version;
};

/**
* `getLatestTag` is a helper function that returns the latest tag.
* @param app - name of the app to be deployed
Expand Down Expand Up @@ -84,4 +105,12 @@ const pushTags = () => {
const tagIsValid = (app: DeployableApp, matchString: string) =>
new RegExp(`${app}/v\\d+.\\d+.\\d+`).test(matchString);

export { createTagAndPush, deleteTag, getLatestTag, pushTags, tagIsValid };
export {
createTagAndPush,
deleteTag,
getLatestTag,
getReleaseVersion,
pushTags,
tagIsValid,
ReleaseVersion,
};

0 comments on commit 0009da0

Please sign in to comment.