versionary 0.27.0 → 0.28.0
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/dist/release/changelog.js +1 -1
- package/dist/release/pr.js +3 -10
- package/dist/release/release.d.ts +1 -0
- package/dist/release/release.js +28 -11
- package/dist/scm/github-plugin.js +40 -4
- package/dist/scm/types.d.ts +6 -1
- package/dist/strategy/package-context.d.ts +1 -0
- package/dist/strategy/package-context.js +8 -0
- package/package.json +1 -1
|
@@ -226,7 +226,7 @@ function prependChangelog(cwd, changelogFile, section, format = "markdown-change
|
|
|
226
226
|
}
|
|
227
227
|
const heading = "# Changelog\n\n";
|
|
228
228
|
const bodyWithoutHeading = existing.replace(/^# Changelog\s*/u, "");
|
|
229
|
-
const separator =
|
|
229
|
+
const separator = bodyWithoutHeading.length > 0 ? "\n\n" : "";
|
|
230
230
|
const next = `${`${heading}${section}${separator}${bodyWithoutHeading}`.trimEnd()}\n`;
|
|
231
231
|
node_fs_1.default.writeFileSync(changelogPath, next, "utf8");
|
|
232
232
|
}
|
package/dist/release/pr.js
CHANGED
|
@@ -157,13 +157,6 @@ function fetchRemoteReleaseBranch(cwd, branch) {
|
|
|
157
157
|
});
|
|
158
158
|
return remoteRef;
|
|
159
159
|
}
|
|
160
|
-
function resolveReleaseName(cwd, packagePath, packageConfig, strategy, strategyConfig) {
|
|
161
|
-
const configuredName = packageConfig["package-name"]?.trim();
|
|
162
|
-
if (configuredName) {
|
|
163
|
-
return configuredName;
|
|
164
|
-
}
|
|
165
|
-
return strategy.readPackageName?.(cwd, strategyConfig) ?? packagePath;
|
|
166
|
-
}
|
|
167
160
|
function buildReleaseTargets(cwd, plan, loadedConfig) {
|
|
168
161
|
const releaseTargets = plan.packages
|
|
169
162
|
? plan.packages
|
|
@@ -178,7 +171,7 @@ function buildReleaseTargets(cwd, plan, loadedConfig) {
|
|
|
178
171
|
}
|
|
179
172
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
180
173
|
const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, pkg.path, packageConfig);
|
|
181
|
-
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
174
|
+
const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
182
175
|
const tagPrefix = normalizeReleaseNameForTag(releaseName);
|
|
183
176
|
return {
|
|
184
177
|
path: pkg.path,
|
|
@@ -211,7 +204,7 @@ function buildPackageReleaseMetadata(cwd, plan, loadedConfig) {
|
|
|
211
204
|
}
|
|
212
205
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
213
206
|
const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, pkg.path, packageConfig);
|
|
214
|
-
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
207
|
+
const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
215
208
|
metadataByPath[pkg.path] = {
|
|
216
209
|
releaseName,
|
|
217
210
|
tagPrefix: normalizeReleaseNameForTag(releaseName),
|
|
@@ -389,7 +382,7 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
389
382
|
}
|
|
390
383
|
const packageConfig = loadedConfig.packages?.[packagePath] ?? {};
|
|
391
384
|
const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, packagePath, packageConfig);
|
|
392
|
-
const releaseName = resolveReleaseName(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config);
|
|
385
|
+
const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config);
|
|
393
386
|
return normalizeReleaseNameForTag(releaseName);
|
|
394
387
|
};
|
|
395
388
|
if (plan?.packages && plan.packages.length > 1) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { VersionaryConfig } from "../types/config.js";
|
|
2
2
|
import type { VersionaryPluginContext } from "../types/plugins.js";
|
|
3
|
+
export declare function resolveTargetPackageName(cwd: string, config: VersionaryConfig, targetPath: string): string | undefined;
|
|
3
4
|
export declare function extractReleaseNotes(content: string, version: string, changelogFormat: "markdown-changelog" | "r-news"): string;
|
|
4
5
|
export declare function extractClosingReferencesFromNotes(notes: string): number[];
|
|
5
6
|
export declare function resolveTargetChangelogFile(config: VersionaryConfig, rootChangelogFile: string, targetPath: string): string;
|
package/dist/release/release.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveTargetPackageName = resolveTargetPackageName;
|
|
6
7
|
exports.extractReleaseNotes = extractReleaseNotes;
|
|
7
8
|
exports.extractClosingReferencesFromNotes = extractClosingReferencesFromNotes;
|
|
8
9
|
exports.resolveTargetChangelogFile = resolveTargetChangelogFile;
|
|
@@ -15,6 +16,7 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
15
16
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
17
|
const load_config_js_1 = require("../config/load-config.js");
|
|
17
18
|
const client_js_1 = require("../scm/client.js");
|
|
19
|
+
const package_context_js_1 = require("../strategy/package-context.js");
|
|
18
20
|
const resolve_js_1 = require("../strategy/resolve.js");
|
|
19
21
|
const plan_js_1 = require("./plan.js");
|
|
20
22
|
const pr_js_1 = require("./pr.js");
|
|
@@ -23,6 +25,15 @@ const state_js_1 = require("./state.js");
|
|
|
23
25
|
function escapeRegExp(input) {
|
|
24
26
|
return input.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
25
27
|
}
|
|
28
|
+
function resolveTargetPackageName(cwd, config, targetPath) {
|
|
29
|
+
const packageConfig = config.packages?.[targetPath] ?? {};
|
|
30
|
+
const { strategy, config: strategyConfig } = (0, package_context_js_1.resolvePackageStrategyContext)(config, targetPath, packageConfig);
|
|
31
|
+
const resolved = (0, package_context_js_1.resolveReleaseName)(cwd, targetPath, packageConfig, strategy, strategyConfig);
|
|
32
|
+
if (!resolved || resolved === targetPath) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return resolved;
|
|
36
|
+
}
|
|
26
37
|
function extractReleaseNotes(content, version, changelogFormat) {
|
|
27
38
|
const lines = content.split("\n");
|
|
28
39
|
const shortVersion = version.replace(/\.\d+$/u, "");
|
|
@@ -172,12 +183,12 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
172
183
|
}
|
|
173
184
|
const scmClient = (0, client_js_1.getScmClient)();
|
|
174
185
|
const releases = [];
|
|
175
|
-
const
|
|
186
|
+
const referenceReleases = [];
|
|
176
187
|
for (const target of targets) {
|
|
177
188
|
const targetChangelogFile = resolveTargetChangelogFile(loaded.config, changelogFile, target.path);
|
|
178
189
|
const targetChangelogFormat = resolveTargetChangelogFormat(loaded.config, target.path);
|
|
179
190
|
const releaseNotes = readReleaseNotes(cwd, target.version, targetChangelogFile, targetChangelogFormat);
|
|
180
|
-
|
|
191
|
+
const references = extractClosingReferencesFromNotes(releaseNotes);
|
|
181
192
|
const outcome = await (0, recovery_js_1.executeIdempotentReleaseTarget)(cwd, {
|
|
182
193
|
tag: target.tag,
|
|
183
194
|
version: target.version,
|
|
@@ -197,21 +208,27 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
197
208
|
tagStatus: outcome.tagStatus,
|
|
198
209
|
metadataStatus: outcome.metadataStatus,
|
|
199
210
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
await scmClient.createReleaseReferenceComments({
|
|
211
|
+
if (references.length > 0) {
|
|
212
|
+
referenceReleases.push({
|
|
213
|
+
name: resolveTargetPackageName(cwd, loaded.config, target.path),
|
|
214
|
+
tag: outcome.tag,
|
|
205
215
|
version: target.version,
|
|
206
216
|
releaseUrl: outcome.url,
|
|
207
217
|
references,
|
|
208
|
-
mode: referenceCommentMode,
|
|
209
|
-
}, {
|
|
210
|
-
cwd,
|
|
211
|
-
logger: options.logger,
|
|
212
218
|
});
|
|
213
219
|
}
|
|
214
220
|
}
|
|
221
|
+
if (referenceReleases.length > 0 &&
|
|
222
|
+
referenceCommentMode !== "off" &&
|
|
223
|
+
scmClient.createReleaseReferenceComments) {
|
|
224
|
+
await scmClient.createReleaseReferenceComments({
|
|
225
|
+
releases: referenceReleases,
|
|
226
|
+
mode: referenceCommentMode,
|
|
227
|
+
}, {
|
|
228
|
+
cwd,
|
|
229
|
+
logger: options.logger,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
215
232
|
const published = releases.map((outcome) => `${outcome.tag}: ${outcome.url} (tag=${outcome.tagStatus}, metadata=${outcome.metadataStatus})`);
|
|
216
233
|
return {
|
|
217
234
|
action: "release-published",
|
|
@@ -86,6 +86,42 @@ async function ensureLabels(octokit, repo, pullNumber, labels, branchContext) {
|
|
|
86
86
|
throw new Error(`Failed applying labels to pull request #${pullNumber}: [${repoRef(repo)} base=${branchContext.baseBranch} head=${branchContext.headBranch}] ${message}`);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
function groupReleasesByIssue(releases) {
|
|
90
|
+
const byIssue = new Map();
|
|
91
|
+
for (const release of releases) {
|
|
92
|
+
for (const reference of release.references) {
|
|
93
|
+
const bucket = byIssue.get(reference) ?? [];
|
|
94
|
+
if (!bucket.some((entry) => entry.tag === release.tag)) {
|
|
95
|
+
bucket.push(release);
|
|
96
|
+
}
|
|
97
|
+
byIssue.set(reference, bucket);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const bucket of byIssue.values()) {
|
|
101
|
+
bucket.sort((a, b) => a.tag.localeCompare(b.tag));
|
|
102
|
+
}
|
|
103
|
+
return new Map([...byIssue.entries()].sort(([a], [b]) => a - b));
|
|
104
|
+
}
|
|
105
|
+
function renderReleaseLink(release) {
|
|
106
|
+
if (release.name) {
|
|
107
|
+
return `[\`${release.name}\` v${release.version}](${release.releaseUrl})`;
|
|
108
|
+
}
|
|
109
|
+
return `[version ${release.version}](${release.releaseUrl})`;
|
|
110
|
+
}
|
|
111
|
+
function renderReleaseReferenceCommentBody(releases) {
|
|
112
|
+
const footer = "Released by [Versionary](https://github.com/jolars/versionary).";
|
|
113
|
+
if (releases.length === 1) {
|
|
114
|
+
const release = releases[0];
|
|
115
|
+
if (!release) {
|
|
116
|
+
throw new Error("Expected at least one release for comment body.");
|
|
117
|
+
}
|
|
118
|
+
return `This is included in ${renderReleaseLink(release)}. :tada:\n\n${footer}`;
|
|
119
|
+
}
|
|
120
|
+
const bullets = releases
|
|
121
|
+
.map((release) => `- ${renderReleaseLink(release)}`)
|
|
122
|
+
.join("\n");
|
|
123
|
+
return `This is included in the following releases: :tada:\n\n${bullets}\n\n${footer}`;
|
|
124
|
+
}
|
|
89
125
|
function createGitHubPlugin() {
|
|
90
126
|
return {
|
|
91
127
|
name: "github",
|
|
@@ -275,11 +311,11 @@ function createGitHubPlugin() {
|
|
|
275
311
|
async createReleaseReferenceComments(input, context) {
|
|
276
312
|
const repo = getRepoFromEnv();
|
|
277
313
|
const octokit = new rest_1.Octokit({ auth: getGitHubToken() });
|
|
278
|
-
const uniqueReferences = [...new Set(input.references)].sort((a, b) => a - b);
|
|
279
|
-
const commented = [];
|
|
280
314
|
const mode = input.mode ?? "best-effort";
|
|
281
|
-
|
|
282
|
-
|
|
315
|
+
const releasesByIssue = groupReleasesByIssue(input.releases);
|
|
316
|
+
const commented = [];
|
|
317
|
+
for (const [reference, releases] of releasesByIssue) {
|
|
318
|
+
const body = renderReleaseReferenceCommentBody(releases);
|
|
283
319
|
try {
|
|
284
320
|
await octokit.issues.createComment({
|
|
285
321
|
owner: repo.owner,
|
package/dist/scm/types.d.ts
CHANGED
|
@@ -41,10 +41,15 @@ export interface ScmReleaseMetadataResult {
|
|
|
41
41
|
url: string;
|
|
42
42
|
status?: "created" | "exists";
|
|
43
43
|
}
|
|
44
|
-
export interface
|
|
44
|
+
export interface ScmReleaseReferenceCommentsRelease {
|
|
45
|
+
name?: string;
|
|
46
|
+
tag: string;
|
|
45
47
|
version: string;
|
|
46
48
|
releaseUrl: string;
|
|
47
49
|
references: number[];
|
|
50
|
+
}
|
|
51
|
+
export interface ScmReleaseReferenceCommentsInput {
|
|
52
|
+
releases: ScmReleaseReferenceCommentsRelease[];
|
|
48
53
|
mode?: "best-effort" | "strict";
|
|
49
54
|
}
|
|
50
55
|
export interface ScmReleaseReferenceCommentsResult {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { VersionaryConfig, VersionaryPackage } from "../types/config.js";
|
|
2
2
|
import type { VersionStrategy } from "./types.js";
|
|
3
|
+
export declare function resolveReleaseName(cwd: string, packagePath: string, packageConfig: VersionaryPackage, strategy: VersionStrategy, strategyConfig: VersionaryConfig): string;
|
|
3
4
|
export declare function resolvePackageStrategyContext(rootConfig: VersionaryConfig, packagePath: string, packageConfig: VersionaryPackage): {
|
|
4
5
|
strategy: VersionStrategy;
|
|
5
6
|
config: VersionaryConfig;
|
|
@@ -3,9 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveReleaseName = resolveReleaseName;
|
|
6
7
|
exports.resolvePackageStrategyContext = resolvePackageStrategyContext;
|
|
7
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
9
|
const resolve_js_1 = require("./resolve.js");
|
|
10
|
+
function resolveReleaseName(cwd, packagePath, packageConfig, strategy, strategyConfig) {
|
|
11
|
+
const configuredName = packageConfig["package-name"]?.trim();
|
|
12
|
+
if (configuredName) {
|
|
13
|
+
return configuredName;
|
|
14
|
+
}
|
|
15
|
+
return strategy.readPackageName?.(cwd, strategyConfig) ?? packagePath;
|
|
16
|
+
}
|
|
9
17
|
function withVersionFile(config, versionFile) {
|
|
10
18
|
return {
|
|
11
19
|
...config,
|