Skip to content

Commit

Permalink
feat: add automatic release notes generation (#3183)
Browse files Browse the repository at this point in the history
  • Loading branch information
Szymon-dziewonski authored Jul 5, 2024
1 parent add35fe commit 317b933
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 3 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,10 @@ jobs:
# refresh token before Saturday, May 25, 2024
NPM_TOKEN: ${{ secrets.NPM_RELEASE_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_TOKEN }}
- name: Create Release Pull Request
# Create release notes
uses: changesets/action@v1
- name: Create Release Notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node releaseNotes.mjs
- name: Create PR to v2-develop branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,22 @@
"@commitlint/cli": "^17.0.0",
"@commitlint/config-conventional": "^17.0.0",
"@frsource/frs-replace": "^4.1.1",
"@octokit/core": "^6.1.2",
"@storefront-ui/typescript-config": "workspace:*",
"@vue-storefront/prettier-config": "^2.0.0-rc.1",
"commitizen": "^4.2.5",
"concurrently": "^8.2.2",
"husky": "^9.0.11",
"hygen": "^6.2.8",
"mdast-util-to-string": "^4.0.0",
"prettier": "latest",
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"rimraf": "^5.0.0",
"tailwindcss": "^3.4.3",
"turbo": "latest",
"typescript": "^5.4.5",
"unified": "^11.0.4",
"wait-on": "^7.0.1"
},
"engines": {
Expand Down
122 changes: 122 additions & 0 deletions releaseNotes.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Octokit } from '@octokit/core';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { toString } from 'mdast-util-to-string';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

const OWNER = 'vuestorefront';
const REPO = 'storefront-ui';
const octokit = new Octokit({ auth: process.env['GITHUB_TOKEN'] });

const BumpLevels = {
dep: 0,
patch: 1,
minor: 2,
major: 3,
};

// Implementation copied from changeset and its generation release notes https://github.com/changesets/action/blob/main/src/utils.ts#L37
function getChangelogEntry(changelog, version) {
let ast = unified().use(remarkParse).parse(changelog);

let highestLevel = BumpLevels.dep;

let nodes = ast.children;
let headingStartInfo;
let endIndex;

for (let i = 0; i < nodes.length; i++) {
let node = nodes[i];
if (node.type === 'heading') {
let stringified = toString(node);
let match = stringified.toLowerCase().match(/(major|minor|patch)/);
if (match !== null) {
let level = BumpLevels[match[0]];
highestLevel = Math.max(level, highestLevel);
}
if (headingStartInfo === undefined && stringified === version) {
headingStartInfo = {
index: i,
depth: node.depth,
};
continue;
}
if (endIndex === undefined && headingStartInfo !== undefined && headingStartInfo.depth === node.depth) {
endIndex = i;
break;
}
}
}
if (headingStartInfo) {
ast.children = ast.children.slice(headingStartInfo.index + 1, endIndex);
}
return {
content: unified().use(remarkStringify).stringify(ast),
highestLevel: highestLevel,
};
}

const data = await octokit.request(`GET /repos/${OWNER}/${REPO}/commits`, {
owner: OWNER,
repo: REPO,
sha: 'v2',
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
});

const commitSha = data.data[0].sha;
const commitBody = await octokit.request(`GET /repos/${OWNER}/${REPO}/commits/${commitSha}`, {
owner: OWNER,
repo: REPO,
ref: commitSha,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
});

const allChangelogFiles = commitBody.data.files.filter((file) => file.filename.endsWith('CHANGELOG.md'));

if (!allChangelogFiles.length) {
console.log('No CHANGELOG file has been found');
} else {
await Promise.all(
allChangelogFiles.map(async (changelogFile) => {
const changelogFilePath = changelogFile.filename;
const updatedPackageDir = changelogFilePath.replace('/CHANGELOG.md', '');
const packageJsonPath = join(updatedPackageDir, 'package.json');

const changelogContent = readFileSync(changelogFilePath, 'utf-8');
const packageJsonContent = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));

const pkgName = packageJsonContent.name;
const pkgVersion = packageJsonContent.version;
const tagName = `${pkgName}@${pkgVersion}`;

let changelogEntry = getChangelogEntry(changelogContent, pkgVersion);

try {
await octokit.request(`POST /repos/${OWNER}/${REPO}/releases`, {
owner: OWNER,
repo: REPO,
tag_name: tagName,
target_commitish: commitSha,
name: tagName,
body: changelogEntry.content,
draft: false,
prerelease: pkgVersion.includes('-'),
generate_release_notes: false,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
});
} catch (e) {
console.log(e);
}

console.log(`Release notes for ${tagName} has been created 🎉`);
}),
);
}
99 changes: 99 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3639,6 +3639,86 @@ __metadata:
languageName: node
linkType: hard

"@octokit/auth-token@npm:^5.0.0":
version: 5.1.1
resolution: "@octokit/auth-token@npm:5.1.1"
checksum: b39516dda44aeced0326227c53aade621effe1d59c4b0f48ebe2b9fd32b5156e02705bcb2fb1bf48b11f26cc6aff1a0683c32c3d5424e0118dae6596e431d489
languageName: node
linkType: hard

"@octokit/core@npm:^6.1.2":
version: 6.1.2
resolution: "@octokit/core@npm:6.1.2"
dependencies:
"@octokit/auth-token": ^5.0.0
"@octokit/graphql": ^8.0.0
"@octokit/request": ^9.0.0
"@octokit/request-error": ^6.0.1
"@octokit/types": ^13.0.0
before-after-hook: ^3.0.2
universal-user-agent: ^7.0.0
checksum: e794fb11b3942f55033f4cf6c0914953fd974587309498e8709c428660fa5c098334d83af5e41457dbe67d92d70a8b559c6cc00457d6c95290fa6c9e1d4bfc42
languageName: node
linkType: hard

