Skip to content

Commit

Permalink
fix conventional commits version calcuation and include all conventio…
Browse files Browse the repository at this point in the history
…nally commited commits in changelog
  • Loading branch information
hipstersmoothie committed Jan 15, 2021
1 parent c8ea512 commit 5345303
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 23 deletions.
2 changes: 2 additions & 0 deletions packages/core/src/log-parse.ts
Expand Up @@ -61,6 +61,8 @@ export type IExtendedCommit = ICommit & {
pullRequest?: IPullRequest;
/** Labels associated with the commit */
labels: string[];
/** Whether to force include the commit in the changelog */
includeInChangelog?: boolean;
};

/** Parse the PR information for the merge commit message */
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/release.ts
Expand Up @@ -144,7 +144,9 @@ export default class Release {
);
const uniqueCommits = allCommits.filter(
(commit) =>
(commit.pullRequest || !allPrCommitHashes.includes(commit.hash)) &&
(commit.pullRequest ||
!allPrCommitHashes.includes(commit.hash) ||
commit.includeInChangelog === true) &&
!commit.subject.includes("[skip ci]")
);

Expand Down Expand Up @@ -200,8 +202,14 @@ export default class Release {
const index = commitsInRelease.findIndex(
(c) => c && c.hash === commit.hash
);
const normalized = await logParse.normalizeCommit(commit);

commitsInRelease[index] = await logParse.normalizeCommit(commit);
// If a commit has includeInChangelog keep the title
if (commit.includeInChangelog && normalized) {
normalized.subject = commit.subject;
}

commitsInRelease[index] = normalized;
})
);

Expand Down
Expand Up @@ -42,6 +42,7 @@ test("should add correct semver label to commit", async () => {
labels: defaultLabels,
semVerLabels: versionLabels,
logger: dummyLog(),
git: { getCommitsForPR: () => Promise.resolve([]) } as any,
} as Auto);

const logParseHooks = makeLogParseHooks();
Expand All @@ -52,6 +53,7 @@ test("should add correct semver label to commit", async () => {
const commit = makeCommitFromMsg("fix: normal commit with no bump");
expect(await logParseHooks.parseCommit.promise({ ...commit })).toStrictEqual({
...commit,
includeInChangelog: true,
labels: ["patch"],
});
});
Expand All @@ -64,6 +66,7 @@ test("should add correct semver label to commit - feat", async () => {
labels: defaultLabels,
semVerLabels: versionLabels,
logger: dummyLog(),
git: { getCommitsForPR: () => Promise.resolve([]) } as any,
} as Auto);

const logParseHooks = makeLogParseHooks();
Expand All @@ -74,6 +77,7 @@ test("should add correct semver label to commit - feat", async () => {
const commit = makeCommitFromMsg("feat: normal commit with no bump");
expect(await logParseHooks.parseCommit.promise({ ...commit })).toStrictEqual({
...commit,
includeInChangelog: true,
labels: ["minor"],
});
});
Expand All @@ -86,6 +90,7 @@ test("should add major semver label to commit", async () => {
labels: defaultLabels,
semVerLabels: versionLabels,
logger: dummyLog(),
git: { getCommitsForPR: () => Promise.resolve([]) } as any,
} as Auto);

const logParseHooks = makeLogParseHooks();
Expand All @@ -96,6 +101,7 @@ test("should add major semver label to commit", async () => {
const commit = makeCommitFromMsg("BREAKING: normal commit with no bump");
expect(await logParseHooks.parseCommit.promise({ ...commit })).toStrictEqual({
...commit,
includeInChangelog: true,
labels: ["major"],
});
});
Expand All @@ -108,6 +114,7 @@ test("should add major semver label to commit - !", async () => {
labels: defaultLabels,
semVerLabels: versionLabels,
logger: dummyLog(),
git: { getCommitsForPR: () => Promise.resolve([]) } as any,
} as Auto);

const logParseHooks = makeLogParseHooks();
Expand All @@ -118,11 +125,12 @@ test("should add major semver label to commit - !", async () => {
const commit = makeCommitFromMsg("feat!: normal commit with no bump");
expect(await logParseHooks.parseCommit.promise({ ...commit })).toStrictEqual({
...commit,
includeInChangelog: true,
labels: ["major"],
});
});

