Skip to content

Commit

Permalink
build(changelog): fixed some more changelog/release behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Feb 13, 2021
1 parent 3f6e866 commit e11c0ea
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 110 deletions.
206 changes: 114 additions & 92 deletions packages/dev-utils/changelog.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const GROUPS = [
'Features',
'Documentation',
'Performance Improvements',
'Refactoring',
'Other Internal Changes',
];

Expand All @@ -31,19 +30,8 @@ function getCommitType({ type, scope, revert }) {
return 'Performance Improvements';
case 'docs':
return 'Documentation';
case 'style':
return 'Styles';
case 'refactor':
return 'Refactoring';
case 'test':
return 'Tests';
case 'build':
case 'ci':
return 'Build System';
case 'chore':
return 'Other Internal Changes';
default:
return type;
return 'Other Internal Changes';
}
}

Expand Down Expand Up @@ -85,94 +73,128 @@ function tokenize(subject) {
.replace(/([a-z][A-z]+Props)/g, '`$1`');
}

const parserOpts = {
headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
headerCorrespondence: ['type', 'scope', 'subject'],
noteKeywords: ['BREAKING CHANGE'],
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
revertCorrespondence: ['header', 'hash'],
};

const writerOpts = {
transform: (commit, context) => {
// don't want to show the release tag in changelog
if (commit.scope === 'release') {
return;
}

const issues = [];
let isBreaking = false;
commit.notes.forEach((note) => {
isBreaking = false;
note.title = 'BREAKING CHANGES';
});

commit.type = getCommitType(commit);
commit.scope = getCommitScope(commit);
if (!isBreaking && (!commit.type || commit.scope.includes('deps'))) {
// don't include un-typed commits in changelogs or deps
return;
}

if (typeof commit.hash === 'string') {
commit.shortHash = commit.hash.substring(0, 7);
}

if (typeof commit.subject === 'string') {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl;

if (url) {
url = `${url}/issues/`;
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
issues.push(issue);
return `[#${issue}](${url}${issue})`;
});
}

commit.subject = tokenize(commit.subject);
}

// remove references that already appear in the subject
commit.references = commit.references.filter(
(reference) => !issues.includes(reference.issue)
);

return commit;
},
groupBy: 'type',
commitGroupsSort: function (a, b) {
const aIndex = GROUPS.indexOf(a.title);
const bIndex = GROUPS.indexOf(b.title);
if (aIndex !== -1 && bIndex !== -1) {
return aIndex - bIndex;
}

return a.title.localeCompare(b.title);
},
commitsSort: ['scope', 'subject'],
noteGroupsSort: 'title',
mainTemplate: readFileSync(
resolve(__dirname, './templates/template.hbs'),
'utf-8'
),
headerPartial: readFileSync(
resolve(__dirname, './templates/header.hbs'),
'utf-8'
),
commitPartial: readFileSync(
resolve(__dirname, './templates/commit.hbs'),
'utf-8'
),
footerPartial: readFileSync(
resolve(__dirname, './templates/footer.hbs'),
'utf-8'
),
};