"@octokit/endpoint@npm:^10.0.0":
version: 10.1.1
resolution: "@octokit/endpoint@npm:10.1.1"
dependencies:
"@octokit/types": ^13.0.0
universal-user-agent: ^7.0.2
checksum: fde158f40dc9a88e92a8ac1d347a54599aa5715ec24045be9cb8ff8decb3c17b63c91eca1bab12dfe0e0cd37433127dd05cd05db14a719dca749bc56093aa915
languageName: node
linkType: hard

"@octokit/graphql@npm:^8.0.0":
version: 8.1.1
resolution: "@octokit/graphql@npm:8.1.1"
dependencies:
"@octokit/request": ^9.0.0
"@octokit/types": ^13.0.0
universal-user-agent: ^7.0.0
checksum: 07239666b0ca38a7d8c581570b544ee9fd1a2616c8dd436af31879662b3345c44ed52e3d7b311840a1c5772a23f02caf7585aca56f36e50f38f0207a87577a9c
languageName: node
linkType: hard

"@octokit/openapi-types@npm:^22.2.0":
version: 22.2.0
resolution: "@octokit/openapi-types@npm:22.2.0"
checksum: eca41feac2b83298e0d95e253ac1c5b6d65155ac57f65c5fd8d4a485d9728922d85ff4bee0e815a1f3a5421311db092bdb6da9d6104a1b1843d8b274bcad9630
languageName: node
linkType: hard

"@octokit/request-error@npm:^6.0.1":
version: 6.1.1
resolution: "@octokit/request-error@npm:6.1.1"
dependencies:
"@octokit/types": ^13.0.0
checksum: cae7bc4078629a02edcf35977f496a4b943e730165f6d7828795073f99a1d884ac67343b02eff69e553a5057765e466d70ddd9d266787f505aa29018858ab06d
languageName: node
linkType: hard

"@octokit/request@npm:^9.0.0":
version: 9.1.1
resolution: "@octokit/request@npm:9.1.1"
dependencies:
"@octokit/endpoint": ^10.0.0
"@octokit/request-error": ^6.0.1
"@octokit/types": ^13.1.0
universal-user-agent: ^7.0.2
checksum: 0c41654911c217eb2892ce6c9c273cc2139e5510b025c71e72e1528f0d8bad2a9e578e5b305595599f2e1cb630c1812cd7d9e4f6d16a63007a7d1745f1c682ce
languageName: node
linkType: hard

"@octokit/types@npm:^13.0.0, @octokit/types@npm:^13.1.0":
version: 13.5.0
resolution: "@octokit/types@npm:13.5.0"
dependencies:
"@octokit/openapi-types": ^22.2.0
checksum: 8e92f2b145b3c28a35312f93714245824a7b6b7353caa88edfdc85fc2ed4108321ed0c3988001ea53449fbb212febe0e8e9582744e85c3574dabe9d0441af5a0
languageName: node
linkType: hard

"@open-draft/deferred-promise@npm:^2.2.0":
version: 2.2.0
resolution: "@open-draft/deferred-promise@npm:2.2.0"
Expand Down Expand Up @@ -4705,17 +4785,22 @@ __metadata:
"@commitlint/cli": ^17.0.0
"@commitlint/config-conventional": ^17.0.0
"@frsource/frs-replace": ^4.1.1
"@octokit/core": ^6.1.2
"@storefront-ui/typescript-config": "workspace:*"
"@vue-storefront/prettier-config": ^2.0.0-rc.1
commitizen: ^4.2.5
concurrently: ^8.2.2
husky: ^9.0.11
hygen: ^6.2.8
mdast-util-to-string: ^4.0.0
prettier: latest
remark-parse: ^11.0.0
remark-stringify: ^11.0.0
rimraf: ^5.0.0
tailwindcss: ^3.4.3
turbo: latest
typescript: ^5.4.5
unified: ^11.0.4
wait-on: ^7.0.1
languageName: unknown
linkType: soft
Expand Down Expand Up @@ -7683,6 +7768,13 @@ __metadata:
languageName: node
linkType: hard

"before-after-hook@npm:^3.0.2":
version: 3.0.2
resolution: "before-after-hook@npm:3.0.2"
checksum: 5f76a9d31909f7f1f7125b7e017ff018799308f5c1fc5a5bfeba9986149da77e6a5cdde0d151671cf374a7fa6452533237bb1de62dfd6c235c20e7c61cc9569d
languageName: node
linkType: hard

"better-path-resolve@npm:1.0.0":
version: 1.0.0
resolution: "better-path-resolve@npm:1.0.0"
Expand Down Expand Up @@ -23148,6 +23240,13 @@ __metadata:
languageName: node
linkType: hard

"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2":
version: 7.0.2
resolution: "universal-user-agent@npm:7.0.2"
checksum: 3f02cb6de0bb9fbaf379566bd0320d8e46af6e4358a2e88fce7e70687ed7b48b37f479d728bb22f4204a518e363f3038ac4841c033af1ee2253f6428a6c67e53
languageName: node
linkType: hard

"universalify@npm:^0.1.0, universalify@npm:^0.1.2":
version: 0.1.2
resolution: "universalify@npm:0.1.2"
Expand Down

0 comments on commit 317b933

Please sign in to comment.