@vestfoldfylke/vfk-cli 2.0.1
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/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/clickable-link.d.ts +2 -0
- package/dist/lib/clickable-link.d.ts.map +1 -0
- package/dist/lib/clickable-link.js +4 -0
- package/dist/lib/clickable-link.js.map +1 -0
- package/dist/lib/git.d.ts +30 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +178 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.d.ts.map +1 -0
- package/dist/lib/open-url.js +25 -0
- package/dist/lib/open-url.js.map +1 -0
- package/dist/lib/release-notes.d.ts +8 -0
- package/dist/lib/release-notes.d.ts.map +1 -0
- package/dist/lib/release-notes.js +44 -0
- package/dist/lib/release-notes.js.map +1 -0
- package/dist/lib/run-tests.d.ts +3 -0
- package/dist/lib/run-tests.d.ts.map +1 -0
- package/dist/lib/run-tests.js +16 -0
- package/dist/lib/run-tests.js.map +1 -0
- package/dist/lib/semver.d.ts +16 -0
- package/dist/lib/semver.d.ts.map +1 -0
- package/dist/lib/semver.js +163 -0
- package/dist/lib/semver.js.map +1 -0
- package/dist/tests/git.test.d.ts +2 -0
- package/dist/tests/git.test.d.ts.map +1 -0
- package/dist/tests/git.test.js +77 -0
- package/dist/tests/git.test.js.map +1 -0
- package/dist/tests/semver.test.d.ts +2 -0
- package/dist/tests/semver.test.d.ts.map +1 -0
- package/dist/tests/semver.test.js +110 -0
- package/dist/tests/semver.test.js.map +1 -0
- package/dist/tools/pr.d.ts +2 -0
- package/dist/tools/pr.d.ts.map +1 -0
- package/dist/tools/pr.js +194 -0
- package/dist/tools/pr.js.map +1 -0
- package/dist/tools/release.d.ts +2 -0
- package/dist/tools/release.d.ts.map +1 -0
- package/dist/tools/release.js +111 -0
- package/dist/tools/release.js.map +1 -0
- package/dist/types/git.d.ts +25 -0
- package/dist/types/git.d.ts.map +1 -0
- package/dist/types/git.js +2 -0
- package/dist/types/git.js.map +1 -0
- package/dist/types/semver.d.ts +14 -0
- package/dist/types/semver.d.ts.map +1 -0
- package/dist/types/semver.js +2 -0
- package/dist/types/semver.js.map +1 -0
- package/dist/types/tools.d.ts +18 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +2 -0
- package/dist/types/tools.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import semver from "semver";
|
|
4
|
+
export const SUPPORTED_SEMVER_TYPES_BY_PRIORITY = ["major", "minor", "patch"];
|
|
5
|
+
export const getLatestSemverTag = (tags) => {
|
|
6
|
+
const semverTags = tags.filter((tag) => semver.valid(tag));
|
|
7
|
+
return semver.maxSatisfying(semverTags, "*", { includePrerelease: true });
|
|
8
|
+
};
|
|
9
|
+
export const getProjectInfo = () => {
|
|
10
|
+
// Read project version from relevant file based on project type
|
|
11
|
+
// Node.js - package.json
|
|
12
|
+
if (existsSync("./package.json")) {
|
|
13
|
+
const pkg = JSON.parse(readFileSync("./package.json", "utf-8"));
|
|
14
|
+
const paths = ["./package.json"];
|
|
15
|
+
if (existsSync("./package-lock.json")) {
|
|
16
|
+
paths.push("./package-lock.json");
|
|
17
|
+
}
|
|
18
|
+
if (!semver.valid(pkg.version)) {
|
|
19
|
+
throw new Error(`Invalid semver version in package.json: ${pkg.version}, please fix it manually before proceeding...`);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
version: pkg.version,
|
|
23
|
+
type: "node",
|
|
24
|
+
paths,
|
|
25
|
+
name: pkg.name
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// .NET - .csproj
|
|
29
|
+
const csProjFiles = readdirSync("./", { recursive: true }).filter((filename) => typeof filename === "string" && filename.endsWith(".csproj") && !filename.match(/\/bin\/|\/obj\//));
|
|
30
|
+
if (!csProjFiles.every((file) => typeof file === "string")) {
|
|
31
|
+
throw new Error("Error reading .csproj files, not all filenames are strings.");
|
|
32
|
+
}
|
|
33
|
+
if (csProjFiles.length > 0) {
|
|
34
|
+
const versions = csProjFiles
|
|
35
|
+
.map((file) => {
|
|
36
|
+
const content = readFileSync(`./${file}`, "utf-8");
|
|
37
|
+
const match = content.match(/<Version>(.*?)<\/Version>/);
|
|
38
|
+
return match ? { version: match[1], path: file } : null;
|
|
39
|
+
})
|
|
40
|
+
.filter((v) => v !== null);
|
|
41
|
+
if (versions.length > 1) {
|
|
42
|
+
throw new Error("Multiple .csproj files with version tag found in solution.");
|
|
43
|
+
}
|
|
44
|
+
if (versions.length === 0) {
|
|
45
|
+
throw new Error("No <Version> tag found in any .csproj file.");
|
|
46
|
+
}
|
|
47
|
+
if (!semver.valid(versions[0]?.version)) {
|
|
48
|
+
throw new Error(`Invalid semver version in ${versions[0]?.path}: ${versions[0]?.version}, please fix it manually before proceeding...`);
|
|
49
|
+
}
|
|
50
|
+
if (!versions[0]?.path) {
|
|
51
|
+
throw new Error("Error reading .csproj file path.");
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
version: versions[0]?.version, // We know it's defined here, as semver.valid passed
|
|
55
|
+
type: "dotnet",
|
|
56
|
+
paths: [versions[0]?.path]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Add more project types as needed
|
|
60
|
+
throw new Error("Unsupported project type for version retrieval.");
|
|
61
|
+
};
|
|
62
|
+
const hasBeenIncreasedOneTime = (semver1, semver2) => {
|
|
63
|
+
const diffType = semver.diff(semver1, semver2); // 'major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease' or null
|
|
64
|
+
if (!diffType)
|
|
65
|
+
return false;
|
|
66
|
+
const incrementedVersion = semver.inc(semver1, diffType);
|
|
67
|
+
return incrementedVersion === semver2;
|
|
68
|
+
};
|
|
69
|
+
export const useExistingProjectVersion = (latestTag, projectVersion, releaseType) => {
|
|
70
|
+
if (!semver.valid(latestTag) || !semver.valid(projectVersion)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (!hasBeenIncreasedOneTime(latestTag, projectVersion)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return !semver.lt(projectVersion, semver.inc(latestTag, releaseType)); // We already checked that both projectVersion and latestTag are valid above
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
* Finds the next version based on latest tag and project version.
|
|
81
|
+
* If project version is already sufficiently increased from latest tag, it will be used (and not increased again).
|
|
82
|
+
* Favors the latest semver tag, and fallbacks to project version if semver tag is not present.
|
|
83
|
+
*/
|
|
84
|
+
export const getNextVersion = (latestTag, projectInfo, releaseType) => {
|
|
85
|
+
if (!semver.valid(projectInfo.version) && !semver.valid(latestTag)) {
|
|
86
|
+
throw new Error("No valid version found from latest tag or project version.");
|
|
87
|
+
}
|
|
88
|
+
if (latestTag && semver.valid(latestTag)) {
|
|
89
|
+
// Check if project version already has been bumped one time from latest tag - if so, someone else has already merged to main before the release
|
|
90
|
+
if (projectInfo.version && semver.valid(projectInfo.version) && useExistingProjectVersion(latestTag, projectInfo.version, releaseType)) {
|
|
91
|
+
return {
|
|
92
|
+
version: projectInfo.version,
|
|
93
|
+
isInitialRelease: false,
|
|
94
|
+
source: "project-already-bumped",
|
|
95
|
+
description: "Project version has already been bumped sufficiently from latest tag"
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
version: semver.inc(latestTag, releaseType),
|
|
100
|
+
isInitialRelease: false,
|
|
101
|
+
source: "tag",
|
|
102
|
+
description: `Increased ${releaseType} from latest tag ${latestTag}`
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const isInitialRelease = projectInfo.version === "1.0.0";
|
|
106
|
+
return {
|
|
107
|
+
version: isInitialRelease ? "1.0.0" : semver.inc(projectInfo.version, releaseType), // We also know that projectInfo.version is valid here
|
|
108
|
+
isInitialRelease,
|
|
109
|
+
source: "project",
|
|
110
|
+
description: `No valid latest tag found, using project version as base`
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
export const updateProjectVersion = (projectInfo, newVersion) => {
|
|
114
|
+
if (!semver.valid(newVersion)) {
|
|
115
|
+
throw new Error(`Invalid semver version for new version: ${newVersion}`);
|
|
116
|
+
}
|
|
117
|
+
switch (projectInfo.type) {
|
|
118
|
+
case "node": {
|
|
119
|
+
for (const path of projectInfo.paths) {
|
|
120
|
+
// We do not parse JSON to preserve formatting yes
|
|
121
|
+
const content = readFileSync(path, "utf-8");
|
|
122
|
+
if (!projectInfo.name) {
|
|
123
|
+
throw new Error("Project name is required to update version.");
|
|
124
|
+
}
|
|
125
|
+
const newContent = content.replace(new RegExp(`("name": "${projectInfo.name}",\\s+"version": ")[^"]*(")`, "g"), (_, prefix, suffix) => {
|
|
126
|
+
return `${prefix}${newVersion}${suffix}`;
|
|
127
|
+
});
|
|
128
|
+
writeFileSync(path, newContent, "utf-8");
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "dotnet": {
|
|
133
|
+
for (const path of projectInfo.paths) {
|
|
134
|
+
const content = readFileSync(path, "utf-8");
|
|
135
|
+
const newContent = content.replace(/<Version>(.*?)<\/Version>/, `<Version>${newVersion}</Version>`);
|
|
136
|
+
writeFileSync(path, newContent, "utf-8");
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
default:
|
|
141
|
+
throw new Error(`Unsupported project type: ${projectInfo.type}`);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
export const getSemverReleaseType = (latestTag, projectInfo) => {
|
|
145
|
+
if (!projectInfo.version || !semver.valid(projectInfo.version)) {
|
|
146
|
+
throw new Error("Cannot determine semver type without a valid project version. Please fix it manually.");
|
|
147
|
+
}
|
|
148
|
+
if (!latestTag || !semver.valid(latestTag)) {
|
|
149
|
+
return "initial-release";
|
|
150
|
+
}
|
|
151
|
+
if (!hasBeenIncreasedOneTime(latestTag, projectInfo.version)) {
|
|
152
|
+
throw new Error(`Project version ${projectInfo.version} has not been bumped correctly from latest tag ${latestTag}. Please fix it manually.`);
|
|
153
|
+
}
|
|
154
|
+
const semverType = semver.diff(latestTag, projectInfo.version);
|
|
155
|
+
if (!semverType) {
|
|
156
|
+
throw new Error("Cannot determine semver type from latest tag and project version. Please fix it manually.");
|
|
157
|
+
}
|
|
158
|
+
if (!SUPPORTED_SEMVER_TYPES_BY_PRIORITY.includes(semverType)) {
|
|
159
|
+
throw new Error(`Unsupported semver difference type: ${semverType}. Must be one of ${SUPPORTED_SEMVER_TYPES_BY_PRIORITY.join(", ")}. Please fix it manually.`);
|
|
160
|
+
}
|
|
161
|
+
return semverType;
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=semver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.js","sourceRoot":"","sources":["../../src/lib/semver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.test.d.ts","sourceRoot":"","sources":["../../src/tests/git.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { parseGitLogs, sortCommitsByType } from "../lib/git.js";
|
|
4
|
+
const rawLog = `commithash1\x00Franken Stein\x00franken.stein@smyger.no\x00Merge remote-tracking branch 'origin/main' into mordor\x00\x002025-11-03T14:13:00+01:00\x00ENDOFCOMMIT\x00
|
|
5
|
+
commithash2\x00franky\x00franken.stein@smyger.no\x00En commit med body\x00Jeg er Franky!
|
|
6
|
+
|
|
7
|
+
Hvordan går det ❤️\x002025-11-03T14:12:33+01:00\x00ENDOFCOMMIT\x00
|
|
8
|
+
commithash3\x00Franken Stein\x00franken.stein@smyger.no\x00chore: bump version to 3.3.1\x00\x002025-10-29T13:06:56+01:00\x00ENDOFCOMMIT\x00
|
|
9
|
+
`;
|
|
10
|
+
describe("parseGitLogs", () => {
|
|
11
|
+
it("should parse git logs into structured commits", () => {
|
|
12
|
+
const commits = parseGitLogs(rawLog);
|
|
13
|
+
assert.strictEqual(commits.length, 3);
|
|
14
|
+
assert.deepStrictEqual(commits[0], {
|
|
15
|
+
hash: "commithash1",
|
|
16
|
+
authorName: "Franken Stein",
|
|
17
|
+
authorEmail: "franken.stein@smyger.no",
|
|
18
|
+
subject: "Merge remote-tracking branch 'origin/main' into mordor",
|
|
19
|
+
body: "",
|
|
20
|
+
commitDate: "2025-11-03T14:13:00+01:00"
|
|
21
|
+
});
|
|
22
|
+
assert.deepStrictEqual(commits[1], {
|
|
23
|
+
hash: "commithash2",
|
|
24
|
+
authorName: "franky",
|
|
25
|
+
authorEmail: "franken.stein@smyger.no",
|
|
26
|
+
subject: "En commit med body",
|
|
27
|
+
body: "Jeg er Franky!\n\nHvordan går det ❤️",
|
|
28
|
+
commitDate: "2025-11-03T14:12:33+01:00"
|
|
29
|
+
});
|
|
30
|
+
assert.deepStrictEqual(commits[2], {
|
|
31
|
+
hash: "commithash3",
|
|
32
|
+
authorName: "Franken Stein",
|
|
33
|
+
authorEmail: "franken.stein@smyger.no",
|
|
34
|
+
subject: "chore: bump version to 3.3.1",
|
|
35
|
+
body: "",
|
|
36
|
+
commitDate: "2025-10-29T13:06:56+01:00"
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
it("should return empty array for empty log", () => {
|
|
40
|
+
const commits = parseGitLogs("");
|
|
41
|
+
assert.strictEqual(commits.length, 0);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
// Check that sortCommitsByType and getCommitType works as expected
|
|
45
|
+
describe("sortCommitsByType", () => {
|
|
46
|
+
it("should sort commits by type correctly", () => {
|
|
47
|
+
const commits = [
|
|
48
|
+
{ hash: "hash1", authorName: "Author", authorEmail: "author@example.com", subject: "feat: add new feature", body: "", commitDate: "2025-11-11T10:00:00Z" }, // Should be first minor
|
|
49
|
+
{ hash: "hash2", authorName: "Author", authorEmail: "author@example.com", subject: "fix - fix a bug", body: "", commitDate: "2025-11-02T10:00:00Z" }, // Should be first patch
|
|
50
|
+
{ hash: "hash3", authorName: "Author", authorEmail: "author@example.com", subject: "chore: update dependencies", body: "", commitDate: "2025-12-03T10:00:00Z" }, // Should be first maintenance
|
|
51
|
+
{ hash: "hash4", authorName: "Author", authorEmail: "author@example.com", subject: "docs: update README", body: "", commitDate: "2025-11-10T10:00:00Z" }, // Should be second maintenance
|
|
52
|
+
{ hash: "hash5", authorName: "Author", authorEmail: "author@example.com", subject: "refactor - improve code structure", body: "", commitDate: "2025-11-05T10:00:00Z" }, // Should be third maintenance
|
|
53
|
+
{ hash: "hash6", authorName: "Author", authorEmail: "author@example.com", subject: "perf: improve performance", body: "", commitDate: "2025-11-01T10:00:00Z" }, // Should be second patch
|
|
54
|
+
{ hash: "hash7", authorName: "Author", authorEmail: "author@example.com", subject: "breaking change: overhaul API", body: "", commitDate: "2025-11-07T10:00:00Z" }, // Should be only major
|
|
55
|
+
{ hash: "hash8", authorName: "Author", authorEmail: "author@example.com", subject: "minor: add minor improvement", body: "", commitDate: "2025-11-08T08:00:00Z" }, // Should be second minor
|
|
56
|
+
{ hash: "hash9", authorName: "Author", authorEmail: "author@example.com", subject: "unknown type commit", body: "", commitDate: "2025-11-09T10:00:00Z" }, // Should be only other
|
|
57
|
+
{ hash: "hash10", authorName: "Author", authorEmail: "author@example.com", subject: "chore frankestein type commit", body: "", commitDate: "2025-11-08T10:00:00Z" } // Should be the second other
|
|
58
|
+
];
|
|
59
|
+
const sorted = sortCommitsByType(commits);
|
|
60
|
+
assert.strictEqual(sorted.major.length, 1);
|
|
61
|
+
assert.strictEqual(sorted.major[0]?.subject, "breaking change: overhaul API");
|
|
62
|
+
assert.strictEqual(sorted.minor.length, 2);
|
|
63
|
+
assert.strictEqual(sorted.minor[0]?.subject, "feat: add new feature");
|
|
64
|
+
assert.strictEqual(sorted.minor[1]?.subject, "minor: add minor improvement");
|
|
65
|
+
assert.strictEqual(sorted.patch.length, 2);
|
|
66
|
+
assert.strictEqual(sorted.patch[0]?.subject, "fix - fix a bug");
|
|
67
|
+
assert.strictEqual(sorted.patch[1]?.subject, "perf: improve performance");
|
|
68
|
+
assert.strictEqual(sorted.maintenance.length, 3);
|
|
69
|
+
assert.strictEqual(sorted.maintenance[0]?.subject, "chore: update dependencies");
|
|
70
|
+
assert.strictEqual(sorted.maintenance[1]?.subject, "docs: update README");
|
|
71
|
+
assert.strictEqual(sorted.maintenance[2]?.subject, "refactor - improve code structure");
|
|
72
|
+
assert.strictEqual(sorted.other.length, 2);
|
|
73
|
+
assert.strictEqual(sorted.other[0]?.subject, "unknown type commit");
|
|
74
|
+
assert.strictEqual(sorted.other[1]?.subject, "chore frankestein type commit");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=git.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.test.js","sourceRoot":"","sources":["../../src/tests/git.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.test.d.ts","sourceRoot":"","sources":["../../src/tests/semver.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { getLatestSemverTag, getNextVersion, useExistingProjectVersion } from "../lib/semver.js";
|
|
4
|
+
describe("getLatestSemverTag", () => {
|
|
5
|
+
it("should return the latest semver tag", () => {
|
|
6
|
+
// This test assumes that the git repository has at least one semver tag.
|
|
7
|
+
const latestTag = getLatestSemverTag(["v3.0.0", "v1.1.0", "v2.0.0", "v5.0.1-beta", "v6.0.0", "not-a-tag"]);
|
|
8
|
+
assert.strictEqual(latestTag, "v6.0.0");
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
describe("getNextVersion", () => {
|
|
12
|
+
it("should calculate the next version correctly if project is already increased", () => {
|
|
13
|
+
const latestTag = "1.2.3";
|
|
14
|
+
const projectInfo = {
|
|
15
|
+
version: "1.2.4",
|
|
16
|
+
type: "node",
|
|
17
|
+
paths: ["./package.json"]
|
|
18
|
+
};
|
|
19
|
+
const releaseType = "minor";
|
|
20
|
+
const nextVersion = getNextVersion(latestTag, projectInfo, releaseType);
|
|
21
|
+
assert.strictEqual(nextVersion.version, "1.3.0");
|
|
22
|
+
assert.strictEqual(nextVersion.source, "tag");
|
|
23
|
+
assert.strictEqual(nextVersion.isInitialRelease, false);
|
|
24
|
+
});
|
|
25
|
+
it("should calculate the next version correctly if project is behind latest tag", () => {
|
|
26
|
+
const latestTag = "2.0.0";
|
|
27
|
+
const projectInfo = {
|
|
28
|
+
version: "1.5.0",
|
|
29
|
+
type: "node",
|
|
30
|
+
paths: ["./package.json"]
|
|
31
|
+
};
|
|
32
|
+
const releaseType = "patch";
|
|
33
|
+
const nextVersion = getNextVersion(latestTag, projectInfo, releaseType);
|
|
34
|
+
assert.strictEqual(nextVersion.version, "2.0.1");
|
|
35
|
+
assert.strictEqual(nextVersion.source, "tag");
|
|
36
|
+
assert.strictEqual(nextVersion.isInitialRelease, false);
|
|
37
|
+
});
|
|
38
|
+
it("should throw if no valid versions exist", () => {
|
|
39
|
+
const latestTag = null;
|
|
40
|
+
const projectInfo = {
|
|
41
|
+
// @ts-expect-error Testing invalid version
|
|
42
|
+
version: null,
|
|
43
|
+
type: "node",
|
|
44
|
+
paths: ["./package.json"]
|
|
45
|
+
};
|
|
46
|
+
const releaseType = "major";
|
|
47
|
+
assert.throws(() => {
|
|
48
|
+
getNextVersion(latestTag, projectInfo, releaseType);
|
|
49
|
+
}, /No valid version found/);
|
|
50
|
+
});
|
|
51
|
+
it("should use tag if tag and project version are the same", () => {
|
|
52
|
+
const latestTag = "1.0.0";
|
|
53
|
+
const projectInfo = {
|
|
54
|
+
version: "1.0.0",
|
|
55
|
+
type: "node",
|
|
56
|
+
paths: ["./package.json"]
|
|
57
|
+
};
|
|
58
|
+
const releaseType = "minor";
|
|
59
|
+
const nextVersion = getNextVersion(latestTag, projectInfo, releaseType);
|
|
60
|
+
assert.strictEqual(nextVersion.version, "1.1.0");
|
|
61
|
+
assert.strictEqual(nextVersion.source, "tag");
|
|
62
|
+
assert.strictEqual(nextVersion.isInitialRelease, false);
|
|
63
|
+
});
|
|
64
|
+
it("should return 1.0.0 and mark as initial release if project version is 1.0.0 and no tags exist", () => {
|
|
65
|
+
const latestTag = null;
|
|
66
|
+
const projectInfo = {
|
|
67
|
+
version: "1.0.0",
|
|
68
|
+
type: "node",
|
|
69
|
+
paths: ["./package.json"]
|
|
70
|
+
};
|
|
71
|
+
const releaseType = "minor";
|
|
72
|
+
const nextVersion = getNextVersion(latestTag, projectInfo, releaseType);
|
|
73
|
+
assert.strictEqual(nextVersion.version, "1.0.0");
|
|
74
|
+
assert.strictEqual(nextVersion.source, "project");
|
|
75
|
+
assert.strictEqual(nextVersion.isInitialRelease, true);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("useExistingProjectVersion", () => {
|
|
79
|
+
it("should return true if project version has been already been increased one time with semver type from latest tag, and we also want to increase with the same semver type", () => {
|
|
80
|
+
const patch = useExistingProjectVersion("1.2.3", "1.2.4", "patch");
|
|
81
|
+
assert.strictEqual(patch, true);
|
|
82
|
+
const minor = useExistingProjectVersion("1.2.3", "1.3.0", "minor");
|
|
83
|
+
assert.strictEqual(minor, true);
|
|
84
|
+
const major = useExistingProjectVersion("1.2.3", "2.0.0", "major");
|
|
85
|
+
assert.strictEqual(major, true);
|
|
86
|
+
});
|
|
87
|
+
it("should return false if project version has been increased more than one time from latest tag (someone has messed with it)", () => {
|
|
88
|
+
const result = useExistingProjectVersion("1.2.3", "1.4.1", "minor");
|
|
89
|
+
assert.strictEqual(result, false);
|
|
90
|
+
});
|
|
91
|
+
it("should return false if project version has already been increased with patch but we want to increase with minor", () => {
|
|
92
|
+
const result = useExistingProjectVersion("1.2.3", "1.2.4", "minor");
|
|
93
|
+
assert.strictEqual(result, false);
|
|
94
|
+
});
|
|
95
|
+
it("should return false if project version is behind latest tag", () => {
|
|
96
|
+
const result = useExistingProjectVersion("2.0.0", "1.5.0", "major");
|
|
97
|
+
assert.strictEqual(result, false);
|
|
98
|
+
});
|
|
99
|
+
it("should return false if project version is the same as latest tag", () => {
|
|
100
|
+
const result = useExistingProjectVersion("1.2.3", "1.2.3", "minor");
|
|
101
|
+
assert.strictEqual(result, false);
|
|
102
|
+
});
|
|
103
|
+
it("should return false if either version is invalid", () => {
|
|
104
|
+
const result1 = useExistingProjectVersion("not-a-version", "1.2.4", "patch");
|
|
105
|
+
assert.strictEqual(result1, false);
|
|
106
|
+
const result2 = useExistingProjectVersion("1.2.3", "also-not-a-version", "patch");
|
|
107
|
+
assert.strictEqual(result2, false);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=semver.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.test.js","sourceRoot":"","sources":["../../src/tests/semver.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/tools/pr.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,EAAE,GAAI,GAAG,MAAM,MAAM,EAAE,SAyLnC,CAAA"}
|
package/dist/tools/pr.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import yoctoSpinner from "yocto-spinner";
|
|
2
|
+
import { commitAndPush, conventionalCommitTypes, getBranchSpecificCommits, getLatestReleaseTag, getRepoInfo, repoIsReadyForPullRequest, sortCommitsByType } from "../lib/git.js";
|
|
3
|
+
import { openUrl } from "../lib/open-url.js";
|
|
4
|
+
import { runTests } from "../lib/run-tests.js";
|
|
5
|
+
import { getNextVersion, getProjectInfo, SUPPORTED_SEMVER_TYPES_BY_PRIORITY, updateProjectVersion } from "../lib/semver.js";
|
|
6
|
+
const toolHelp = `
|
|
7
|
+
VFK Pull Request Tool
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
vfk pr patch Create a pull request for a patch release (bug fixes)
|
|
11
|
+
vfk pr minor Create a pull request for a minor release (new features)
|
|
12
|
+
vfk pr major Create a pull request for a major release (breaking changes)
|
|
13
|
+
|
|
14
|
+
Description:
|
|
15
|
+
This tool helps you create a pull request for releasing new versions of your project.
|
|
16
|
+
It checks that your repository is clean and up-to-date, determines the next version
|
|
17
|
+
based on semantic versioning, updates the project files, commits the changes, and
|
|
18
|
+
provides a link to create the pull request on GitHub.
|
|
19
|
+
`;
|
|
20
|
+
export const pr = (...args) => {
|
|
21
|
+
if (args.length === 0 || args[0] === "help" || !SUPPORTED_SEMVER_TYPES_BY_PRIORITY.includes(args[0])) {
|
|
22
|
+
console.log(toolHelp);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const repoInfo = getRepoInfo();
|
|
26
|
+
// yocto-spinner og yocto-colors
|
|
27
|
+
let spinner = yoctoSpinner({
|
|
28
|
+
text: "Checking if repo is clean and up-to-date..."
|
|
29
|
+
}).start();
|
|
30
|
+
try {
|
|
31
|
+
repoIsReadyForPullRequest(repoInfo);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
spinner.error(`Repository is not ready for PR: ${error instanceof Error ? error.message : String(error)}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
spinner.success("Repository is clean and up-to-date");
|
|
38
|
+
const pullRequestData = {
|
|
39
|
+
semverType: args[0],
|
|
40
|
+
latestTag: null,
|
|
41
|
+
projectInfo: null,
|
|
42
|
+
nextVersion: null,
|
|
43
|
+
sortedCommits: null
|
|
44
|
+
};
|
|
45
|
+
spinner = yoctoSpinner({ text: "Getting project info..." }).start();
|
|
46
|
+
try {
|
|
47
|
+
pullRequestData.projectInfo = getProjectInfo();
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
51
|
+
spinner.error(`Failed to get project info: ${errorMessage}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
if (!pullRequestData.projectInfo) {
|
|
55
|
+
spinner.error("Project info is null??? Contact idiot-developers.");
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
spinner.success(`Project version is ${pullRequestData.projectInfo.version} (${pullRequestData.projectInfo.type})`);
|
|
59
|
+
// Run tests before proceeding
|
|
60
|
+
spinner = yoctoSpinner({ text: "Running tests..." }).start();
|
|
61
|
+
try {
|
|
62
|
+
runTests(pullRequestData.projectInfo);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
66
|
+
spinner.error(`Tests failed, please fix the errors before you create a PR: ${errorMessage}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
spinner.success("All tests passed");
|
|
70
|
+
// Get commits in current branch not in main/default branch - check that there are commits, and if semverType is present, check that it is not lower than the commit types
|
|
71
|
+
spinner = yoctoSpinner({ text: `Getting commits in branch ${repoInfo.currentBranch} not in ${repoInfo.defaultBranch}...` }).start();
|
|
72
|
+
try {
|
|
73
|
+
const commitsInCurrentBranch = getBranchSpecificCommits(repoInfo.currentBranch);
|
|
74
|
+
if (commitsInCurrentBranch.length === 0) {
|
|
75
|
+
spinner.error(`No commits found in branch ${repoInfo.currentBranch} that are not in ${repoInfo.defaultBranch}. Why do you want to create a PR with no new changes??? 🍕`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
spinner.success(`Found ${commitsInCurrentBranch.length} commits in branch ${repoInfo.currentBranch} not in ${repoInfo.defaultBranch}`);
|
|
79
|
+
spinner = yoctoSpinner({ text: "Analyzing commit types..." }).start();
|
|
80
|
+
pullRequestData.sortedCommits = sortCommitsByType(commitsInCurrentBranch);
|
|
81
|
+
if (!pullRequestData.sortedCommits) {
|
|
82
|
+
spinner.error("Sorted commits is null??? Contact idiot-developers.");
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
// Determine the highest semver type present in the commits
|
|
86
|
+
const commitTypesByPriority = [...SUPPORTED_SEMVER_TYPES_BY_PRIORITY, "maintenance", "other"];
|
|
87
|
+
const highestCommitType = commitTypesByPriority.find((type) => pullRequestData.sortedCommits?.[type] && pullRequestData.sortedCommits[type].length > 0);
|
|
88
|
+
if (!highestCommitType) {
|
|
89
|
+
spinner.error("No commit types found. Probably no commits at all, but we already checked that??? Contact idiot-developers.");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const requestedTypeIndex = commitTypesByPriority.indexOf(pullRequestData.semverType); // Lower index means higher priority
|
|
93
|
+
const highestTypeIndex = commitTypesByPriority.indexOf(highestCommitType);
|
|
94
|
+
if (highestTypeIndex < requestedTypeIndex) {
|
|
95
|
+
spinner.error(`The requested PR type "${pullRequestData.semverType}" is lower than the highest commit type "${highestCommitType}" in the branch. Please review your commits and choose a higher PR type.`);
|
|
96
|
+
// List the commits beautifully-ish in the terminal
|
|
97
|
+
console.log(`Commits by type:`);
|
|
98
|
+
for (const type of commitTypesByPriority) {
|
|
99
|
+
if (pullRequestData.sortedCommits?.[type] && pullRequestData.sortedCommits[type].length > 0) {
|
|
100
|
+
console.log(`\n${type.toUpperCase()} COMMITS:`);
|
|
101
|
+
for (const commit of pullRequestData.sortedCommits[type]) {
|
|
102
|
+
console.log(`- ${commit.subject} (${commit.hash})`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
// Check if there are commits that do not follow conventional commit types
|
|
109
|
+
if (pullRequestData.sortedCommits.other.length > 0) {
|
|
110
|
+
yoctoSpinner().start().warning(`There are ${pullRequestData.sortedCommits.other.length} commit(s) of type "other". Remember to prefix with conventional commit types for proper versioning.`);
|
|
111
|
+
// List out conventional commit types
|
|
112
|
+
console.log(`\t - Conventional commit types (suffix the type with : or - ) are: ${Object.values(conventionalCommitTypes).flat().join(", ")}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
spinner.error(`Failed to get commits: ${error instanceof Error ? error.message : String(error)}`);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
spinner.success(`Commits validated for PR type "${pullRequestData.semverType}"`);
|
|
120
|
+
spinner = yoctoSpinner({ text: "Finding latest release tag..." }).start();
|
|
121
|
+
try {
|
|
122
|
+
pullRequestData.latestTag = getLatestReleaseTag();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
spinner.error(`Failed to get latest release tag: ${error instanceof Error ? error.message : String(error)}`);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
spinner.success(pullRequestData.latestTag ? `Latest release tag is ${pullRequestData.latestTag}` : "No release tags found, will use project version or start from 1.0.0");
|
|
129
|
+
spinner = yoctoSpinner({ text: "Determining next version..." }).start();
|
|
130
|
+
try {
|
|
131
|
+
pullRequestData.nextVersion = getNextVersion(pullRequestData.latestTag, pullRequestData.projectInfo, pullRequestData.semverType);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
spinner.error(`Failed to determine next version: ${error instanceof Error ? error.message : String(error)}`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
spinner.success(`Next version is ${pullRequestData.nextVersion.version} (${pullRequestData.nextVersion.description})${pullRequestData.nextVersion.isInitialRelease ? ", this is the initial release" : ""}`);
|
|
138
|
+
// If project version is different from next version, update project version
|
|
139
|
+
if (pullRequestData.projectInfo.version !== pullRequestData.nextVersion.version) {
|
|
140
|
+
spinner = yoctoSpinner({
|
|
141
|
+
text: `Updating ${pullRequestData.projectInfo.type}-project version in ${pullRequestData.projectInfo.paths.join(" and ")} to ${pullRequestData.nextVersion.version}...`
|
|
142
|
+
}).start();
|
|
143
|
+
try {
|
|
144
|
+
updateProjectVersion(pullRequestData.projectInfo, pullRequestData.nextVersion.version);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
spinner.error(`Failed to update project version: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
spinner.success(`${pullRequestData.projectInfo.type}-project version in ${pullRequestData.projectInfo.paths.join(" and ")} updated to ${pullRequestData.nextVersion.version}`);
|
|
151
|
+
spinner = yoctoSpinner({
|
|
152
|
+
text: "Committing version update and pushing to remote"
|
|
153
|
+
}).start();
|
|
154
|
+
try {
|
|
155
|
+
// Commit and push changes
|
|
156
|
+
commitAndPush(`chore: bump version to ${pullRequestData.nextVersion.version}`);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
spinner.error(`Failed to commit and push changes: ${error instanceof Error ? error.message : String(error)}`);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
spinner.success("Version update committed and pushed to remote");
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
spinner = yoctoSpinner({
|
|
166
|
+
text: `${pullRequestData.projectInfo.type}-project version in ${pullRequestData.projectInfo.paths.join(" and ")} is already up to date.`
|
|
167
|
+
});
|
|
168
|
+
spinner.start();
|
|
169
|
+
spinner.success();
|
|
170
|
+
}
|
|
171
|
+
if (!repoInfo.githubUsername) {
|
|
172
|
+
yoctoSpinner({
|
|
173
|
+
text: "Consider adding 'github.user' to your git config to allow setting your GitHub user as assignee to the PR's you create. Run: 'git config --global github.user %replace-with-your-github-username%'"
|
|
174
|
+
})
|
|
175
|
+
.start()
|
|
176
|
+
.warning();
|
|
177
|
+
}
|
|
178
|
+
// Then we create a PR from a query link to GitHub with the right info filled in
|
|
179
|
+
const prTitle = `${pullRequestData.semverType}: ${pullRequestData.nextVersion.version} - ${repoInfo.currentBranch}`;
|
|
180
|
+
// Create PR body based on all the commits in the branch
|
|
181
|
+
let prBody = "";
|
|
182
|
+
for (const [type, commits] of Object.entries(pullRequestData.sortedCommits)) {
|
|
183
|
+
if (commits && commits.length > 0) {
|
|
184
|
+
prBody += `\n### ${type.charAt(0).toUpperCase() + type.slice(1)} commits:\n`;
|
|
185
|
+
for (const commit of commits) {
|
|
186
|
+
prBody += `- ${commit.subject} (${commit.hash})\n`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const assignee = repoInfo.githubUsername ? `&assignees=${encodeURIComponent(repoInfo.githubUsername)}` : "";
|
|
191
|
+
const prLink = `${repoInfo.githubUrl}/compare/${repoInfo.defaultBranch}...${encodeURIComponent(repoInfo.currentBranch)}?quick_pull=1&title=${encodeURIComponent(prTitle)}&body=${encodeURIComponent(prBody)}${assignee}`;
|
|
192
|
+
openUrl(prLink, " Create your PR here if it did not open automatically");
|
|
193
|
+
};
|
|
194
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/tools/pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../src/tools/release.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,MAAM,EAAE,SA+FxC,CAAA"}
|