Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: generate changelog based on conventional commits #5487

Merged
merged 8 commits into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/workflows/lint-pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,20 @@ jobs:
with:
# Configure which types are allowed (newline-delimited).
# Default: https://github.com/commitizen/conventional-commit-types
#types: |
# Customized based on sections defined in scripts/generate_changelog.js
types: |
feat
fix
perf
refactor
deps
revert
build
ci
test
style
chore
docs

# Configure which scopes are allowed (newline-delimited).
# These are regex patterns auto-wrapped in `^ $`.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
# </common-build>

- name: Generate changelog
run: node scripts/generate_changelog_simple.js ${{ needs.tag.outputs.prev_tag }} ${{ needs.tag.outputs.tag }} CHANGELOG.md
run: node scripts/generate_changelog.js ${{ needs.tag.outputs.prev_tag }} ${{ needs.tag.outputs.tag }} CHANGELOG.md
nflaig marked this conversation as resolved.
Show resolved Hide resolved

- name: Create Release
id: create_release
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
# </common-build>

- name: Generate changelog
run: node scripts/generate_changelog_simple.js ${{ needs.tag.outputs.prev_tag }} ${{ needs.tag.outputs.tag }} CHANGELOG.md
run: node scripts/generate_changelog.js ${{ needs.tag.outputs.prev_tag }} ${{ needs.tag.outputs.tag }} CHANGELOG.md

- name: Create Release
id: create_release
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const fs = require("node:fs");
// Docs
// [script] <fromTag> <toTag>
//
// Exmaple
// Example
// ```
// node scripts/changelog_simple.js v0.32.0 v0.33.0
// node scripts/generate_changelog.js v0.32.0 v0.33.0
// ```

