create-app-release 1.0.0 → 1.0.2
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 +12 -0
- package/package.json +1 -1
- package/src/index.js +81 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.2] - 2025-02-09
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Added smart filtering to exclude PRs already included in previous releases
|
|
13
|
+
|
|
14
|
+
## [1.0.1] - 2025-02-07
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Enhanced pull request fetching to retrieve all closed pull requests using pagination
|
|
19
|
+
|
|
8
20
|
## [1.0.0] - 2025-02-06
|
|
9
21
|
|
|
10
22
|
### Added
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -106,24 +106,102 @@ async function initializeTokens() {
|
|
|
106
106
|
return { githubToken, openaiToken };
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Get the latest release pull request
|
|
111
|
+
* @param {string} owner - Repository owner
|
|
112
|
+
* @param {string} repo - Repository name
|
|
113
|
+
* @returns {Promise<Object|null>} Latest release PR or null
|
|
114
|
+
*/
|
|
115
|
+
async function getLatestReleasePR(owner, repo) {
|
|
116
|
+
try {
|
|
117
|
+
const iterator = octokit.paginate.iterator(octokit.rest.pulls.list, {
|
|
118
|
+
owner,
|
|
119
|
+
repo,
|
|
120
|
+
state: 'closed',
|
|
121
|
+
sort: 'updated',
|
|
122
|
+
direction: 'desc',
|
|
123
|
+
per_page: 100,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
for await (const { data } of iterator) {
|
|
127
|
+
// SemVer regex pattern: matches X.Y.Z with optional pre-release and build metadata
|
|
128
|
+
const semverPattern =
|
|
129
|
+
/\b(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?\b/;
|
|
130
|
+
|
|
131
|
+
const recentReleasePR = data.find((pr) => semverPattern.test(pr.title));
|
|
132
|
+
if (recentReleasePR) {
|
|
133
|
+
return recentReleasePR;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error(chalk.red('Failed to fetch latest release PR:', error.message));
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Extract PR numbers from release PR description
|
|
145
|
+
* @param {string} description - PR description
|
|
146
|
+
* @returns {Set<number>} Set of PR numbers
|
|
147
|
+
*/
|
|
148
|
+
function extractPRNumbersFromDescription(description) {
|
|
149
|
+
if (!description) return new Set();
|
|
150
|
+
|
|
151
|
+
// Match PR numbers in various formats like #123, (#123), or just plain 123 in PR lists
|
|
152
|
+
const prMatches = description.match(/#\d+|\(#\d+\)|(?<=PR:?\s*)\d+/g) || [];
|
|
153
|
+
|
|
154
|
+
return new Set(prMatches.map((match) => parseInt(match.replace(/[^0-9]/g, ''))));
|
|
155
|
+
}
|
|
156
|
+
|
|
109
157
|
/**
|
|
110
158
|
* Fetch closed pull requests from the repository
|
|
111
159
|
* @param {string} owner - Repository owner
|
|
112
160
|
* @param {string} repo - Repository name
|
|
161
|
+
* @param {string} targetBranch - Target branch name
|
|
113
162
|
* @returns {Promise<Array>} List of pull requests
|
|
114
163
|
*/
|
|
115
164
|
async function fetchPullRequests(owner, repo) {
|
|
116
165
|
const spinner = ora('Fetching pull requests...').start();
|
|
117
166
|
try {
|
|
118
|
-
|
|
167
|
+
// Get the latest release PR first
|
|
168
|
+
const latestReleasePR = await getLatestReleasePR(owner, repo);
|
|
169
|
+
|
|
170
|
+
const includedPRNumbers = extractPRNumbersFromDescription(latestReleasePR?.body);
|
|
171
|
+
const pulls = [];
|
|
172
|
+
const iterator = octokit.paginate.iterator(octokit.rest.pulls.list, {
|
|
119
173
|
owner,
|
|
120
174
|
repo,
|
|
121
175
|
state: 'closed',
|
|
122
176
|
sort: 'updated',
|
|
123
177
|
direction: 'desc',
|
|
124
|
-
per_page:
|
|
178
|
+
per_page: 100,
|
|
125
179
|
});
|
|
126
|
-
|
|
180
|
+
|
|
181
|
+
for await (const { data } of iterator) {
|
|
182
|
+
// Filter PRs that are merged after the last release and not included in it
|
|
183
|
+
const relevantPRs = data.filter((pr) => {
|
|
184
|
+
if (!pr.merged_at) return false;
|
|
185
|
+
|
|
186
|
+
const isAfterLastRelease = latestReleasePR
|
|
187
|
+
? new Date(pr.merged_at) >= new Date(latestReleasePR.merged_at)
|
|
188
|
+
: true;
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
isAfterLastRelease &&
|
|
192
|
+
!includedPRNumbers.has(`#${pr.number}`) &&
|
|
193
|
+
pr.id !== latestReleasePR?.id
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
pulls.push(...relevantPRs);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const excludedCount = includedPRNumbers.size;
|
|
200
|
+
const message = latestReleasePR
|
|
201
|
+
? `Found ${pulls.length} new merged pull requests (excluding ${excludedCount} PRs from last release)`
|
|
202
|
+
: `Found ${pulls.length} merged pull requests`;
|
|
203
|
+
|
|
204
|
+
spinner.succeed(message);
|
|
127
205
|
return pulls;
|
|
128
206
|
} catch (error) {
|
|
129
207
|
spinner.fail('Failed to fetch pull requests');
|