@williamthorsen/release-kit 6.0.0 → 8.0.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/CHANGELOG.md +18 -0
- package/README.md +5 -3
- package/dist/esm/assertCleanWorkingTree.js +9 -14
- package/dist/esm/bin/release-kit.js +200 -199
- package/dist/esm/buildChangelogEntries.d.ts +2 -2
- package/dist/esm/buildChangelogEntries.js +142 -149
- package/dist/esm/buildDependencyGraph.d.ts +1 -1
- package/dist/esm/buildDependencyGraph.js +60 -59
- package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -1
- package/dist/esm/buildEmptyReleaseEntry.js +12 -15
- package/dist/esm/buildReleaseSummary.d.ts +1 -1
- package/dist/esm/buildReleaseSummary.js +23 -26
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +1 -1
- package/dist/esm/buildSyntheticChangelogEntry.js +9 -12
- package/dist/esm/bumpAllVersions.d.ts +1 -1
- package/dist/esm/bumpAllVersions.js +51 -52
- package/dist/esm/bumpVersion.d.ts +1 -1
- package/dist/esm/bumpVersion.js +25 -28
- package/dist/esm/changelogJsonFile.d.ts +1 -1
- package/dist/esm/changelogJsonFile.js +59 -62
- package/dist/esm/changelogJsonUtils.d.ts +1 -1
- package/dist/esm/changelogJsonUtils.js +35 -32
- package/dist/esm/changelogOverrides.d.ts +1 -1
- package/dist/esm/changelogOverrides.js +374 -377
- package/dist/esm/checkWorkTypesDrift.js +104 -102
- package/dist/esm/collectPolicyViolations.d.ts +2 -2
- package/dist/esm/collectPolicyViolations.js +11 -14
- package/dist/esm/commitCommand.js +48 -46
- package/dist/esm/compareVersions.js +20 -23
- package/dist/esm/createGithubRelease.js +56 -59
- package/dist/esm/createGithubReleaseCommand.js +21 -23
- package/dist/esm/createTags.js +57 -56
- package/dist/esm/decideRelease.d.ts +2 -2
- package/dist/esm/decideRelease.js +27 -41
- package/dist/esm/defaults.d.ts +3 -3
- package/dist/esm/defaults.js +36 -48
- package/dist/esm/deleteFileIfExists.js +10 -12
- package/dist/esm/deriveWorkspaceConfig.d.ts +1 -1
- package/dist/esm/deriveWorkspaceConfig.js +34 -36
- package/dist/esm/detectPackageManager.js +35 -37
- package/dist/esm/detectUndeclaredTagPrefixes.js +41 -40
- package/dist/esm/determineBumpFromCommits.d.ts +2 -2
- package/dist/esm/determineBumpFromCommits.js +25 -29
- package/dist/esm/determineBumpType.d.ts +1 -1
- package/dist/esm/determineBumpType.js +31 -32
- package/dist/esm/discoverWorkspaces.js +38 -40
- package/dist/esm/format.js +6 -11
- package/dist/esm/generateChangelogs.d.ts +1 -1
- package/dist/esm/generateChangelogs.js +13 -17
- package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
- package/dist/esm/getCommitsSinceTarget.js +54 -55
- package/dist/esm/hasPrettierConfig.js +33 -35
- package/dist/esm/help/prepareHelp.js +4 -8
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.js +2 -8
- package/dist/esm/init/checks.js +28 -32
- package/dist/esm/init/detectRepoType.js +12 -15
- package/dist/esm/init/initCommand.js +60 -54
- package/dist/esm/init/parseJsonRecord.js +9 -11
- package/dist/esm/init/scaffold.d.ts +1 -1
- package/dist/esm/init/scaffold.js +32 -38
- package/dist/esm/init/templates.d.ts +1 -1
- package/dist/esm/init/templates.js +16 -22
- package/dist/esm/injectReleaseNotesIntoReadme.js +42 -49
- package/dist/esm/injectSection.js +17 -27
- package/dist/esm/loadConfig.d.ts +1 -1
- package/dist/esm/loadConfig.js +206 -225
- package/dist/esm/parseCommitMessage.d.ts +1 -1
- package/dist/esm/parseCommitMessage.js +72 -76
- package/dist/esm/parseRequestedTags.js +6 -9
- package/dist/esm/prepareCommand.d.ts +1 -1
- package/dist/esm/prepareCommand.js +225 -235
- package/dist/esm/previewTagPrefixes.d.ts +1 -1
- package/dist/esm/previewTagPrefixes.js +101 -96
- package/dist/esm/propagateBumps.d.ts +2 -2
- package/dist/esm/propagateBumps.js +48 -50
- package/dist/esm/publish.d.ts +2 -2
- package/dist/esm/publish.js +22 -28
- package/dist/esm/publishCommand.js +75 -80
- package/dist/esm/pushCommand.js +33 -34
- package/dist/esm/pushRelease.d.ts +1 -1
- package/dist/esm/pushRelease.js +21 -24
- package/dist/esm/readCurrentVersion.js +13 -17
- package/dist/esm/releasePrepare.d.ts +1 -1
- package/dist/esm/releasePrepare.js +213 -231
- package/dist/esm/releasePrepareMono.d.ts +2 -2
- package/dist/esm/releasePrepareMono.js +434 -494
- package/dist/esm/releasePrepareProject.d.ts +2 -2
- package/dist/esm/releasePrepareProject.js +143 -153
- package/dist/esm/renderChangelogMarkdown.d.ts +1 -1
- package/dist/esm/renderChangelogMarkdown.js +20 -24
- package/dist/esm/renderReleaseNotes.d.ts +1 -1
- package/dist/esm/renderReleaseNotes.js +50 -55
- package/dist/esm/reportPrepare.d.ts +1 -1
- package/dist/esm/reportPrepare.js +230 -231
- package/dist/esm/resolveCliffConfigPath.js +18 -23
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +47 -45
- package/dist/esm/resolveReleaseNotesConfig.d.ts +1 -1
- package/dist/esm/resolveReleaseNotesConfig.js +39 -43
- package/dist/esm/resolveReleaseTags.d.ts +1 -1
- package/dist/esm/resolveReleaseTags.js +39 -40
- package/dist/esm/runGitCliff.js +27 -30
- package/dist/esm/showTagPrefixesCommand.js +48 -70
- package/dist/esm/stripEmojiPrefix.js +2 -5
- package/dist/esm/stripScope.js +18 -21
- package/dist/esm/sync-labels/generateCommand.d.ts +1 -1
- package/dist/esm/sync-labels/generateCommand.js +51 -53
- package/dist/esm/sync-labels/initCommand.js +46 -48
- package/dist/esm/sync-labels/loadSyncLabelsConfig.d.ts +1 -1
- package/dist/esm/sync-labels/loadSyncLabelsConfig.js +46 -52
- package/dist/esm/sync-labels/presets.d.ts +1 -1
- package/dist/esm/sync-labels/presets.js +40 -43
- package/dist/esm/sync-labels/resolveLabels.d.ts +1 -1
- package/dist/esm/sync-labels/resolveLabels.js +28 -35
- package/dist/esm/sync-labels/syncCommand.js +30 -31
- package/dist/esm/sync-labels/templates.d.ts +1 -1
- package/dist/esm/sync-labels/templates.js +23 -26
- package/dist/esm/sync-labels/types.js +1 -0
- package/dist/esm/syncWorkTypes.js +83 -84
- package/dist/esm/tagCommand.js +12 -14
- package/dist/esm/typeGuards.js +4 -8
- package/dist/esm/types.js +66 -60
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +109 -115
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +2 -2
- package/dist/esm/validateOnlyExcludesStrandedDependents.js +97 -91
- package/dist/esm/validateOverridesCommand.d.ts +2 -2
- package/dist/esm/validateOverridesCommand.js +110 -111
- package/dist/esm/workTypesData.js +57 -60
- package/dist/esm/workTypesUtils.js +16 -21
- package/dist/esm/writeReleaseNotesPreviews.js +55 -57
- package/package.json +3 -2
- package/dist/esm/.cache +0 -1
package/dist/esm/createTags.js
CHANGED
|
@@ -1,65 +1,66 @@
|
|
|
1
|
-
import { execFileSync } from
|
|
2
|
-
import { readFileSync } from
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { deleteFileIfExists } from "./deleteFileIfExists.js";
|
|
4
4
|
import { RELEASE_SUMMARY_FILE, RELEASE_TAGS_FILE } from "./prepareCommand.js";
|
|
5
|
-
function createTags(options) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
content = readFileSync(RELEASE_TAGS_FILE, "utf8");
|
|
10
|
-
} catch {
|
|
11
|
-
throw new Error("No tags file found. Run `release-kit prepare` first.");
|
|
12
|
-
}
|
|
13
|
-
const tags = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
14
|
-
if (tags.length === 0) {
|
|
15
|
-
return [];
|
|
16
|
-
}
|
|
17
|
-
if (!dryRun && !noGitChecks) {
|
|
18
|
-
assertCleanWorkingTree();
|
|
19
|
-
}
|
|
20
|
-
if (dryRun) {
|
|
21
|
-
console.info("[dry-run] Would create tags:");
|
|
22
|
-
for (const tag of tags) {
|
|
23
|
-
console.info(`\u{1F3F7}\uFE0F ${tag}`);
|
|
24
|
-
}
|
|
25
|
-
return tags;
|
|
26
|
-
}
|
|
27
|
-
const created = [];
|
|
28
|
-
for (const tag of tags) {
|
|
5
|
+
export function createTags(options) {
|
|
6
|
+
const { dryRun, noGitChecks } = options;
|
|
7
|
+
let content;
|
|
29
8
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
9
|
+
content = readFileSync(RELEASE_TAGS_FILE, 'utf8');
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new Error('No tags file found. Run `release-kit prepare` first.');
|
|
13
|
+
}
|
|
14
|
+
const tags = content
|
|
15
|
+
.split('\n')
|
|
16
|
+
.map((line) => line.trim())
|
|
17
|
+
.filter((line) => line.length > 0);
|
|
18
|
+
if (tags.length === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
if (!dryRun && !noGitChecks) {
|
|
22
|
+
assertCleanWorkingTree();
|
|
23
|
+
}
|
|
24
|
+
if (dryRun) {
|
|
25
|
+
console.info('[dry-run] Would create tags:');
|
|
26
|
+
for (const tag of tags) {
|
|
27
|
+
console.info(`🏷️ ${tag}`);
|
|
37
28
|
}
|
|
38
|
-
|
|
39
|
-
throw error;
|
|
29
|
+
return tags;
|
|
40
30
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
31
|
+
const created = [];
|
|
32
|
+
for (const tag of tags) {
|
|
33
|
+
try {
|
|
34
|
+
execFileSync('git', ['tag', '-a', tag, '-m', tag]);
|
|
35
|
+
created.push(tag);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (created.length > 0) {
|
|
39
|
+
console.warn('Tags created before failure:');
|
|
40
|
+
for (const t of created) {
|
|
41
|
+
console.warn(` ${t}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
console.info('Created tags:');
|
|
48
|
+
for (const tag of tags) {
|
|
49
|
+
console.info(`🏷️ ${tag}`);
|
|
50
|
+
}
|
|
51
|
+
deleteFileIfExists(RELEASE_TAGS_FILE);
|
|
52
|
+
deleteFileIfExists(RELEASE_SUMMARY_FILE);
|
|
53
|
+
return tags;
|
|
49
54
|
}
|
|
50
55
|
function assertCleanWorkingTree() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
try {
|
|
57
|
+
execFileSync('git', ['diff', '--quiet']);
|
|
58
|
+
execFileSync('git', ['diff', '--quiet', '--cached']);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
throw new Error('Working tree is dirty. Commit or stash changes before tagging, or use `--no-git-checks` to skip this check.');
|
|
57
65
|
}
|
|
58
|
-
throw new Error(
|
|
59
|
-
"Working tree is dirty. Commit or stash changes before tagging, or use `--no-git-checks` to skip this check."
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
66
|
}
|
|
63
|
-
export {
|
|
64
|
-
createTags
|
|
65
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type PolicyViolationHandler } from './parseCommitMessage.
|
|
2
|
-
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.
|
|
1
|
+
import { type PolicyViolationHandler } from './parseCommitMessage.js';
|
|
2
|
+
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
3
3
|
export interface DecideReleaseArgs {
|
|
4
4
|
commits: readonly Commit[];
|
|
5
5
|
force?: boolean | undefined;
|
|
@@ -1,44 +1,30 @@
|
|
|
1
1
|
import { determineBumpType } from "./determineBumpType.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
...onPolicyViolation !== void 0 && { onPolicyViolation }
|
|
20
|
-
};
|
|
21
|
-
const parsedCommits = [];
|
|
22
|
-
const unparseable = [];
|
|
23
|
-
for (const commit of commits) {
|
|
24
|
-
const parsed = parseCommitMessage(commit.message, commit.hash, workTypes, scopeAliases, parseOptions);
|
|
25
|
-
if (parsed === void 0) {
|
|
26
|
-
unparseable.push(commit);
|
|
27
|
-
} else {
|
|
28
|
-
parsedCommits.push(parsed);
|
|
2
|
+
import { parseCommitMessage, } from "./parseCommitMessage.js";
|
|
3
|
+
export function decideRelease(args) {
|
|
4
|
+
const { commits, force = false, bumpOverride, workTypes, versionPatterns, scopeAliases, breakingPolicies, onPolicyViolation, skipReasons, } = args;
|
|
5
|
+
const parseOptions = {
|
|
6
|
+
...(breakingPolicies !== undefined && { breakingPolicies }),
|
|
7
|
+
...(onPolicyViolation !== undefined && { onPolicyViolation }),
|
|
8
|
+
};
|
|
9
|
+
const parsedCommits = [];
|
|
10
|
+
const unparseable = [];
|
|
11
|
+
for (const commit of commits) {
|
|
12
|
+
const parsed = parseCommitMessage(commit.message, commit.hash, workTypes, scopeAliases, parseOptions);
|
|
13
|
+
if (parsed === undefined) {
|
|
14
|
+
unparseable.push(commit);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
parsedCommits.push(parsed);
|
|
18
|
+
}
|
|
29
19
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return { outcome: "release", releaseType, parsedCommitCount, unparseableCommits };
|
|
20
|
+
const parsedCommitCount = parsedCommits.length;
|
|
21
|
+
const unparseableCommits = unparseable.length > 0 ? unparseable : undefined;
|
|
22
|
+
const naturalBump = determineBumpType(parsedCommits, workTypes, versionPatterns);
|
|
23
|
+
const shouldRelease = naturalBump !== undefined || force;
|
|
24
|
+
if (!shouldRelease) {
|
|
25
|
+
const skipReason = commits.length === 0 ? skipReasons.noCommits : skipReasons.noBumpWorthy;
|
|
26
|
+
return { outcome: 'skip', skipReason, parsedCommitCount, unparseableCommits };
|
|
27
|
+
}
|
|
28
|
+
const releaseType = bumpOverride ?? naturalBump ?? 'patch';
|
|
29
|
+
return { outcome: 'release', releaseType, parsedCommitCount, unparseableCommits };
|
|
41
30
|
}
|
|
42
|
-
export {
|
|
43
|
-
decideRelease
|
|
44
|
-
};
|
package/dist/esm/defaults.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ChangelogJsonConfig, ReleaseNotesConfig, VersionPatterns, WorkTypeConfig } from './types.
|
|
2
|
-
export type { WorkTypesData } from './workTypesData.
|
|
3
|
-
export { WORK_TYPES_DATA } from './workTypesData.
|
|
1
|
+
import type { ChangelogJsonConfig, ReleaseNotesConfig, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
2
|
+
export type { WorkTypesData } from './workTypesData.js';
|
|
3
|
+
export { WORK_TYPES_DATA } from './workTypesData.js';
|
|
4
4
|
export declare function composeHeader(entry: {
|
|
5
5
|
emoji: string;
|
|
6
6
|
label: string;
|
package/dist/esm/defaults.js
CHANGED
|
@@ -1,59 +1,47 @@
|
|
|
1
1
|
import { WORK_TYPES_DATA } from "./workTypesData.js";
|
|
2
|
-
|
|
3
|
-
function composeHeader(entry) {
|
|
4
|
-
|
|
2
|
+
export { WORK_TYPES_DATA } from "./workTypesData.js";
|
|
3
|
+
export function composeHeader(entry) {
|
|
4
|
+
return `${entry.emoji} ${entry.label}`;
|
|
5
5
|
}
|
|
6
|
-
const DEV_ONLY_TIERS =
|
|
6
|
+
const DEV_ONLY_TIERS = new Set(['internal', 'process']);
|
|
7
7
|
function deriveDefaultWorkTypes() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const result = {};
|
|
9
|
+
for (const entry of WORK_TYPES_DATA.types) {
|
|
10
|
+
const config = {
|
|
11
|
+
header: composeHeader(entry),
|
|
12
|
+
};
|
|
13
|
+
if (entry.aliases.length > 0) {
|
|
14
|
+
config.aliases = [...entry.aliases];
|
|
15
|
+
}
|
|
16
|
+
result[entry.key] = config;
|
|
15
17
|
}
|
|
16
|
-
result
|
|
17
|
-
}
|
|
18
|
-
return result;
|
|
18
|
+
return result;
|
|
19
19
|
}
|
|
20
20
|
function deriveDevOnlySections() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const sections = [];
|
|
22
|
+
for (const entry of WORK_TYPES_DATA.types) {
|
|
23
|
+
if (!DEV_ONLY_TIERS.has(entry.tier)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (entry.excludedFromChangelog === true) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
sections.push(composeHeader(entry));
|
|
25
30
|
}
|
|
26
|
-
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
sections.push(composeHeader(entry));
|
|
30
|
-
}
|
|
31
|
-
return sections;
|
|
31
|
+
return sections;
|
|
32
32
|
}
|
|
33
|
-
const DEFAULT_WORK_TYPES = deriveDefaultWorkTypes();
|
|
34
|
-
const DEFAULT_BREAKING_POLICIES = Object.fromEntries(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
major: ["!"],
|
|
39
|
-
minor: ["feat"]
|
|
40
|
-
};
|
|
41
|
-
const DEFAULT_CHANGELOG_JSON_CONFIG = {
|
|
42
|
-
enabled: true,
|
|
43
|
-
outputPath: ".meta/changelog.json",
|
|
44
|
-
devOnlySections: deriveDevOnlySections()
|
|
33
|
+
export const DEFAULT_WORK_TYPES = deriveDefaultWorkTypes();
|
|
34
|
+
export const DEFAULT_BREAKING_POLICIES = Object.fromEntries(WORK_TYPES_DATA.types.map((entry) => [entry.key, entry.breakingPolicy]));
|
|
35
|
+
export const DEFAULT_VERSION_PATTERNS = {
|
|
36
|
+
major: ['!'],
|
|
37
|
+
minor: ['feat'],
|
|
45
38
|
};
|
|
46
|
-
const
|
|
47
|
-
|
|
39
|
+
export const DEFAULT_CHANGELOG_JSON_CONFIG = {
|
|
40
|
+
enabled: true,
|
|
41
|
+
outputPath: '.meta/changelog.json',
|
|
42
|
+
devOnlySections: deriveDevOnlySections(),
|
|
48
43
|
};
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
DEFAULT_BREAKING_POLICIES,
|
|
52
|
-
DEFAULT_CHANGELOG_JSON_CONFIG,
|
|
53
|
-
DEFAULT_PROJECT_TAG_PREFIX,
|
|
54
|
-
DEFAULT_RELEASE_NOTES_CONFIG,
|
|
55
|
-
DEFAULT_VERSION_PATTERNS,
|
|
56
|
-
DEFAULT_WORK_TYPES,
|
|
57
|
-
WORK_TYPES_DATA2 as WORK_TYPES_DATA,
|
|
58
|
-
composeHeader
|
|
44
|
+
export const DEFAULT_RELEASE_NOTES_CONFIG = {
|
|
45
|
+
shouldInjectIntoReadme: false,
|
|
59
46
|
};
|
|
47
|
+
export const DEFAULT_PROJECT_TAG_PREFIX = 'v';
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { unlinkSync } from
|
|
2
|
-
function deleteFileIfExists(filePath) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { unlinkSync } from 'node:fs';
|
|
2
|
+
export function deleteFileIfExists(filePath) {
|
|
3
|
+
try {
|
|
4
|
+
unlinkSync(filePath);
|
|
5
|
+
}
|
|
6
|
+
catch (error) {
|
|
7
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
throw error;
|
|
8
11
|
}
|
|
9
|
-
throw error;
|
|
10
|
-
}
|
|
11
12
|
}
|
|
12
|
-
export {
|
|
13
|
-
deleteFileIfExists
|
|
14
|
-
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { WorkspaceConfig } from './types.
|
|
1
|
+
import type { WorkspaceConfig } from './types.js';
|
|
2
2
|
export declare function deriveWorkspaceConfig(workspacePath: string): WorkspaceConfig;
|
|
@@ -1,40 +1,38 @@
|
|
|
1
|
-
import { readFileSync } from
|
|
2
|
-
import { basename } from
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
3
|
import { isRecord } from "./typeGuards.js";
|
|
4
|
-
function deriveWorkspaceConfig(workspacePath) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
4
|
+
export function deriveWorkspaceConfig(workspacePath) {
|
|
5
|
+
const dir = basename(workspacePath);
|
|
6
|
+
const packageJsonPath = `${workspacePath}/package.json`;
|
|
7
|
+
let parsed;
|
|
8
|
+
try {
|
|
9
|
+
parsed = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13
|
+
throw new Error(`Failed to read ${packageJsonPath}: ${message}`);
|
|
14
|
+
}
|
|
15
|
+
const name = isRecord(parsed) ? parsed.name : undefined;
|
|
16
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
17
|
+
throw new Error(`${packageJsonPath} is missing a 'name' field (required for tag derivation).`);
|
|
18
|
+
}
|
|
19
|
+
const unscopedName = stripNpmScope(name);
|
|
20
|
+
const privateField = isRecord(parsed) ? parsed.private : undefined;
|
|
21
|
+
const isPublishable = privateField === undefined || privateField === false;
|
|
22
|
+
return {
|
|
23
|
+
dir,
|
|
24
|
+
name,
|
|
25
|
+
tagPrefix: `${unscopedName}-v`,
|
|
26
|
+
workspacePath,
|
|
27
|
+
isPublishable,
|
|
28
|
+
packageFiles: [packageJsonPath],
|
|
29
|
+
changelogPaths: [workspacePath],
|
|
30
|
+
paths: [`${workspacePath}/**`],
|
|
31
|
+
};
|
|
31
32
|
}
|
|
32
33
|
function stripNpmScope(name) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
if (name.startsWith('@') && name.includes('/')) {
|
|
35
|
+
return name.slice(name.indexOf('/') + 1);
|
|
36
|
+
}
|
|
37
|
+
return name;
|
|
37
38
|
}
|
|
38
|
-
export {
|
|
39
|
-
deriveWorkspaceConfig
|
|
40
|
-
};
|
|
@@ -1,44 +1,42 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from
|
|
2
|
-
import { join } from
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
3
|
import { isRecord } from "./typeGuards.js";
|
|
4
|
-
function detectPackageManager() {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
export function detectPackageManager() {
|
|
5
|
+
const packageJsonPath = join(process.cwd(), 'package.json');
|
|
6
|
+
try {
|
|
7
|
+
const content = readFileSync(packageJsonPath, 'utf8');
|
|
8
|
+
const parsed = JSON.parse(content);
|
|
9
|
+
if (isRecord(parsed) && typeof parsed.packageManager === 'string') {
|
|
10
|
+
const [name, version] = parsed.packageManager.split('@');
|
|
11
|
+
if (name === 'pnpm' || name === 'npm') {
|
|
12
|
+
return name;
|
|
13
|
+
}
|
|
14
|
+
if (name === 'yarn') {
|
|
15
|
+
return isYarnBerry(version) ? 'yarn-berry' : 'yarn';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
catch {
|
|
20
|
+
}
|
|
21
|
+
return detectFromLockfile();
|
|
21
22
|
}
|
|
22
23
|
function isYarnBerry(version) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
if (version === undefined) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const major = Number.parseInt(version, 10);
|
|
28
|
+
return !Number.isNaN(major) && major >= 2;
|
|
28
29
|
}
|
|
29
30
|
function detectFromLockfile() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
const cwd = process.cwd();
|
|
32
|
+
if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {
|
|
33
|
+
return 'pnpm';
|
|
34
|
+
}
|
|
35
|
+
if (existsSync(join(cwd, 'package-lock.json'))) {
|
|
36
|
+
return 'npm';
|
|
37
|
+
}
|
|
38
|
+
if (existsSync(join(cwd, 'yarn.lock'))) {
|
|
39
|
+
return 'yarn';
|
|
40
|
+
}
|
|
41
|
+
return 'npm';
|
|
41
42
|
}
|
|
42
|
-
export {
|
|
43
|
-
detectPackageManager
|
|
44
|
-
};
|
|
@@ -1,46 +1,47 @@
|
|
|
1
|
-
import { execFileSync } from
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
2
|
const EXAMPLE_TAG_LIMIT = 3;
|
|
3
3
|
const CANDIDATE_TAG_PATTERN = /^(?<prefix>[a-z][a-z0-9-]*-v)\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/;
|
|
4
|
-
function detectUndeclaredTagPrefixes(knownPrefixes) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} catch {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
16
|
-
for (const line of rawOutput.split("\n")) {
|
|
17
|
-
const tag = line.trim();
|
|
18
|
-
if (tag === "") continue;
|
|
19
|
-
const match = CANDIDATE_TAG_PATTERN.exec(tag);
|
|
20
|
-
if (match === null) continue;
|
|
21
|
-
const prefix = match.groups?.prefix ?? "";
|
|
22
|
-
if (prefix === "" || known.has(prefix)) continue;
|
|
23
|
-
let tags = grouped.get(prefix);
|
|
24
|
-
if (tags === void 0) {
|
|
25
|
-
tags = [];
|
|
26
|
-
grouped.set(prefix, tags);
|
|
4
|
+
export function detectUndeclaredTagPrefixes(knownPrefixes) {
|
|
5
|
+
const known = new Set(knownPrefixes);
|
|
6
|
+
let rawOutput;
|
|
7
|
+
try {
|
|
8
|
+
rawOutput = execFileSync('git', ['tag', '--list'], {
|
|
9
|
+
encoding: 'utf8',
|
|
10
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
11
|
+
});
|
|
27
12
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const grouped = new Map();
|
|
17
|
+
for (const line of rawOutput.split('\n')) {
|
|
18
|
+
const tag = line.trim();
|
|
19
|
+
if (tag === '')
|
|
20
|
+
continue;
|
|
21
|
+
const match = CANDIDATE_TAG_PATTERN.exec(tag);
|
|
22
|
+
if (match === null)
|
|
23
|
+
continue;
|
|
24
|
+
const prefix = match.groups?.prefix ?? '';
|
|
25
|
+
if (prefix === '' || known.has(prefix))
|
|
26
|
+
continue;
|
|
27
|
+
let tags = grouped.get(prefix);
|
|
28
|
+
if (tags === undefined) {
|
|
29
|
+
tags = [];
|
|
30
|
+
grouped.set(prefix, tags);
|
|
31
|
+
}
|
|
32
|
+
tags.push(tag);
|
|
33
|
+
}
|
|
34
|
+
const results = [];
|
|
35
|
+
for (const [prefix, tags] of grouped) {
|
|
36
|
+
results.push({
|
|
37
|
+
prefix,
|
|
38
|
+
tagCount: tags.length,
|
|
39
|
+
exampleTags: tags.slice(0, EXAMPLE_TAG_LIMIT),
|
|
40
|
+
suggestedDir: stripTrailingTagMarker(prefix),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return results.sort((a, b) => a.prefix.localeCompare(b.prefix));
|
|
40
44
|
}
|
|
41
45
|
function stripTrailingTagMarker(prefix) {
|
|
42
|
-
|
|
46
|
+
return prefix.endsWith('-v') ? prefix.slice(0, -2) : prefix;
|
|
43
47
|
}
|
|
44
|
-
export {
|
|
45
|
-
detectUndeclaredTagPrefixes
|
|
46
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type PolicyViolationHandler } from './parseCommitMessage.
|
|
2
|
-
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.
|
|
1
|
+
import { type PolicyViolationHandler } from './parseCommitMessage.js';
|
|
2
|
+
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
3
3
|
export interface BumpDetermination {
|
|
4
4
|
releaseType: ReleaseType | undefined;
|
|
5
5
|
parsedCommitCount: number;
|