Skip to content

Commit 60dad34

Browse files
authored
ci: Add workflow to automatically add external contributors to CHANGELOG.md (#12428)
This adds a new GHA job that, if a PR is created by an external contributor, it will open a PR against that branch that adds the contributor to the changelog, so we do not forget about this. It will open a PR like this: #12435 which we have to manually merge/review, so nothing "bad" can happen.
1 parent f032f3f commit 60dad34

File tree

6 files changed

+156
-0
lines changed

6 files changed

+156
-0
lines changed

.github/workflows/build.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,44 @@ jobs:
224224
message: |
225225
⚠️ This PR is opened against **master**. You probably want to open it against **develop**.
226226
227+
job_external_contributor:
228+
name: External Contributors
229+
needs: job_install_deps
230+
runs-on: ubuntu-20.04
231+
if: |
232+
github.event_name == 'pull_request'
233+
&& (github.action == 'opened' || github.action == 'reopened')
234+
&& github.event.pull_request.author_association != 'COLLABORATOR'
235+
&& github.event.pull_request.author_association != 'MEMBER'
236+
&& github.event.pull_request.author_association != 'OWNER'
237+
steps:
238+
- uses: actions/checkout@v4
239+
with:
240+
ref: ${{ github.head_ref }}
241+
- name: Set up Node
242+
uses: actions/setup-node@v4
243+
with:
244+
node-version-file: 'package.json'
245+
- name: Check dependency cache
246+
uses: actions/cache/restore@v4
247+
with:
248+
path: ${{ env.CACHED_DEPENDENCY_PATHS }}
249+
key: ${{ needs.job_install_deps.outputs.dependency_cache_key }}
250+
fail-on-cache-miss: true
251+
252+
- name: Add external contributor to CHANGELOG.md
253+
uses: ./dev-packages/external-contributor-gh-action
254+
with:
255+
name: ${{ github.event.pull_request.user.login }}
256+
- name: Create PR with changes
257+
uses: peter-evans/create-pull-request@v6
258+
with:
259+
commit-message: "ref: Add external contributor to CHANGELOG.md"
260+
title: "ref: Add external contributor to CHANGELOG.md"
261+
branch: 'external-contributor/patch-${{ github.event.pull_request.user.login }}'
262+
delete-branch: true
263+
body: This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution.
264+
227265
job_build:
228266
name: Build
229267
needs: [job_get_metadata, job_install_deps]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
extends: ['../../.eslintrc.js'],
3+
parserOptions: {
4+
sourceType: 'module',
5+
ecmaVersion: 'latest',
6+
},
7+
8+
overrides: [
9+
{
10+
files: ['*.mjs'],
11+
extends: ['@sentry-internal/sdk/src/base'],
12+
},
13+
],
14+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: 'external-contributor-gh-action'
2+
description: 'Add external contributors to CHANGELOG.md'
3+
inputs:
4+
name:
5+
required: true
6+
description: 'The name of the external contributor'
7+
runs:
8+
using: 'node20'
9+
main: 'index.mjs'
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { promises as fs } from 'node:fs';
2+
import path from 'node:path';
3+
import * as core from '@actions/core';
4+
5+
const UNRELEASED_HEADING = `## Unreleased
6+
7+
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
8+
`;
9+
10+
const contributorMessageRegex = /Work in this release was contributed by (.+)\. Thank you for your contribution!/;
11+
12+
async function run() {
13+
const { getInput } = core;
14+
15+
const name = getInput('name');
16+
17+
if (!name) {
18+
return;
19+
}
20+
21+
const ghUserName = name.startsWith('@') ? name : `@${name}`;
22+
23+
const cwd = process.cwd();
24+
const changelogFilePath = path.resolve(cwd, 'CHANGELOG.md');
25+
26+
const changelogStr = await fs.readFile(changelogFilePath, 'utf8');
27+
28+
// Find the unreleased section
29+
const start = changelogStr.indexOf(UNRELEASED_HEADING) + UNRELEASED_HEADING.length;
30+
const end = changelogStr.slice(start).indexOf('## ');
31+
32+
const inBetween = changelogStr.slice(start, start + end);
33+
34+
const existing = contributorMessageRegex.exec(inBetween);
35+
36+
// If the contributor message already exists, add the new contributor to the list
37+
if (existing) {
38+
const users = existing[1].split(/(?:,? and )|(?:, )/);
39+
if (!users.includes(ghUserName)) {
40+
users.push(ghUserName);
41+
}
42+
43+
const formatter = new Intl.ListFormat('en', {
44+
style: 'long',
45+
type: 'conjunction',
46+
});
47+
48+
const newContributors = formatter.format(users);
49+
const newChangelog = changelogStr.replace(
50+
contributorMessageRegex,
51+
`Work in this release was contributed by ${newContributors}. Thank you for your contribution!`,
52+
);
53+
54+
fs.writeFile(changelogFilePath, newChangelog);
55+
56+
// eslint-disable-next-line no-console
57+
console.log('Added contributor to list of existing contributors.');
58+
return;
59+
}
60+
61+
// If the contributor message does not exist, add it
62+
const newChangelog = changelogStr.replace(
63+
UNRELEASED_HEADING,
64+
`${UNRELEASED_HEADING}\nWork in this release was contributed by ${ghUserName}. Thank you for your contribution!\n`,
65+
);
66+
fs.writeFile(changelogFilePath, newChangelog);
67+
68+
// eslint-disable-next-line no-console
69+
console.log('Added contributor message.');
70+
}
71+
72+
run();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@sentry-internal/external-contributor-gh-action",
3+
"description": "An internal Github Action to add external contributors to the CHANGELOG.md file.",
4+
"version": "8.8.0",
5+
"license": "MIT",
6+
"engines": {
7+
"node": ">=18"
8+
},
9+
"private": true,
10+
"main": "index.mjs",
11+
"type": "module",
12+
"scripts": {
13+
"lint": "eslint . --format stylish",
14+
"fix": "eslint . --format stylish --fix"
15+
},
16+
"dependencies": {
17+
"@actions/core": "1.10.1"
18+
},
19+
"volta": {
20+
"extends": "../../package.json"
21+
}
22+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"dev-packages/overhead-metrics",
8686
"dev-packages/test-utils",
8787
"dev-packages/size-limit-gh-action",
88+
"dev-packages/external-contributor-gh-action",
8889
"dev-packages/rollup-utils"
8990
],
9091
"devDependencies": {

0 commit comments

Comments
 (0)