/**
Expand All @@ -23,8 +23,8 @@ const fs = require("node:fs");
*/
const knownAuthors = {
"caymannava@gmail.com": "wemeetagain",
"76567250+g11tech@users.noreply.github.com": "g11tech",
"vutuyen2636@gmail.com": "tuyennhv",
"develop@g11tech.io": "g11tech",
"tuyen@chainsafe.io": "tuyennhv",
"35266934+dapplion@users.noreply.github.com": "dapplion",
"41898282+github-actions[bot]@users.noreply.github.com": "github-actions[bot]",
"49699333+dependabot[bot]@users.noreply.github.com": "dependabot[bot]",
Expand All @@ -39,6 +39,9 @@ const knownAuthors = {
"ammar1lakho@gmail.com": "ammarlakho",
"dadepo@gmail.com": "dadepo",
"hi@enriqueortiz.dev": "Evalir",
"nflaig@protonmail.com": "nflaig",
"nazarhussain@gmail.com": "nazarhussain",
"me@matthewkeil.com": "matthewkeil",
};

const fromTag = process.argv[2];
Expand All @@ -49,36 +52,96 @@ if (!fromTag) throw Error("No process.argv[2]");
if (!toTag) throw Error("No process.argv[3]");
if (!outpath) throw Error("No process.argv[4]");

/**
* @type {Record<string, {heading: string; commitsByScope: Record<string, string[]>}>}
*/
const sections = {
Copy link
Member Author

Choose a reason for hiding this comment

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

Looking for feedback on what sections, headings and ordering we want to use here.

feat: {heading: "Features", commitsByScope: {"": []}},
fix: {heading: "Bug Fixes", commitsByScope: {"": []}},
perf: {heading: "Performance", commitsByScope: {"": []}},
refactor: {heading: "Refactoring", commitsByScope: {"": []}},
deps: {heading: "Dependencies", commitsByScope: {"": []}},
revert: {heading: "Reverts", commitsByScope: {"": []}},
build: {heading: "Build System", commitsByScope: {"": []}},
ci: {heading: "Continuous Integration", commitsByScope: {"": []}},
test: {heading: "Tests", commitsByScope: {"": []}},
style: {heading: "Styles", commitsByScope: {"": []}},
chore: {heading: "Maintenance", commitsByScope: {"": []}},
docs: {heading: "Documentation", commitsByScope: {"": []}},
_: {heading: "Miscellaneous", commitsByScope: {"": []}},
};

const isPrCommitRg = /\(#\d+\)/;
const conventionalCommitRg = /^([a-z]+)(?:\((.*)\))?(?:(!))?: (.*)$/;

const commitHashes = shell(`git log --pretty=format:"%H" ${fromTag}...${toTag}`);

let commitListStr = "";

for (const commitHash of commitHashes.trim().split("\n")) {
const subject = shell(`git log --format='%s' ${commitHash}^!`);
if (!isPrCommitRg.test(subject)) {
const rawCommit = shell(`git log --format='%s' ${commitHash}^!`);

if (!isPrCommitRg.test(rawCommit)) {
// Drop commits without a PR reference
continue;
}

const conventionalCommit = rawCommit.match(conventionalCommitRg);
if (!conventionalCommit) {
// Drop commits that do not follow conventional commit pattern
continue;
}

const [, type, scope, _breaking, subject] = conventionalCommit;
Copy link
Member Author

@nflaig nflaig May 12, 2023

Choose a reason for hiding this comment

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

Breaking changes are not highlighted at the moment, possible solution could be to have an extra section ## Breaking Changes but based on how we used ! so far this would be too noisy as there are too many changes marked as breaking which are not user facing.

I think if we can restrain breaking commits as highlighted by ! to user facing changes it would be valuable as it provides a quick way for operators (or other downstream tooling) to just check this section to know if they are affected by any of the introduced changes.

Potential solutions to highlight breaking changes

  • separate Section (## Breaking Changes)
  • prefixing or suffixing line (**BREAKING CHANGE:** or [BREAKING])
  • using some kind of emoji at beginning of the line (⚠️)

Copy link
Member

@philknows philknows May 16, 2023

Choose a reason for hiding this comment

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

I have no strong opinion to either method. However as you already mentioned, we do have a lot of breaking changes which isn't necessarily useful to a non-developer user/operator of Lodestar. If it does affect a user, it'll likely be highlighted already on my manual summaries.

Copy link
Member Author

Choose a reason for hiding this comment

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

Let's not highlight breaking changes in the Changelog for now, until we have more clarity on it. Updated description of #5433 to discuss it there.


const authorEmail = shell(`git log --format='%ae' ${commitHash}^!`);
const authorName = shell(`git log --format='%an' ${commitHash}^!`);
const login = getCommitAuthorLogin(commitHash, authorEmail, authorName);

commitListStr += `- ${subject} (@${login})\n`;
const formattedCommit = `- ${scope ? `**${scope}:** ` : ""}${subject} (@${login})\n`;

// Sort commits by type and scope
// - assign each commit to section based on type
// - group commits by scope within each section
if (sections[type] != null) {
if (scope) {
if (sections[type].commitsByScope[scope] == null) {
sections[type].commitsByScope[scope] = [];
}
sections[type].commitsByScope[scope].push(formattedCommit);
} else {
sections[type].commitsByScope[""].push(formattedCommit);
}
} else {
// Commits with a type that is not defined in sections
sections._.commitsByScope[""].push(formattedCommit);
}
}

// Print knownAuthors to update if necessary
console.log("knownAuthors", knownAuthors);

const changelog = `# Changelog
let changelog = `## Changelog

[Full Changelog](https://github.com/ChainSafe/lodestar/compare/${fromTag}...${toTag})
`;

**Merged pull requests:**
// Write sections to changelog
for (const type in sections) {
const section = sections[type];
let hasCommits = false;
let sectionChangelog = `\n### ${section.heading}\n\n`;

${commitListStr}
`;
for (const commits of Object.values(section.commitsByScope)) {
if (commits.length > 0) {
hasCommits = true;
sectionChangelog += commits.join("");
}
}

if (hasCommits) {
// Only add section if it has at least one commit
changelog += sectionChangelog;
}
}

// Print to console
console.log(changelog);
Expand Down