Skip to content

Commit e11c0ea

Browse files
committed
build(changelog): fixed some more changelog/release behavior
1 parent 3f6e866 commit e11c0ea

File tree

4 files changed

+152
-110
lines changed

4 files changed

+152
-110
lines changed

packages/dev-utils/changelog.config.js

Lines changed: 114 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const GROUPS = [
88
'Features',
99
'Documentation',
1010
'Performance Improvements',
11-
'Refactoring',
1211
'Other Internal Changes',
1312
];
1413

@@ -31,19 +30,8 @@ function getCommitType({ type, scope, revert }) {
3130
return 'Performance Improvements';
3231
case 'docs':
3332
return 'Documentation';
34-
case 'style':
35-
return 'Styles';
36-
case 'refactor':
37-
return 'Refactoring';
38-
case 'test':
39-
return 'Tests';
40-
case 'build':
41-
case 'ci':
42-
return 'Build System';
43-
case 'chore':
44-
return 'Other Internal Changes';
4533
default:
46-
return type;
34+
return 'Other Internal Changes';
4735
}
4836
}
4937

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

76+
const parserOpts = {
77+
headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
78+
headerCorrespondence: ['type', 'scope', 'subject'],
79+
noteKeywords: ['BREAKING CHANGE'],
80+
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
81+
revertCorrespondence: ['header', 'hash'],
82+
};
83+
84+
const writerOpts = {
85+
transform: (commit, context) => {
86+
// don't want to show the release tag in changelog
87+
if (commit.scope === 'release') {
88+
return;
89+
}
90+
91+
const issues = [];
92+
let isBreaking = false;
93+
commit.notes.forEach((note) => {
94+
isBreaking = false;
95+
note.title = 'BREAKING CHANGES';
96+
});
97+
98+
commit.type = getCommitType(commit);
99+
commit.scope = getCommitScope(commit);
100+
if (!isBreaking && (!commit.type || commit.scope.includes('deps'))) {
101+
// don't include un-typed commits in changelogs or deps
102+
return;
103+
}
104+
105+
if (typeof commit.hash === 'string') {
106+
commit.shortHash = commit.hash.substring(0, 7);
107+
}
108+
109+
if (typeof commit.subject === 'string') {
110+
let url = context.repository
111+
? `${context.host}/${context.owner}/${context.repository}`
112+
: context.repoUrl;
113+
114+
if (url) {
115+
url = `${url}/issues/`;
116+
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
117+
issues.push(issue);
118+
return `[#${issue}](${url}${issue})`;
119+
});
120+
}
121+
122+
commit.subject = tokenize(commit.subject);
123+
}
124+
125+
// remove references that already appear in the subject
126+
commit.references = commit.references.filter(
127+
(reference) => !issues.includes(reference.issue)
128+
);
129+
130+
return commit;
131+
},
132+
groupBy: 'type',
133+
commitGroupsSort: function (a, b) {
134+
const aIndex = GROUPS.indexOf(a.title);
135+
const bIndex = GROUPS.indexOf(b.title);
136+
if (aIndex !== -1 && bIndex !== -1) {
137+
return aIndex - bIndex;
138+
}
139+
140+
return a.title.localeCompare(b.title);
141+
},
142+
commitsSort: ['scope', 'subject'],
143+
noteGroupsSort: 'title',
144+
mainTemplate: readFileSync(
145+
resolve(__dirname, './templates/template.hbs'),
146+
'utf-8'
147+
),
148+
headerPartial: readFileSync(
149+
resolve(__dirname, './templates/header.hbs'),
150+
'utf-8'
151+
),
152+
commitPartial: readFileSync(
153+
resolve(__dirname, './templates/commit.hbs'),
154+
'utf-8'
155+
),
156+
footerPartial: readFileSync(
157+
resolve(__dirname, './templates/footer.hbs'),
158+
'utf-8'
159+
),
160+
};
161+
88162
/**
89163
* This is basically the conventional-changelog-angular with a few changes to
90164
* allow more commit messages to appear. I also "tokenize" known packages and
91165
* exports from react-md in the changelogs.
92166
*/
93167
module.exports = {
94-
parserOpts: {
95-
headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
96-
headerCorrespondence: ['type', 'scope', 'subject'],
97-
noteKeywords: ['BREAKING CHANGE'],
98-
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
99-
revertCorrespondence: ['header', 'hash'],
168+
parserOpts,
169+
writerOpts,
170+
conventionalChangelog: {
171+
writerOpts,
172+
parserOpts,
100173
},
101-
writerOpts: {
102-
transform: (commit, context) => {
103-
// don't want to show the release tag in changelog
104-
if (commit.scope === 'release') {
105-
return;
106-
}
107-
108-
const issues = [];
109-
let isBreaking = false;
110-
commit.notes.forEach((note) => {
111-
isBreaking = false;
112-
note.title = 'BREAKING CHANGES';
113-
});
114-
115-
commit.type = getCommitType(commit);
116-
commit.scope = getCommitScope(commit);
117-
if (!isBreaking && (!commit.type || commit.scope.includes('deps'))) {
118-
// don't include un-typed commits in changelogs or deps
119-
return;
120-
}
121-
122-
if (typeof commit.hash === 'string') {
123-
commit.shortHash = commit.hash.substring(0, 7);
124-
}
125-
126-
if (typeof commit.subject === 'string') {
127-
let url = context.repository
128-
? `${context.host}/${context.owner}/${context.repository}`
129-
: context.repoUrl;
130-
131-
if (url) {
132-
url = `${url}/issues/`;
133-
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
134-
issues.push(issue);
135-
return `[#${issue}](${url}${issue})`;
136-
});
174+
recommendedBumpOpts: {
175+
parserOpts,
176+
177+
whatBump: (commits) => {
178+
let level = 2;
179+
let breaking = 0;
180+
let features = 0;
181+
commits.forEach((commit) => {
182+
if (commit.notes.length > 0) {
183+
breaking += commit.notes.length;
184+
level = 0;
185+
} else if (commit.type === 'feat') {
186+
features += 1;
187+
if (level === 2) {
188+
level = 1;
189+
}
137190
}
191+
});
138192

139-
commit.subject = tokenize(commit.subject);
140-
}
141-
142-
// remove references that already appear in the subject
143-
commit.references = commit.references.filter(
144-
(reference) => !issues.includes(reference.issue)
145-
);
146-
147-
return commit;
148-
},
149-
groupBy: 'type',
150-
commitGroupsSort: function (a, b) {
151-
const aIndex = GROUPS.indexOf(a.title);
152-
const bIndex = GROUPS.indexOf(b.title);
153-
if (aIndex !== -1 && bIndex !== -1) {
154-
return aIndex - bIndex;
155-
}
156-
157-
return a.title.localeCompare(b.title);
193+
const verb = breaking === 1 ? 'is' : 'are';
194+
return {
195+
level,
196+
reason: `There ${verb} ${breaking} BREAKING CHANGES and ${features} features`,
197+
};
158198
},
159-
commitsSort: ['scope', 'subject'],
160-
noteGroupsSort: 'title',
161-
mainTemplate: readFileSync(
162-
resolve(__dirname, './templates/template.hbs'),
163-
'utf-8'
164-
),
165-
headerPartial: readFileSync(
166-
resolve(__dirname, './templates/header.hbs'),
167-
'utf-8'
168-
),
169-
commitPartial: readFileSync(
170-
resolve(__dirname, './templates/commit.hbs'),
171-
'utf-8'
172-
),
173-
footerPartial: readFileSync(
174-
resolve(__dirname, './templates/footer.hbs'),
175-
'utf-8'
176-
),
177199
},
178200
};

packages/dev-utils/src/changelogData.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { writeFile } from "fs-extra";
22
import { join } from "path";
3+
34
import { packagesRoot } from "./constants";
45
import {
56
format,
@@ -9,7 +10,7 @@ import {
910
loadDependenciesOf,
1011
} from "./utils";
1112

12-
export async function updateChangelogData(): Promise<void> {
13+
export async function changelogData(): Promise<void> {
1314
const outputPath = join(packagesRoot, "dev-utils", "changelogData.js");
1415
const rmdExports = getAllReactMDExports();
1516
await loadDependenciesOf("dev-utils", false);

packages/dev-utils/src/cli.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,18 @@ createCommand("release")
100100
"--yes",
101101
"Passes `--yes` to the `lerna version` and `lerna publish` commands"
102102
)
103+
.option(
104+
"--no-clean",
105+
"Disables cleaning when the build waas cancelled beforehand"
106+
)
103107
.description("Goes through the steps of releasing a new version of react-md.")
104-
.action(({ yes = false, blog = undefined, type = "" }) =>
105-
release(type, blog, yes)
108+
.action(({ yes = false, blog = undefined, type = "", clean = true }) =>
109+
release({
110+
autoYes: yes,
111+
blog,
112+
clean,
113+
type,
114+
})
106115
);
107116

108117
createCommand("sandbox", true)

packages/dev-utils/src/release.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import prompts from "prompts";
33

44
import { clean } from "./clean";
55
import { libsize } from "./libsize";
6-
import { updateChangelogData } from "./changelogData";
6+
import { changelogData } from "./changelogData";
77
import { getLernaVersion, git, replaceTag, run } from "./utils";
88
import { variables } from "./variables";
99
import { initBlog } from "./utils/initBlog";
@@ -61,28 +61,38 @@ async function verify(): Promise<void> {
6161
log.info();
6262
}
6363

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

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

78-
log.info("Cleaning all the old dists and `.tsbuildinfo` files...");
79-
await clean();
79+
if (enableClean) {
80+
log.info("Cleaning all the old dists and `.tsbuildinfo` files...");
81+
await clean();
82+
}
8083

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

88+
// have to run the build before updating the changelog data since it pulls
89+
// the variables from the react-md package
8590
run("yarn build");
91+
92+
await changelogData();
93+
run(`npx lerna version ${type} --no-push${yes}`);
94+
await initBlog();
95+
8696
await libsize({
8797
umd: true,
8898
themes: true,

0 commit comments

Comments
 (0)