@swisspost/design-system-changelog-github 10.0.0-next.72 ā 10.0.0-next.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.js +111 -5
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @swisspost/design-system-changelog-github
|
|
2
2
|
|
|
3
|
+
## 10.0.0-next.75
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies, co-contributors are now mentioned in changelogs and added a delay when making GitHub API calls to enable exiting pre-mode with 900+ changesets. (by [@gfellerph](https://github.com/gfellerph) with [#7923](https://github.com/swisspost/design-system/pull/7923))
|
|
8
|
+
|
|
9
|
+
## 10.0.0-next.74
|
|
10
|
+
|
|
11
|
+
## 10.0.0-next.73
|
|
12
|
+
|
|
3
13
|
## 10.0.0-next.72
|
|
4
14
|
|
|
5
15
|
## 10.0.0-next.71
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,105 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const dotenv_1 = require("dotenv");
|
|
8
8
|
const get_github_info_1 = require("@changesets/get-github-info");
|
|
9
9
|
(0, dotenv_1.config)();
|
|
10
|
+
/**
|
|
11
|
+
* Simple concurrency limiter to avoid overwhelming the GitHub API.
|
|
12
|
+
* Limits parallel requests and adds a small delay between them.
|
|
13
|
+
*/
|
|
14
|
+
function createRateLimiter(concurrency, delayMs) {
|
|
15
|
+
let active = 0;
|
|
16
|
+
const queue = [];
|
|
17
|
+
function next() {
|
|
18
|
+
if (queue.length > 0 && active < concurrency) {
|
|
19
|
+
active++;
|
|
20
|
+
const resolve = queue.shift();
|
|
21
|
+
resolve();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return async function (fn) {
|
|
25
|
+
await new Promise(resolve => {
|
|
26
|
+
queue.push(resolve);
|
|
27
|
+
next();
|
|
28
|
+
});
|
|
29
|
+
try {
|
|
30
|
+
const result = await fn();
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
active--;
|
|
35
|
+
// Small delay between requests to avoid hitting secondary rate limits
|
|
36
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
37
|
+
next();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// Cache GitHub info lookups by commit hash to avoid duplicate API calls
|
|
42
|
+
const commitInfoCache = new Map();
|
|
43
|
+
// Cache co-authors by commit hash
|
|
44
|
+
const coAuthorsCache = new Map();
|
|
45
|
+
// Allow max 5 concurrent requests with 100ms delay between them
|
|
46
|
+
const rateLimited = createRateLimiter(5, 100);
|
|
47
|
+
// Progress tracking
|
|
48
|
+
let processedCount = 0;
|
|
49
|
+
let cacheHits = 0;
|
|
50
|
+
async function getGitHubInfo(repo, commit) {
|
|
51
|
+
if (commitInfoCache.has(commit)) {
|
|
52
|
+
cacheHits++;
|
|
53
|
+
processedCount++;
|
|
54
|
+
process.stderr.write(`\rš Changelog: ${processedCount} processed (${cacheHits} cached)`);
|
|
55
|
+
return commitInfoCache.get(commit);
|
|
56
|
+
}
|
|
57
|
+
const promise = rateLimited(() => (0, get_github_info_1.getInfo)({ repo, commit }));
|
|
58
|
+
commitInfoCache.set(commit, promise);
|
|
59
|
+
processedCount++;
|
|
60
|
+
process.stderr.write(`\rš Changelog: ${processedCount} processed (${cacheHits} cached)`);
|
|
61
|
+
return promise;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetch co-authors from the squash merge commit's Co-authored-by trailers.
|
|
65
|
+
* With squash merging, the merge commit contains all co-author information.
|
|
66
|
+
*/
|
|
67
|
+
async function getCoAuthors(repo, commit, mainUser) {
|
|
68
|
+
if (coAuthorsCache.has(commit)) {
|
|
69
|
+
return coAuthorsCache.get(commit);
|
|
70
|
+
}
|
|
71
|
+
const promise = rateLimited(async () => {
|
|
72
|
+
const token = process.env.GITHUB_TOKEN;
|
|
73
|
+
if (!token)
|
|
74
|
+
return [];
|
|
75
|
+
const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com';
|
|
76
|
+
const apiUrl = process.env.GITHUB_API_URL || 'https://api.github.com';
|
|
77
|
+
const response = await fetch(`${apiUrl}/repos/${repo}/commits/${commit}`, {
|
|
78
|
+
headers: {
|
|
79
|
+
Authorization: `Token ${token}`,
|
|
80
|
+
Accept: 'application/vnd.github.v3+json',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok)
|
|
84
|
+
return [];
|
|
85
|
+
const commitData = (await response.json());
|
|
86
|
+
const users = new Set();
|
|
87
|
+
// Parse Co-authored-by trailers from the squash merge commit
|
|
88
|
+
const coAuthorMatches = commitData.commit.message.matchAll(/^Co-authored-by:\s+.+<([^>]+)>/gm);
|
|
89
|
+
for (const match of coAuthorMatches) {
|
|
90
|
+
// GitHub noreply emails contain the username
|
|
91
|
+
const noreplyMatch = match[1].match(/^(\d+\+)?([^@]+)@users\.noreply\.github\.com$/);
|
|
92
|
+
if (noreplyMatch) {
|
|
93
|
+
users.add(noreplyMatch[2]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Remove the main PR author and bots
|
|
97
|
+
if (mainUser)
|
|
98
|
+
users.delete(mainUser);
|
|
99
|
+
for (const user of users) {
|
|
100
|
+
if (user.endsWith('[bot]') || user === 'web-flow') {
|
|
101
|
+
users.delete(user);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return [...users].map(login => `[@${login}](${serverUrl}/${login})`);
|
|
105
|
+
});
|
|
106
|
+
coAuthorsCache.set(commit, promise);
|
|
107
|
+
return promise;
|
|
108
|
+
}
|
|
10
109
|
const changelogFunctions = {
|
|
11
110
|
getDependencyReleaseLine: async (_changesets, dependenciesUpdated, options) => {
|
|
12
111
|
if (!options.repo) {
|
|
@@ -27,10 +126,7 @@ const changelogFunctions = {
|
|
|
27
126
|
const links = await (async () => {
|
|
28
127
|
const commitToFetchFrom = changeset.commit;
|
|
29
128
|
if (commitToFetchFrom) {
|
|
30
|
-
const { links } = await (
|
|
31
|
-
repo: options.repo,
|
|
32
|
-
commit: commitToFetchFrom,
|
|
33
|
-
});
|
|
129
|
+
const { links } = await getGitHubInfo(options.repo, commitToFetchFrom);
|
|
34
130
|
return links;
|
|
35
131
|
}
|
|
36
132
|
return {
|
|
@@ -40,8 +136,18 @@ const changelogFunctions = {
|
|
|
40
136
|
};
|
|
41
137
|
})();
|
|
42
138
|
const users = links.user;
|
|
139
|
+
// Fetch co-authors from the squash merge commit
|
|
140
|
+
let coAuthors = [];
|
|
141
|
+
if (changeset.commit) {
|
|
142
|
+
const mainUser = links.user ? (links.user.match(/@([\w-]+)/)?.[1] ?? null) : null;
|
|
143
|
+
coAuthors = await getCoAuthors(options.repo, changeset.commit, mainUser);
|
|
144
|
+
}
|
|
43
145
|
const pullOrCommit = links.pull || links.commit || null;
|
|
44
|
-
const
|
|
146
|
+
const allUsersList = [users, ...coAuthors].filter(Boolean);
|
|
147
|
+
const allUsers = allUsersList.length > 1
|
|
148
|
+
? `${allUsersList.slice(0, -1).join(', ')} and ${allUsersList[allUsersList.length - 1]}`
|
|
149
|
+
: allUsersList.join('');
|
|
150
|
+
const userString = allUsers ? `by ${allUsers}` : '';
|
|
45
151
|
const pullString = pullOrCommit !== null ? `with ${pullOrCommit}` : '';
|
|
46
152
|
const hasUserOrPull = userString && pullString;
|
|
47
153
|
const entry = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swisspost/design-system-changelog-github",
|
|
3
|
-
"version": "10.0.0-next.
|
|
3
|
+
"version": "10.0.0-next.75",
|
|
4
4
|
"description": "A changelog entry generator for GitHub that links to PRs and users",
|
|
5
5
|
"author": "Swiss Post <design-system@post.ch>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"main": "./dist/index.js",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@changesets/get-github-info": "0.
|
|
22
|
-
"@changesets/types": "6.
|
|
21
|
+
"@changesets/get-github-info": "0.8.0",
|
|
22
|
+
"@changesets/types": "6.1.0",
|
|
23
23
|
"dotenv": "17.2.3"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"@eslint/js": "9.18.0",
|
|
28
28
|
"eslint": "9.26.0",
|
|
29
29
|
"globals": "17.3.0",
|
|
30
|
+
"rimraf": "6.0.1",
|
|
30
31
|
"typescript": "5.9.3",
|
|
31
|
-
"typescript-eslint": "8.59.2"
|
|
32
|
-
"rimraf": "6.0.1"
|
|
32
|
+
"typescript-eslint": "8.59.2"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [
|
|
35
35
|
"changelog",
|