Skip to content

Commit

Permalink
Feat(ci): Introduce posting changelog into the Slack channel
Browse files Browse the repository at this point in the history
refs #1781
  • Loading branch information
literat committed Dec 17, 2024
1 parent 557f3e5 commit 2cc978e
Show file tree
Hide file tree
Showing 4 changed files with 655 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,8 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

- name: Post Changelog
run: yarn zx scripts/post-changelog.mjs
env:
SLACK_CHANGELOG_WEBHOOK_URL: ${{ secrets.SLACK_CHANGELOG_WEBHOOK_URL }}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@
"babel-loader": "9.2.1",
"core-js": "3.39.0",
"css-loader": "7.1.2",
"dotenv-safe": "^9.1.0",
"eslint": "8.57.1",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-react": "7.37.2",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-storybook": "0.11.1",
"gitdiff-parser": "^0.3.1",
"husky": "9.1.7",
"is-ci": "3.0.1",
"lerna": "8.1.8",
Expand All @@ -96,11 +98,14 @@
"remark-frontmatter": "5.0.0",
"remark-lint-heading-capitalization": "1.2.0",
"sass-loader": "14.2.1",
"simple-git": "^3.27.0",
"slackify-markdown": "^4.4.0",
"style-loader": "4.0.0",
"typescript": "4.7.4",
"vite-raw-plugin": "1.0.2",
"webpack": "5.96.1",
"webpack-cli": "5.1.4"
"webpack-cli": "5.1.4",
"zx": "^8.2.4"
},
"resolutions": {
"typescript": "4.7.4"
Expand Down
151 changes: 151 additions & 0 deletions scripts/post-changelog.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint-disable no-console */
import { $, fetch, argv } from 'zx';
import dotenv from 'dotenv-safe';
import slackifyMarkdown from 'slackify-markdown';
import { simpleGit } from 'simple-git';
import gitDiffParser from 'gitdiff-parser';

const COLOR_CORE = '#00A58E';
const PACKAGES = ['web', 'web-react', 'web-twig', 'design-tokens', 'icons', 'codemods', 'analytics'];
const SLACK_CHANGELOG_WEBHOOK_URL = process.env.SLACK_CHANGELOG_WEBHOOK_URL ?? '';

function getTitle(pkg) {
return `🚀 New ${pkg
.split('-')
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join(' ')} package release`;
}
async function sendToWebhook({ content, webhookUrl }) {
await fetch(webhookUrl, {
method: 'POST',
body: JSON.stringify(content),
})
.then((res) => {
if (res.status !== 200) {
throw new Error(`${res.status} ${res.statusText}`);
}
})
.catch((err) => {
console.error(err);
process.exit(1);
});
}

function format(str, package_, prefix = '@lmc-eu') {
const output = str
.replace(
/^#+ /,
`# 📦 ${package_
.split('-')
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join(' ')} \`${prefix}/spirit-${package_}\` `,
)
.replace('Bug Fixes', '🐛 Bug Fixes')
.replace('Features', '⚡ Features')
.replace('BREAKING CHANGES', '🚨 BREAKING CHANGES')
.replace('Dependencies', '📦 Dependencies')
.replace('Documentation', '📜 Documentation')
.replace('Tests', '🧪 Tests')
.replace('Code Refactoring', '🛠️ Code Refactoring')
.replace('Chores', '🔨 Chores')
.replace('Styles', '💅 Styles')
.replaceAll('https://github.com/lmc-eu/spirit-design-system/issues/', 'https://jira.almacareer.tech/browse/');

return output;
}

function getChangelogFromDiff(files) {
// Only one file as we're only looking at the changelog
const versionPattern = /<a name=".*"><\/a>/;
const [changelogFile] = files;
const changelog = changelogFile.hunks
.flatMap((hunk) => hunk.changes.filter(({ isInsert }) => isInsert).map(({ content }) => content))
.filter((line) => !versionPattern.test(line))
.join('\n')
.trim();

return changelog;
}

function getDiff(tag, path) {
return simpleGit().show([tag, path]);
}

function changelogPath(package_) {
return `packages/${package_}/CHANGELOG.md`;
}

async function postSlackNotification(changelog, package_) {
try {
$.verbose = false;
const res = await sendToWebhook({
webhookUrl: SLACK_CHANGELOG_WEBHOOK_URL,
content: {
attachments: [
{
title: getTitle(package_),
text: changelog,
color: COLOR_CORE,
},
],
},
});

return res;
} catch (err) {
console.log('Error posting to Slack');
console.error(err);
}

return undefined;
}

async function configureWebhookURL() {
try {
dotenv.config({
allowEmptyValues: true,
example: '.env.example',
});
} catch (err) {
if (/SLACK_CHANGELOG_WEBHOOK_URL/g.test(err.message)) {
throw new Error('SLACK_CHANGELOG_WEBHOOK_URL is not set');
}
}
}

async function publishChangelog(package_) {
try {
await simpleGit().fetch(['origin', 'main', '--tags']);
const tags = await simpleGit().tags({ '--sort': '-taggerdate' });
console.log(tags.latest);
const diff = await getDiff(tags.latest ?? '', changelogPath(package_));
const files = gitDiffParser.parse(diff);
if (files.length === 0) {
console.log(`No changes in ${package_}`);

return;
}
const changelog = getChangelogFromDiff(files);
const formattedChangelog = format(changelog, package_);
const slackifiedChangelog = slackifyMarkdown(formattedChangelog);

if (argv.dry) {
console.info(formattedChangelog);
} else {
await configureWebhookURL();
await postSlackNotification(slackifiedChangelog, package_);
}
} catch (err) {
console.error(err);
process.exit(1);
}
}

(async () => {
await Promise.all(
PACKAGES.map(async (package_) => {
await publishChangelog(package_);
}),
);
process.exit(0);
})();
Loading

0 comments on commit 2cc978e

Please sign in to comment.