versionary
Advanced tools
@@ -229,3 +229,3 @@ "use strict"; | ||
| const bodyWithoutHeading = existing.replace(/^# Changelog\s*/u, ""); | ||
| const separator = existing.length > 0 ? "\n" : ""; | ||
| const separator = bodyWithoutHeading.length > 0 ? "\n\n" : ""; | ||
| const next = `${`${heading}${section}${separator}${bodyWithoutHeading}`.trimEnd()}\n`; | ||
@@ -232,0 +232,0 @@ node_fs_1.default.writeFileSync(changelogPath, next, "utf8"); |
+3
-10
@@ -160,9 +160,2 @@ "use strict"; | ||
| } | ||
| function resolveReleaseName(cwd, packagePath, packageConfig, strategy, strategyConfig) { | ||
| const configuredName = packageConfig["package-name"]?.trim(); | ||
| if (configuredName) { | ||
| return configuredName; | ||
| } | ||
| return strategy.readPackageName?.(cwd, strategyConfig) ?? packagePath; | ||
| } | ||
| function buildReleaseTargets(cwd, plan, loadedConfig) { | ||
@@ -182,3 +175,3 @@ const releaseTargets = plan.packages | ||
| const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, pkg.path, packageConfig); | ||
| const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config); | ||
| const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config); | ||
| const tagPrefix = normalizeReleaseNameForTag(releaseName); | ||
@@ -216,3 +209,3 @@ return { | ||
| const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, pkg.path, packageConfig); | ||
| const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config); | ||
| const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config); | ||
| metadataByPath[pkg.path] = { | ||
@@ -395,3 +388,3 @@ releaseName, | ||
| const packageContext = (0, package_context_js_1.resolvePackageStrategyContext)(loadedConfig, packagePath, packageConfig); | ||
| const releaseName = resolveReleaseName(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config); | ||
| const releaseName = (0, package_context_js_1.resolveReleaseName)(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config); | ||
| return normalizeReleaseNameForTag(releaseName); | ||
@@ -398,0 +391,0 @@ }; |
| import type { VersionaryConfig } from "../types/config.js"; | ||
| import type { VersionaryPluginContext } from "../types/plugins.js"; | ||
| export declare function resolveTargetPackageName(cwd: string, config: VersionaryConfig, targetPath: string): string | undefined; | ||
| export declare function extractReleaseNotes(content: string, version: string, changelogFormat: "markdown-changelog" | "r-news"): string; | ||
@@ -4,0 +5,0 @@ export declare function extractClosingReferencesFromNotes(notes: string): number[]; |
+28
-11
@@ -6,2 +6,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.resolveTargetPackageName = resolveTargetPackageName; | ||
| exports.extractReleaseNotes = extractReleaseNotes; | ||
@@ -19,2 +20,3 @@ exports.extractClosingReferencesFromNotes = extractClosingReferencesFromNotes; | ||
| const client_js_1 = require("../scm/client.js"); | ||
| const package_context_js_1 = require("../strategy/package-context.js"); | ||
| const resolve_js_1 = require("../strategy/resolve.js"); | ||
@@ -28,2 +30,11 @@ const plan_js_1 = require("./plan.js"); | ||
| } | ||
| function resolveTargetPackageName(cwd, config, targetPath) { | ||
| const packageConfig = config.packages?.[targetPath] ?? {}; | ||
| const { strategy, config: strategyConfig } = (0, package_context_js_1.resolvePackageStrategyContext)(config, targetPath, packageConfig); | ||
| const resolved = (0, package_context_js_1.resolveReleaseName)(cwd, targetPath, packageConfig, strategy, strategyConfig); | ||
| if (!resolved || resolved === targetPath) { | ||
| return undefined; | ||
| } | ||
| return resolved; | ||
| } | ||
| function extractReleaseNotes(content, version, changelogFormat) { | ||
@@ -178,3 +189,3 @@ const lines = content.split("\n"); | ||
| const releases = []; | ||
| const referencesByTag = new Map(); | ||
| const referenceReleases = []; | ||
| for (const target of targets) { | ||
@@ -184,3 +195,3 @@ const targetChangelogFile = resolveTargetChangelogFile(loaded.config, changelogFile, target.path); | ||
| const releaseNotes = readReleaseNotes(cwd, target.version, targetChangelogFile, targetChangelogFormat); | ||
| referencesByTag.set(target.tag, extractClosingReferencesFromNotes(releaseNotes)); | ||
| const references = extractClosingReferencesFromNotes(releaseNotes); | ||
| const outcome = await (0, recovery_js_1.executeIdempotentReleaseTarget)(cwd, { | ||
@@ -205,17 +216,23 @@ tag: target.tag, | ||
| }); | ||
| const references = referencesByTag.get(outcome.tag) ?? []; | ||
| if (references.length > 0 && | ||
| referenceCommentMode !== "off" && | ||
| scmClient.createReleaseReferenceComments) { | ||
| await scmClient.createReleaseReferenceComments({ | ||
| if (references.length > 0) { | ||
| referenceReleases.push({ | ||
| name: resolveTargetPackageName(cwd, loaded.config, target.path), | ||
| tag: outcome.tag, | ||
| version: target.version, | ||
| releaseUrl: outcome.url, | ||
| references, | ||
| mode: referenceCommentMode, | ||
| }, { | ||
| cwd, | ||
| logger: options.logger, | ||
| }); | ||
| } | ||
| } | ||
| if (referenceReleases.length > 0 && | ||
| referenceCommentMode !== "off" && | ||
| scmClient.createReleaseReferenceComments) { | ||
| await scmClient.createReleaseReferenceComments({ | ||
| releases: referenceReleases, | ||
| mode: referenceCommentMode, | ||
| }, { | ||
| cwd, | ||
| logger: options.logger, | ||
| }); | ||
| } | ||
| const published = releases.map((outcome) => `${outcome.tag}: ${outcome.url} (tag=${outcome.tagStatus}, metadata=${outcome.metadataStatus})`); | ||
@@ -222,0 +239,0 @@ return { |
@@ -89,2 +89,38 @@ "use strict"; | ||
| } | ||
| function groupReleasesByIssue(releases) { | ||
| const byIssue = new Map(); | ||
| for (const release of releases) { | ||
| for (const reference of release.references) { | ||
| const bucket = byIssue.get(reference) ?? []; | ||
| if (!bucket.some((entry) => entry.tag === release.tag)) { | ||
| bucket.push(release); | ||
| } | ||
| byIssue.set(reference, bucket); | ||
| } | ||
| } | ||
| for (const bucket of byIssue.values()) { | ||
| bucket.sort((a, b) => a.tag.localeCompare(b.tag)); | ||
| } | ||
| return new Map([...byIssue.entries()].sort(([a], [b]) => a - b)); | ||
| } | ||
| function renderReleaseLink(release) { | ||
| if (release.name) { | ||
| return `[\`${release.name}\` v${release.version}](${release.releaseUrl})`; | ||
| } | ||
| return `[version ${release.version}](${release.releaseUrl})`; | ||
| } | ||
| function renderReleaseReferenceCommentBody(releases) { | ||
| const footer = "Released by [Versionary](https://github.com/jolars/versionary)."; | ||
| if (releases.length === 1) { | ||
| const release = releases[0]; | ||
| if (!release) { | ||
| throw new Error("Expected at least one release for comment body."); | ||
| } | ||
| return `This is included in ${renderReleaseLink(release)}. :tada:\n\n${footer}`; | ||
| } | ||
| const bullets = releases | ||
| .map((release) => `- ${renderReleaseLink(release)}`) | ||
| .join("\n"); | ||
| return `This is included in the following releases: :tada:\n\n${bullets}\n\n${footer}`; | ||
| } | ||
| function createGitHubPlugin() { | ||
@@ -279,7 +315,7 @@ return { | ||
| const octokit = new rest_1.Octokit({ auth: getGitHubToken() }); | ||
| const uniqueReferences = [...new Set(input.references)].sort((a, b) => a - b); | ||
| const mode = input.mode ?? "best-effort"; | ||
| const releasesByIssue = groupReleasesByIssue(input.releases); | ||
| const commented = []; | ||
| const mode = input.mode ?? "best-effort"; | ||
| for (const reference of uniqueReferences) { | ||
| const body = `This is included in [version ${input.version}](${input.releaseUrl}). :tada:\n\nReleased by [Versionary](https://github.com/jolars/versionary).`; | ||
| for (const [reference, releases] of releasesByIssue) { | ||
| const body = renderReleaseReferenceCommentBody(releases); | ||
| try { | ||
@@ -286,0 +322,0 @@ await octokit.issues.createComment({ |
@@ -44,6 +44,11 @@ export type ScmProvider = "github"; | ||
| } | ||
| export interface ScmReleaseReferenceCommentsInput { | ||
| export interface ScmReleaseReferenceCommentsRelease { | ||
| name?: string; | ||
| tag: string; | ||
| version: string; | ||
| releaseUrl: string; | ||
| references: number[]; | ||
| } | ||
| export interface ScmReleaseReferenceCommentsInput { | ||
| releases: ScmReleaseReferenceCommentsRelease[]; | ||
| mode?: "best-effort" | "strict"; | ||
@@ -50,0 +55,0 @@ } |
| import type { VersionaryConfig, VersionaryPackage } from "../types/config.js"; | ||
| import type { VersionStrategy } from "./types.js"; | ||
| export declare function resolveReleaseName(cwd: string, packagePath: string, packageConfig: VersionaryPackage, strategy: VersionStrategy, strategyConfig: VersionaryConfig): string; | ||
| export declare function resolvePackageStrategyContext(rootConfig: VersionaryConfig, packagePath: string, packageConfig: VersionaryPackage): { | ||
@@ -4,0 +5,0 @@ strategy: VersionStrategy; |
@@ -6,5 +6,13 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.resolveReleaseName = resolveReleaseName; | ||
| exports.resolvePackageStrategyContext = resolvePackageStrategyContext; | ||
| const node_path_1 = __importDefault(require("node:path")); | ||
| const resolve_js_1 = require("./resolve.js"); | ||
| function resolveReleaseName(cwd, packagePath, packageConfig, strategy, strategyConfig) { | ||
| const configuredName = packageConfig["package-name"]?.trim(); | ||
| if (configuredName) { | ||
| return configuredName; | ||
| } | ||
| return strategy.readPackageName?.(cwd, strategyConfig) ?? packagePath; | ||
| } | ||
| function withVersionFile(config, versionFile) { | ||
@@ -11,0 +19,0 @@ return { |
+1
-1
| { | ||
| "name": "versionary", | ||
| "version": "0.27.0", | ||
| "version": "0.28.0", | ||
| "description": "Automatic release framework based on conventional commits and semantic versioning", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
271940
0.99%6037
1.02%