test("should not include label-less head commit if any other commit in PR has conventional commit message", async () => {
test("should not include label-less head commit if all other commit in PR has skip", async () => {
const commit = makeCommitFromMsg("Merge pull request #123 from some-pr\n\n");
const conventionalCommitsPlugin = new ConventionalCommitsPlugin();
const logParse = new LogParse();
Expand All @@ -134,7 +142,10 @@ test("should not include label-less head commit if any other commit in PR has co
getFirstCommit: jest.fn(),
getPr: jest.fn(),
getCommitsForPR: () =>
Promise.resolve([{ sha: "1", commit: { message: "fix: child commit" } }]),
Promise.resolve([
{ sha: "1", commit: { message: "chore: child commit" } },
{ sha: "2", commit: { message: "chore: another commit" } },
]),
} as unknown) as Git;
conventionalCommitsPlugin.apply({
hooks: autoHooks,
Expand Down Expand Up @@ -294,6 +305,7 @@ test("should skip when not a fix/feat/breaking change commit", async () => {
labels: defaultLabels,
semVerLabels: versionLabels,
logger: dummyLog(),
git: { getCommitsForPR: () => Promise.resolve([]) } as any,
} as Auto);

const logParseHooks = makeLogParseHooks();
Expand All @@ -304,6 +316,7 @@ test("should skip when not a fix/feat/breaking change commit", async () => {
const commit = makeCommitFromMsg("chore: i should not trigger a release");
expect(await logParseHooks.parseCommit.promise({ ...commit })).toStrictEqual({
...commit,
includeInChangelog: true,
labels: ["skip-release"],
});
});
61 changes: 42 additions & 19 deletions plugins/conventional-commits/src/index.ts
Expand Up @@ -137,18 +137,11 @@ export default class ConventionalCommitsPlugin implements IPlugin {

auto.hooks.onCreateLogParse.tap(this.name, (logParse) => {
logParse.hooks.parseCommit.tapPromise(this.name, async (commit) => {
if (!auto.semVerLabels) {
if (!auto.semVerLabels || !auto.git) {
return commit;
}

try {
const label = await getBump(`${commit.subject}\n\n${commit.rawBody}`);

if (!label) {
return commit;
}

const incrementLabel = auto.semVerLabels.get(label);
const allSemVerLabels = [
auto.semVerLabels.get(SEMVER.major),
auto.semVerLabels.get(SEMVER.minor),
Expand All @@ -158,10 +151,40 @@ export default class ConventionalCommitsPlugin implements IPlugin {
[]
);

let bump = await getBump(`${commit.subject}\n\n${commit.rawBody}`);

if (
incrementLabel &&
!commit.labels.some((l) => allSemVerLabels.includes(l))
!bump &&
commit.pullRequest &&
!commit.labels.some(l => allSemVerLabels.includes(l))
) {
const prCommits = await auto.git.getCommitsForPR(
commit.pullRequest.number
);
const prBumps = (
await Promise.all(prCommits.map((c) => getBump(c.commit.message)))
).filter((bump): bump is
| SEMVER.major
| SEMVER.minor
| SEMVER.patch => Boolean(bump && bump !== "skip"));

if (prBumps.includes(SEMVER.major)) {
bump = SEMVER.major;
} else if (prBumps.includes(SEMVER.minor)) {
bump = SEMVER.minor;
} else if (prBumps.includes(SEMVER.patch)) {
bump = SEMVER.patch;
}
}

if (!bump) {
return commit;
}

const incrementLabel = auto.semVerLabels.get(bump);

if (incrementLabel && !commit.labels.some(l => allSemVerLabels.includes(l))) {
commit.includeInChangelog = true;
commit.labels = [...commit.labels, incrementLabel[0]];
}
} catch (error) {
Expand All @@ -184,22 +207,22 @@ export default class ConventionalCommitsPlugin implements IPlugin {
const prCommits = await auto.git.getCommitsForPR(
commit.pullRequest.number
);
let shouldOmit = false;

// Omit the commit if one of the commits in the PR contains a CC message since it will already be counted
await Promise.all(
const bumps = await Promise.all(
prCommits.map(async (c) => {
try {
const label = await getBump(c.commit.message);

if (label) {
shouldOmit = true;
}
return label;
} catch (error) {}
})
);

return shouldOmit;
// Omit the commit if all of the commits in the PR contains a skip message
return (
bumps.filter((bump): bump is
| SEMVER.major
| SEMVER.minor
| SEMVER.patch => Boolean(bump === "skip")).length > 0
);
}
});
});
Expand Down

0 comments on commit 5345303

Please sign in to comment.