Skip to content

Commit

Permalink
feat: Add #body-in-changelog option to PR/commit bodies (#554)
Browse files Browse the repository at this point in the history
Right now this is manually done by the getsentry/sentry-python team. I thought it was a good opportunity improve automatic changelog generation. Thanks to @sentrivana for the idea.

Co-authored-by: Burak Yigit Kaya <bkaya21@bloomberg.net>
  • Loading branch information
BYK and Burak Yigit Kaya authored Aug 15, 2024
1 parent b52cd27 commit 40aba8f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.codeActionsOnSave": {
"source.organizeImports": false
"source.organizeImports": "never"
},
"editor.formatOnType": true,
"editor.formatOnSave": true,
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ contains any one of `preview`, `pre`, `rc`, `dev`,`alpha`, `beta`, `unstable`,
| Name | Description |
| -------------- | ------------------------------------------------------------------ |
| `GITHUB_TOKEN` | Personal GitHub API token (see https://github.com/settings/tokens) |
| `GITHUB_TOKEN` | Personal GitHub API token (see <https://github.com/settings/tokens>) |
**Configuration**
Expand Down Expand Up @@ -617,7 +617,7 @@ like [getsentry/pypi]
| Name | Description |
| -------------- | ------------------------------------------------------------------ |
| `GITHUB_TOKEN` | Personal GitHub API token (see https://github.com/settings/tokens) |
| `GITHUB_TOKEN` | Personal GitHub API token (see <https://github.com/settings/tokens>) |
**Configuration**
Expand Down Expand Up @@ -829,7 +829,7 @@ targets:
### Sentry Release Registry (`registry`)
The target will update the Sentry release registry repo(https://github.com/getsentry/sentry-release-registry/) with the latest version of the
The target will update the Sentry release registry repo(<https://github.com/getsentry/sentry-release-registry/>) with the latest version of the
project `craft` is used with. The release registry repository will be checked out
locally, and then the new version file will be created there, along with the necessary
symbolic links.
Expand Down
100 changes: 99 additions & 1 deletion src/utils/__tests__/changelog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { getGitHubClient } from '../githubApi';
jest.mock('../git');
import { getChangesSince } from '../git';

import { SimpleGit } from 'simple-git';
import type { SimpleGit } from 'simple-git';

import {
findChangeset,
removeChangeset,
prependChangeset,
generateChangesetFromGit,
SKIP_CHANGELOG_MAGIC_WORD,
BODY_IN_CHANGELOG_MAGIC_WORD,
} from '../changelog';

describe('findChangeset', () => {
Expand Down Expand Up @@ -705,6 +706,103 @@ describe('generateChangesetFromGit', () => {
'- Fix the clacking sound on gear changes (#950) by @alice',
].join('\n'),
],
[
`should expand commits & prs with the magic ${BODY_IN_CHANGELOG_MAGIC_WORD}`,
[
{
hash: 'abcdef1234567890',
title: 'Upgraded the kernel',
body: SKIP_CHANGELOG_MAGIC_WORD,
},
{
hash: 'bcdef1234567890a',
title: 'Upgraded the manifold (#123)',
body: '',
pr: {
local: '123',
remote: {
number: '123',
author: { login: 'alice' },
milestone: '1',
},
},
},
{
hash: 'cdef1234567890ab',
title: 'Refactored the crankshaft',
body: '',
pr: {
remote: {
number: '456',
author: { login: 'bob' },
body: `This is important and we'll include the __body__ for attention. ${BODY_IN_CHANGELOG_MAGIC_WORD}`,
milestone: '1',
},
},
},
{
hash: 'def1234567890abc',
title: 'Upgrade the HUD (#789)',
body: '',
pr: {
local: '789',
remote: {
number: '789',
author: { login: 'charlie' },
milestone: '5',
},
},
},
{
hash: 'ef1234567890abcd',
title: 'Upgrade the steering wheel (#900)',
body: `Some very important update ${BODY_IN_CHANGELOG_MAGIC_WORD}`,
pr: { local: '900' },
},
{
hash: 'f1234567890abcde',
title: 'Fix the clacking sound on gear changes (#950)',
body: '',
pr: {
local: '950',
remote: { number: '950', author: { login: 'alice' } },
},
},
],
{
'1': {
title: 'Better drivetrain',
description:
'We have upgraded the drivetrain for a smoother and more performant driving experience. Enjoy!',
state: 'CLOSED',
},
'5': {
title: 'Better driver experience',
description:
'We are working on making your driving experience more pleasant and safer.',
state: 'OPEN',
},
},
[
'### Better drivetrain',
'',
'We have upgraded the drivetrain for a smoother and more performant driving experience. Enjoy!',
'',
'By: @alice (#123), @bob (#456)',
'',
'### Better driver experience (ongoing)',
'',
'We are working on making your driving experience more pleasant and safer.',
'',
'By: @charlie (#789)',
'',
'### Various fixes & improvements',
'',
'- Upgrade the steering wheel (#900)',
' Some very important update ',
'- Fix the clacking sound on gear changes (#950) by @alice',
].join('\n'),
],
])(
'%s',
async (
Expand Down
30 changes: 24 additions & 6 deletions src/utils/changelog.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SimpleGit } from 'simple-git';
import type { SimpleGit } from 'simple-git';
import { logger } from '../logger';

import { getGlobalGitHubConfig } from '../config';
Expand All @@ -12,6 +12,7 @@ import { getVersion } from './version';
export const DEFAULT_CHANGELOG_PATH = 'CHANGELOG.md';
export const DEFAULT_UNRELEASED_TITLE = 'Unreleased';
export const SKIP_CHANGELOG_MAGIC_WORD = '#skip-changelog';
export const BODY_IN_CHANGELOG_MAGIC_WORD = '#body-in-changelog';
const DEFAULT_CHANGESET_BODY = '- No documented changes.';
const VERSION_HEADER_LEVEL = 2;
const SUBSECTION_HEADER_LEVEL = VERSION_HEADER_LEVEL + 1;
Expand Down Expand Up @@ -214,8 +215,10 @@ interface Commit {
author?: string;
hash: string;
title: string;
body: string;
hasPRinTitle: boolean;
pr: string | null;
prBody?: string | null;
milestone: string | null;
}

Expand All @@ -224,7 +227,7 @@ interface Milestone {
description: string | null;
state: 'OPEN' | 'CLOSED';
}
type MilestoneWithPRs = Milestone & {
type MilestoneWithPRs = Partial<Milestone> & {
prs: PullRequest[];
};

Expand All @@ -242,6 +245,17 @@ function formatCommit(commit: Commit): string {
if (commit.author) {
text = `${text} by @${commit.author}`;
}
let body = '';
if (commit.prBody?.includes(BODY_IN_CHANGELOG_MAGIC_WORD)) {
body = commit.prBody;
} else if (commit.body.includes(BODY_IN_CHANGELOG_MAGIC_WORD)) {
body = commit.body;
}
body = body.replace(BODY_IN_CHANGELOG_MAGIC_WORD, '');
if (body) {
text += `\n ${body}`;
}

return text;
}

Expand Down Expand Up @@ -270,20 +284,24 @@ export async function generateChangesetFromGit(
continue;
}

const commit = (commits[hash] = {
const commit = {
hash: hash,
title: gitCommit.title,
body: gitCommit.body,
hasPRinTitle: Boolean(gitCommit.pr),
...githubCommit,
});
};
commits[hash] = commit;

if (!githubCommit) {
missing.push(commit);
}
if (!commit.milestone) {
leftovers.push(commit);
} else {
const milestone = milestones[commit.milestone] || { prs: [] };
const milestone = milestones[commit.milestone] || {
prs: [] as PullRequest[],
};
// We _know_ the PR exists as milestones are attached to PRs
milestone.prs.push({
author: commit.author as string,
Expand All @@ -296,7 +314,7 @@ export async function generateChangesetFromGit(

if (missing.length > 0) {
logger.warn(
`The following commits were not found on GitHub:`,
'The following commits were not found on GitHub:',
missing.map(commit => `${commit.hash.slice(0, 8)} ${commit.title}`)
);
}
Expand Down

0 comments on commit 40aba8f

Please sign in to comment.