/**
* This is basically the conventional-changelog-angular with a few changes to
* allow more commit messages to appear. I also "tokenize" known packages and
* exports from react-md in the changelogs.
*/
module.exports = {
parserOpts: {
headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
headerCorrespondence: ['type', 'scope', 'subject'],
noteKeywords: ['BREAKING CHANGE'],
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
revertCorrespondence: ['header', 'hash'],
parserOpts,
writerOpts,
conventionalChangelog: {
writerOpts,
parserOpts,
},
writerOpts: {
transform: (commit, context) => {
// don't want to show the release tag in changelog
if (commit.scope === 'release') {
return;
}

const issues = [];
let isBreaking = false;
commit.notes.forEach((note) => {
isBreaking = false;
note.title = 'BREAKING CHANGES';
});

commit.type = getCommitType(commit);
commit.scope = getCommitScope(commit);
if (!isBreaking && (!commit.type || commit.scope.includes('deps'))) {
// don't include un-typed commits in changelogs or deps
return;
}

if (typeof commit.hash === 'string') {
commit.shortHash = commit.hash.substring(0, 7);
}

if (typeof commit.subject === 'string') {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl;

if (url) {
url = `${url}/issues/`;
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
issues.push(issue);
return `[#${issue}](${url}${issue})`;
});
recommendedBumpOpts: {
parserOpts,

whatBump: (commits) => {
let level = 2;
let breaking = 0;
let features = 0;
commits.forEach((commit) => {
if (commit.notes.length > 0) {
breaking += commit.notes.length;
level = 0;
} else if (commit.type === 'feat') {
features += 1;
if (level === 2) {
level = 1;
}
}
});

commit.subject = tokenize(commit.subject);
}

// remove references that already appear in the subject
commit.references = commit.references.filter(
(reference) => !issues.includes(reference.issue)
);

return commit;
},
groupBy: 'type',
commitGroupsSort: function (a, b) {
const aIndex = GROUPS.indexOf(a.title);
const bIndex = GROUPS.indexOf(b.title);
if (aIndex !== -1 && bIndex !== -1) {
return aIndex - bIndex;
}

return a.title.localeCompare(b.title);
const verb = breaking === 1 ? 'is' : 'are';
return {
level,
reason: `There ${verb} ${breaking} BREAKING CHANGES and ${features} features`,
};
},
commitsSort: ['scope', 'subject'],
noteGroupsSort: 'title',
mainTemplate: readFileSync(
resolve(__dirname, './templates/template.hbs'),
'utf-8'
),
headerPartial: readFileSync(
resolve(__dirname, './templates/header.hbs'),
'utf-8'
),
commitPartial: readFileSync(
resolve(__dirname, './templates/commit.hbs'),
'utf-8'
),
footerPartial: readFileSync(
resolve(__dirname, './templates/footer.hbs'),
'utf-8'
),
},
};
3 changes: 2 additions & 1 deletion packages/dev-utils/src/changelogData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { writeFile } from "fs-extra";
import { join } from "path";

import { packagesRoot } from "./constants";
import {
format,
Expand All @@ -9,7 +10,7 @@ import {
loadDependenciesOf,
} from "./utils";

export async function updateChangelogData(): Promise<void> {
export async function changelogData(): Promise<void> {
const outputPath = join(packagesRoot, "dev-utils", "changelogData.js");
const rmdExports = getAllReactMDExports();
await loadDependenciesOf("dev-utils", false);
Expand Down
13 changes: 11 additions & 2 deletions packages/dev-utils/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,18 @@ createCommand("release")
"--yes",
"Passes `--yes` to the `lerna version` and `lerna publish` commands"
)
.option(
"--no-clean",
"Disables cleaning when the build waas cancelled beforehand"
)
.description("Goes through the steps of releasing a new version of react-md.")
.action(({ yes = false, blog = undefined, type = "" }) =>
release(type, blog, yes)
.action(({ yes = false, blog = undefined, type = "", clean = true }) =>
release({
autoYes: yes,
blog,
clean,
type,
})
);

createCommand("sandbox", true)
Expand Down
40 changes: 25 additions & 15 deletions packages/dev-utils/src/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import prompts from "prompts";

import { clean } from "./clean";
import { libsize } from "./libsize";
import { updateChangelogData } from "./changelogData";
import { changelogData } from "./changelogData";
import { getLernaVersion, git, replaceTag, run } from "./utils";
import { variables } from "./variables";
import { initBlog } from "./utils/initBlog";
Expand Down Expand Up @@ -61,28 +61,38 @@ async function verify(): Promise<void> {
log.info();
}

export async function release(
type: ReleaseType = "",
blog = !type.startsWith("pre"),
autoYes = false
): Promise<void> {
const yes = autoYes ? " --yes" : "";
interface Options {
clean: boolean;
type: ReleaseType;
blog: boolean;
autoYes: boolean;
}

// first, update the version since I'll be ammending this commit and tag with
// libsize changes, prettier changelogs, and adding the themes specifically
// for the tag only
await updateChangelogData();
run(`npx lerna version ${type} --no-push${yes}`);
await initBlog();
export async function release({
autoYes,
blog,
clean: enableClean,
type,
}: Options): Promise<void> {
const yes = autoYes ? " --yes" : "";

log.info("Cleaning all the old dists and `.tsbuildinfo` files...");
await clean();
if (enableClean) {
log.info("Cleaning all the old dists and `.tsbuildinfo` files...");
await clean();
}

log.info("Updating scssVariables files...");
// ensure the latest `dist/scssVariables` have been created
await variables();

// have to run the build before updating the changelog data since it pulls
// the variables from the react-md package
run("yarn build");

await changelogData();
run(`npx lerna version ${type} --no-push${yes}`);
await initBlog();

await libsize({
umd: true,
themes: true,
Expand Down

0 comments on commit e11c0ea

Please sign in to comment.