@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vestfold fylkeskommune
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# vfk-cli
|
|
2
|
+
A command line interface for our pleasure
|
|
3
|
+
|
|
4
|
+
vfk-cli will help you create a beautiful pull request and release based on conventional commits.<br />
|
|
5
|
+
Conventional commits are commits that follow the [Conventional Commits Specification](https://www.conventionalcommits.org/en/v1.0.0/).
|
|
6
|
+
|
|
7
|
+
Supported conventional commit types:
|
|
8
|
+
- Maintenance (🛠): test, style, docs, chore, refactor
|
|
9
|
+
- Patch (🐛): fix, perf, patch
|
|
10
|
+
- Minor (✨): feat, minor
|
|
11
|
+
- Major (🚨): breaking change, breaking, major, feat!, fix!
|
|
12
|
+
|
|
13
|
+
If a commit does not start with one of the supported conventional commit types, it will be put under `Other commits` section in the changelog.
|
|
14
|
+
|
|
15
|
+
Supported project types:
|
|
16
|
+
- Node.js (package.json, package-lock.json)
|
|
17
|
+
- dotnet (*.csproj first one with <Version> tag)
|
|
18
|
+
|
|
19
|
+
## vfk pr [patch|minor|major]
|
|
20
|
+
|
|
21
|
+
Create a pull request with a version bump and changelog based on conventional commits since last release.<br />
|
|
22
|
+
If no previous release is found, it will create an initial release with version 1.0.0.
|
|
23
|
+
|
|
24
|
+
Steps performed:
|
|
25
|
+
- Check current branch is NOT default branch and that current branch is up-to-date with origin and has no uncommitted changes
|
|
26
|
+
- Determine and get project information (supports Node.js and dotnet projects)
|
|
27
|
+
- Run tests to ensure code is working before creating PR
|
|
28
|
+
- Get and analyze commits since last release tag (if no tag found, will create initial release)
|
|
29
|
+
- If no commits found, will exit with error message
|
|
30
|
+
- If chosen pr type is lower than the highest type found in commits, will exit with error message
|
|
31
|
+
- Find latest version tag
|
|
32
|
+
- Determining new version based on chosen pr type, commits found and latest version tag
|
|
33
|
+
- Bump project version file(s)
|
|
34
|
+
- Node.js: package.json, package-lock.json
|
|
35
|
+
- dotnet: *.csproj (the first one found that contains a <Version> tag)
|
|
36
|
+
- Commit version bump and push to origin
|
|
37
|
+
- Generate changelog based on commits found
|
|
38
|
+
- Create pull request link with title and description (changelog)
|
|
39
|
+
|
|
40
|
+
### Usage
|
|
41
|
+
```bash
|
|
42
|
+
vfk pr patch
|
|
43
|
+
vfk pr minor
|
|
44
|
+
vfk pr major
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## vfk release
|
|
48
|
+
|
|
49
|
+
Create a release with changelog based on conventional commits since last release.<br />
|
|
50
|
+
Will create a release draft on GitHub with changelog and tag the release commit.
|
|
51
|
+
|
|
52
|
+
Steps performed:
|
|
53
|
+
- Check current branch is default branch and that current branch is up-to-date with origin and has no uncommitted changes
|
|
54
|
+
- Run tests to ensure code is working before creating release
|
|
55
|
+
- Find latest version tag
|
|
56
|
+
- Get and analyze commits since last release tag (if no tag found, will create initial release)
|
|
57
|
+
- If no commits found, will exit with error message
|
|
58
|
+
- Determining new version based on latest version tag and project version
|
|
59
|
+
- Generate release notes based on commits found
|
|
60
|
+
- Create release draft link with title, description (release notes) and tag
|
|
61
|
+
|
|
62
|
+
### Usage
|
|
63
|
+
```bash
|
|
64
|
+
vfk release
|
|
65
|
+
vfk rel
|
|
66
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --enable-source-maps
|
|
2
|
+
import { pr } from "./tools/pr.js";
|
|
3
|
+
import { release } from "./tools/release.js";
|
|
4
|
+
const usage = `vfk <command>
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
|
|
8
|
+
vfk pr <type> create a GitHub pull request of the specified type (patch, minor, major)
|
|
9
|
+
vfk release create a GitHub release with auto-release notes and tag from project version
|
|
10
|
+
vfk help display this help message
|
|
11
|
+
`;
|
|
12
|
+
const selectedTool = process.argv[2] || "";
|
|
13
|
+
const args = process.argv.slice(3);
|
|
14
|
+
switch (selectedTool) {
|
|
15
|
+
case "pr":
|
|
16
|
+
pr(...args);
|
|
17
|
+
break;
|
|
18
|
+
case "release":
|
|
19
|
+
release(...args);
|
|
20
|
+
break;
|
|
21
|
+
case "help":
|
|
22
|
+
console.log(usage);
|
|
23
|
+
break;
|
|
24
|
+
case "":
|
|
25
|
+
console.log(usage);
|
|
26
|
+
break;
|
|
27
|
+
default:
|
|
28
|
+
throw new Error("SPECIFIED TOOL NOT FOUND");
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAE5C,MAAM,KAAK,GAAG;;;;;;;CAOb,CAAA;AAID,MAAM,YAAY,GAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAU,IAAI,EAAE,CAAA;AAE1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAElC,QAAQ,YAAY,EAAE,CAAC;IACtB,KAAK,IAAI;QACR,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QACX,MAAK;IACN,KAAK,SAAS;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;QAChB,MAAK;IACN,KAAK,MAAM;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,MAAK;IACN,KAAK,EAAE;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,MAAK;IACN;QACC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;AAC7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickable-link.d.ts","sourceRoot":"","sources":["../../src/lib/clickable-link.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,WAE5D,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickable-link.js","sourceRoot":"","sources":["../../src/lib/clickable-link.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,QAAiB,EAAE,EAAE;IAChE,OAAO,aAAa,IAAI,WAAW,QAAQ,IAAI,IAAI,oBAAoB,CAAA;AACxE,CAAC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { GitLogCommit, RepoInfo, SortedCommits } from "../types/git.js";
|
|
2
|
+
export declare const getDefaultBranch: () => string;
|
|
3
|
+
export declare const getCurrentBranch: () => string;
|
|
4
|
+
export declare const fetchChangesAndTags: () => string;
|
|
5
|
+
export declare const isRepoClean: () => boolean;
|
|
6
|
+
export declare const getCommitsBehindAndAheadDefaultBranch: () => {
|
|
7
|
+
behind: number;
|
|
8
|
+
ahead: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const getLatestReleaseTag: () => string | null;
|
|
11
|
+
export declare const repoIsReadyForPullRequest: (repoInfo: RepoInfo) => void;
|
|
12
|
+
export declare const repoIsReadyForRelease: (repoInfo: RepoInfo) => void;
|
|
13
|
+
export declare const getRepoInfo: () => RepoInfo;
|
|
14
|
+
export declare const commitAndPush: (message: string) => void;
|
|
15
|
+
export declare const parseGitLogs: (rawLog: string) => GitLogCommit[];
|
|
16
|
+
export declare const getCommitsSinceTag: (tagOrCommitHash: string | null | undefined) => GitLogCommit[];
|
|
17
|
+
export declare const getBranchSpecificCommits: (branchName: string) => GitLogCommit[];
|
|
18
|
+
/**
|
|
19
|
+
* Maps semantic versioning release types to arrays of conventional commit keywords.
|
|
20
|
+
*/
|
|
21
|
+
type ConventionalCommitTypes = {
|
|
22
|
+
major: string[];
|
|
23
|
+
minor: string[];
|
|
24
|
+
patch: string[];
|
|
25
|
+
maintenance: string[];
|
|
26
|
+
};
|
|
27
|
+
export declare const conventionalCommitTypes: ConventionalCommitTypes;
|
|
28
|
+
export declare const sortCommitsByType: (commits: GitLogCommit[]) => SortedCommits;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AA2B5E,eAAO,MAAM,gBAAgB,cAE5B,CAAA;AAED,eAAO,MAAM,gBAAgB,cAE5B,CAAA;AAED,eAAO,MAAM,mBAAmB,cAE/B,CAAA;AAED,eAAO,MAAM,WAAW,eAGvB,CAAA;AAED,eAAO,MAAM,qCAAqC;;;CAQjD,CAAA;AAED,eAAO,MAAM,mBAAmB,qBAG/B,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,UAAU,QAAQ,SAY3D,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,SAOvD,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,QAwB9B,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,SAK5C,CAAA;AASD,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,YAAY,EAkBzD,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,iBAAiB,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,YAAY,EAQ3F,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,YAAY,MAAM,KAAG,YAAY,EAOzE,CAAA;AAED;;GAEG;AACH,KAAK,uBAAuB,GAAG;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,MAAM,EAAE,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,uBAKrC,CAAA;AAiBD,eAAO,MAAM,iBAAiB,GAAI,SAAS,YAAY,EAAE,KAAG,aAiB3D,CAAA"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { getLatestSemverTag } from "./semver.js";
|
|
3
|
+
const runGitCommand = (command) => {
|
|
4
|
+
if (!command.startsWith("git ")) {
|
|
5
|
+
throw new Error("Command must be string and only git commands are allowed");
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
const res = execSync(command);
|
|
9
|
+
return res.toString().trim();
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
if (err instanceof Error && err.message.includes("Not a git repository")) {
|
|
13
|
+
throw new Error("Directory is not a Git repository");
|
|
14
|
+
}
|
|
15
|
+
throw err;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const getGithubUsername = () => {
|
|
19
|
+
try {
|
|
20
|
+
return runGitCommand("git config --get github.user") ?? runGitCommand("git config --global --get github.user") ?? undefined;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export const getDefaultBranch = () => {
|
|
27
|
+
return runGitCommand("git rev-parse --abbrev-ref origin/HEAD").replace("origin/", "");
|
|
28
|
+
};
|
|
29
|
+
export const getCurrentBranch = () => {
|
|
30
|
+
return runGitCommand("git rev-parse --abbrev-ref HEAD");
|
|
31
|
+
};
|
|
32
|
+
export const fetchChangesAndTags = () => {
|
|
33
|
+
return runGitCommand("git fetch --all --tags --quiet");
|
|
34
|
+
};
|
|
35
|
+
export const isRepoClean = () => {
|
|
36
|
+
const status = runGitCommand("git status");
|
|
37
|
+
return status.includes("Your branch is up to date with ") && status.includes("nothing to commit, working tree clean");
|
|
38
|
+
};
|
|
39
|
+
export const getCommitsBehindAndAheadDefaultBranch = () => {
|
|
40
|
+
const defaultBranch = getDefaultBranch();
|
|
41
|
+
const diff = runGitCommand(`git rev-list --left-right --count origin/${defaultBranch}...HEAD`);
|
|
42
|
+
const [behind, ahead] = diff.split("\t");
|
|
43
|
+
if (!behind || !ahead) {
|
|
44
|
+
throw new Error("Could not determine commit difference between current branch and default branch");
|
|
45
|
+
}
|
|
46
|
+
return { behind: parseInt(behind, 10), ahead: parseInt(ahead, 10) };
|
|
47
|
+
};
|
|
48
|
+
export const getLatestReleaseTag = () => {
|
|
49
|
+
const tags = runGitCommand("git tag").split("\n");
|
|
50
|
+
return getLatestSemverTag(tags);
|
|
51
|
+
};
|
|
52
|
+
export const repoIsReadyForPullRequest = (repoInfo) => {
|
|
53
|
+
if (repoInfo.currentBranch === repoInfo.defaultBranch) {
|
|
54
|
+
throw new Error("You are currently on the default branch. Please switch to a feature branch to create a PR.");
|
|
55
|
+
}
|
|
56
|
+
if (repoInfo.commitDiff.behind > 0) {
|
|
57
|
+
throw new Error(`Your branch is behind the default branch by ${repoInfo.commitDiff.behind} commit(s). Please merge the default branch (git merge origin/${repoInfo.defaultBranch}) into your branch before creating a PR.`);
|
|
58
|
+
}
|
|
59
|
+
if (!repoInfo.repoIsClean) {
|
|
60
|
+
throw new Error("Please pull, commit and push, or stash your changes before creating a PR.");
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export const repoIsReadyForRelease = (repoInfo) => {
|
|
64
|
+
if (repoInfo.currentBranch !== repoInfo.defaultBranch) {
|
|
65
|
+
throw new Error(`You are currently on branch ${repoInfo.currentBranch}. Please switch to the default branch (${repoInfo.defaultBranch}) to create a release.`);
|
|
66
|
+
}
|
|
67
|
+
if (!repoInfo.repoIsClean) {
|
|
68
|
+
throw new Error("Please pull, commit and push, stash, or branch out your changes before creating a release.");
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
export const getRepoInfo = () => {
|
|
72
|
+
const remoteUrl = runGitCommand("git config --get remote.origin.url");
|
|
73
|
+
if (!(remoteUrl.startsWith("git@github.com:") || remoteUrl.startsWith("https://github.com/"))) {
|
|
74
|
+
throw new Error("Repository is not a GitHub repository. VFK CLI only supports GitHub for PR creation.");
|
|
75
|
+
}
|
|
76
|
+
fetchChangesAndTags();
|
|
77
|
+
const githubUrl = (remoteUrl.startsWith("git@") ? remoteUrl.replace("git@github.com:", "https://github.com/") : remoteUrl).replace(/\.git$/, "");
|
|
78
|
+
// git@github.com:<owner>/<repo>.git - SSH version
|
|
79
|
+
// https://github.com/<owner>/<repo>.git - HTTPS version
|
|
80
|
+
const githubUsername = getGithubUsername();
|
|
81
|
+
const currentBranch = getCurrentBranch();
|
|
82
|
+
const defaultBranch = getDefaultBranch();
|
|
83
|
+
const repoIsClean = isRepoClean();
|
|
84
|
+
const commitDiff = getCommitsBehindAndAheadDefaultBranch();
|
|
85
|
+
return {
|
|
86
|
+
remoteUrl,
|
|
87
|
+
githubUrl,
|
|
88
|
+
githubUsername,
|
|
89
|
+
currentBranch,
|
|
90
|
+
defaultBranch,
|
|
91
|
+
repoIsClean,
|
|
92
|
+
commitDiff
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
export const commitAndPush = (message) => {
|
|
96
|
+
runGitCommand("git add .");
|
|
97
|
+
runGitCommand(`git commit -m "${message}"`);
|
|
98
|
+
const currentBranch = getCurrentBranch();
|
|
99
|
+
runGitCommand(`git push origin ${currentBranch} --quiet`);
|
|
100
|
+
};
|
|
101
|
+
const commitSeparator = "%x00ENDOFCOMMIT%x00"; // Nul-character as separator, as it is not allowed in commit messages
|
|
102
|
+
const prettyFormat = `%h%x00%an%x00%ae%x00%s%x00%b%x00%ad${commitSeparator}`;
|
|
103
|
+
const prettyPropertyNamesInOrder = ["hash", "authorName", "authorEmail", "subject", "body", "commitDate"];
|
|
104
|
+
const commitOutputSeparator = "\x00ENDOFCOMMIT\x00\n"; // add newline after commit separator to also remove the newlines after each new commit line from git log
|
|
105
|
+
const commitPropertySeparator = "\x00";
|
|
106
|
+
export const parseGitLogs = (rawLog) => {
|
|
107
|
+
const commitEntries = rawLog.split(commitOutputSeparator).filter((entry) => entry.trim() !== "");
|
|
108
|
+
return commitEntries.map((entry) => {
|
|
109
|
+
const properties = entry.split(commitPropertySeparator);
|
|
110
|
+
if (properties.length < prettyPropertyNamesInOrder.length) {
|
|
111
|
+
throw new Error("Pretty format and property names length mismatch, check prettyFormat and property names array (that they have same number of properties, and in same order)");
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
hash: properties[0],
|
|
115
|
+
authorName: properties[1],
|
|
116
|
+
authorEmail: properties[2],
|
|
117
|
+
subject: properties[3],
|
|
118
|
+
body: properties[4],
|
|
119
|
+
commitDate: properties[5]
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
export const getCommitsSinceTag = (tagOrCommitHash) => {
|
|
124
|
+
const log = tagOrCommitHash
|
|
125
|
+
? runGitCommand(`git log --pretty=format:'${prettyFormat}' ${tagOrCommitHash}..HEAD --date=iso-strict`)
|
|
126
|
+
: runGitCommand(`git log --pretty=format:'${prettyFormat}' --date=iso-strict`);
|
|
127
|
+
if (!log) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
return parseGitLogs(log);
|
|
131
|
+
};
|
|
132
|
+
export const getBranchSpecificCommits = (branchName) => {
|
|
133
|
+
const defaultBranch = getDefaultBranch();
|
|
134
|
+
const log = runGitCommand(`git log --pretty=format:'${prettyFormat}' origin/${defaultBranch}..${branchName} --date=iso-strict`);
|
|
135
|
+
if (!log) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
return parseGitLogs(log);
|
|
139
|
+
};
|
|
140
|
+
export const conventionalCommitTypes = {
|
|
141
|
+
major: ["breaking change", "breaking", "major", "feat!", "fix!"],
|
|
142
|
+
minor: ["feat", "minor"],
|
|
143
|
+
patch: ["fix", "perf", "patch"],
|
|
144
|
+
maintenance: ["test", "style", "docs", "chore", "refactor"]
|
|
145
|
+
};
|
|
146
|
+
const getCommitType = (message) => {
|
|
147
|
+
message = message.trim().toLowerCase();
|
|
148
|
+
for (const [type, keywords] of Object.entries(conventionalCommitTypes)) {
|
|
149
|
+
for (const keyword of keywords) {
|
|
150
|
+
// Check for keyword at the start or after type(scope)
|
|
151
|
+
const regex = new RegExp(`^${keyword}(\\(.+\\))?(!)?(:| -|$)`, "i");
|
|
152
|
+
if (regex.test(message)) {
|
|
153
|
+
// @ts-expect-error DET ER OK
|
|
154
|
+
return type;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return "other";
|
|
159
|
+
};
|
|
160
|
+
export const sortCommitsByType = (commits) => {
|
|
161
|
+
const sorted = {
|
|
162
|
+
major: [],
|
|
163
|
+
minor: [],
|
|
164
|
+
patch: [],
|
|
165
|
+
maintenance: [],
|
|
166
|
+
other: []
|
|
167
|
+
};
|
|
168
|
+
for (const commit of commits) {
|
|
169
|
+
const type = getCommitType(commit.subject);
|
|
170
|
+
sorted[type].push(commit);
|
|
171
|
+
}
|
|
172
|
+
// Sort all arrays by commit date descending
|
|
173
|
+
for (const key of Object.keys(sorted)) {
|
|
174
|
+
sorted[key] = sorted[key].sort((a, b) => b.commitDate.localeCompare(a.commitDate));
|
|
175
|
+
}
|
|
176
|
+
return sorted;
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-url.d.ts","sourceRoot":"","sources":["../../src/lib/open-url.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,EAAE,UAAS,MAAW,KAAG,IA0B3D,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
export const openUrl = (url, message = "") => {
|
|
3
|
+
let command;
|
|
4
|
+
url = url.replaceAll("(", "%28").replaceAll(")", "%29");
|
|
5
|
+
switch (process.platform) {
|
|
6
|
+
case "darwin": // macOS
|
|
7
|
+
command = `open "${url}"`;
|
|
8
|
+
break;
|
|
9
|
+
case "win32": // Windows
|
|
10
|
+
command = `start "${url.replaceAll("&", "^&")}"`;
|
|
11
|
+
break;
|
|
12
|
+
default: // Linux and other POSIX-like systems
|
|
13
|
+
command = `xdg-open "${url}"`;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
exec(command, (error) => {
|
|
17
|
+
if (error) {
|
|
18
|
+
console.error(`Error opening URL: ${error.message}`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const messageStr = message.length > 0 ? `${message}: ` : "";
|
|
22
|
+
console.log(`${messageStr}${url}`);
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=open-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-url.js","sourceRoot":"","sources":["../../src/lib/open-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,UAAkB,EAAE,EAAQ,EAAE;IAClE,IAAI,OAAe,CAAA;IAEnB,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAEvD,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1B,KAAK,QAAQ,EAAE,QAAQ;YACtB,OAAO,GAAG,SAAS,GAAG,GAAG,CAAA;YACzB,MAAK;QACN,KAAK,OAAO,EAAE,UAAU;YACvB,OAAO,GAAG,UAAU,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAA;YAChD,MAAK;QACN,SAAS,qCAAqC;YAC7C,OAAO,GAAG,aAAa,GAAG,GAAG,CAAA;YAC7B,MAAK;IACP,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACvB,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACpD,OAAM;QACP,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,GAAG,GAAG,EAAE,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SortedCommits } from "../types/git.js";
|
|
2
|
+
import type { ReleaseData } from "../types/tools.js";
|
|
3
|
+
export declare const generateCommitNotes: (sortedCommits: SortedCommits) => string;
|
|
4
|
+
/**
|
|
5
|
+
* Generates release notes based on the provided release data.
|
|
6
|
+
*/
|
|
7
|
+
export declare const generateReleaseNotes: (releaseData: ReleaseData) => string;
|
|
8
|
+
//# sourceMappingURL=release-notes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-notes.d.ts","sourceRoot":"","sources":["../../src/lib/release-notes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AASpD,eAAO,MAAM,mBAAmB,GAAI,eAAe,aAAa,KAAG,MAoBlE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,aAAa,WAAW,WAiB5D,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { sortCommitsByType } from "./git.js";
|
|
2
|
+
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
3
|
+
export const generateCommitNotes = (sortedCommits) => {
|
|
4
|
+
const emojisByType = {
|
|
5
|
+
major: "🚨",
|
|
6
|
+
minor: "✨",
|
|
7
|
+
patch: "🐛",
|
|
8
|
+
maintenance: "🛠️",
|
|
9
|
+
other: "🤦♂️"
|
|
10
|
+
};
|
|
11
|
+
let notes = "";
|
|
12
|
+
// Loop through each commit type and add to notes
|
|
13
|
+
for (const [type, commits] of Object.entries(sortedCommits)) {
|
|
14
|
+
if (commits.length > 0) {
|
|
15
|
+
notes += `### ${emojisByType[type]} **${capitalize(type)} Changes:**\n\n`;
|
|
16
|
+
for (const commit of commits) {
|
|
17
|
+
notes += `- ${commit.subject} (${commit.hash})\n`;
|
|
18
|
+
}
|
|
19
|
+
notes += "\n";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return notes.trim();
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Generates release notes based on the provided release data.
|
|
26
|
+
*/
|
|
27
|
+
export const generateReleaseNotes = (releaseData) => {
|
|
28
|
+
if (!releaseData.releaseType || !releaseData.projectInfo) {
|
|
29
|
+
throw new Error("releaseType and projectInfo are required to generate release notes");
|
|
30
|
+
}
|
|
31
|
+
if (releaseData.releaseType === "initial-release") {
|
|
32
|
+
let notes = "Initial release. 👶\n\n";
|
|
33
|
+
if (releaseData.projectInfo.version !== "1.0.0") {
|
|
34
|
+
notes += `Remark: No previous release was found, but project version is greater than 1.0.0, starting release tag from project version: ${releaseData.projectInfo.version}.\n\n`;
|
|
35
|
+
}
|
|
36
|
+
return notes;
|
|
37
|
+
}
|
|
38
|
+
if (!releaseData.commits || releaseData.commits.length === 0) {
|
|
39
|
+
throw new Error("No commits in releaseData, something is wrong...");
|
|
40
|
+
}
|
|
41
|
+
const sortedCommits = sortCommitsByType(releaseData.commits);
|
|
42
|
+
return generateCommitNotes(sortedCommits);
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=release-notes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-notes.js","sourceRoot":"","sources":["../../src/lib/release-notes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAE5C,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;AAMpG,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAA4B,EAAU,EAAE;IAC3E,MAAM,YAAY,GAAiB;QAClC,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,IAAI;QACX,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,OAAO;KACd,CAAA;IACD,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,iDAAiD;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAgE,EAAE,CAAC;QAC5H,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAA;YACzE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC9B,KAAK,IAAI,KAAK,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,KAAK,CAAA;YAClD,CAAC;YACD,KAAK,IAAI,IAAI,CAAA;QACd,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;AACpB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,WAAwB,EAAE,EAAE;IAChE,IAAI,CAAC,WAAW,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;IACtF,CAAC;IACD,IAAI,WAAW,CAAC,WAAW,KAAK,iBAAiB,EAAE,CAAC;QACnD,IAAI,KAAK,GAAG,yBAAyB,CAAA;QACrC,IAAI,WAAW,CAAC,WAAW,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACjD,KAAK,IAAI,gIAAgI,WAAW,CAAC,WAAW,CAAC,OAAO,OAAO,CAAA;QAChL,CAAC;QACD,OAAO,KAAK,CAAA;IACb,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACpE,CAAC;IACD,MAAM,aAAa,GAAG,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC5D,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAA;AAC1C,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tests.d.ts","sourceRoot":"","sources":["../../src/lib/run-tests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,eAAO,MAAM,QAAQ,GAAI,aAAa,WAAW,KAAG,IAanD,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
export const runTests = (projectInfo) => {
|
|
3
|
+
switch (projectInfo.type) {
|
|
4
|
+
case "node": {
|
|
5
|
+
execSync("npm test");
|
|
6
|
+
break;
|
|
7
|
+
}
|
|
8
|
+
case "dotnet": {
|
|
9
|
+
execSync("dotnet test");
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
default:
|
|
13
|
+
throw new Error(`Unsupported project type for running tests: ${projectInfo.type}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=run-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tests.js","sourceRoot":"","sources":["../../src/lib/run-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,WAAwB,EAAQ,EAAE;IAC1D,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,CAAC,CAAC;YACb,QAAQ,CAAC,UAAU,CAAC,CAAA;YACpB,MAAK;QACN,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,QAAQ,CAAC,aAAa,CAAC,CAAA;YACvB,MAAK;QACN,CAAC;QACD;YACC,MAAM,IAAI,KAAK,CAAC,+CAA+C,WAAW,CAAC,IAAI,EAAE,CAAC,CAAA;IACpF,CAAC;AACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NextVersion, ProjectInfo, ReleaseType } from "../types/semver.js";
|
|
2
|
+
import type { SupportedSemverType } from "../types/tools.js";
|
|
3
|
+
export declare const SUPPORTED_SEMVER_TYPES_BY_PRIORITY: SupportedSemverType[];
|
|
4
|
+
export declare const getLatestSemverTag: (tags: string[]) => string | null;
|
|
5
|
+
export declare const getProjectInfo: () => ProjectInfo;
|
|
6
|
+
export declare const useExistingProjectVersion: (latestTag: string, projectVersion: string, releaseType: SupportedSemverType) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* Finds the next version based on latest tag and project version.
|
|
10
|
+
* If project version is already sufficiently increased from latest tag, it will be used (and not increased again).
|
|
11
|
+
* Favors the latest semver tag, and fallbacks to project version if semver tag is not present.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getNextVersion: (latestTag: string | null, projectInfo: ProjectInfo, releaseType: SupportedSemverType) => NextVersion;
|
|
14
|
+
export declare const updateProjectVersion: (projectInfo: ProjectInfo, newVersion: string) => void;
|
|
15
|
+
export declare const getSemverReleaseType: (latestTag: string | null, projectInfo: ProjectInfo) => ReleaseType;
|
|
16
|
+
//# sourceMappingURL=semver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.d.ts","sourceRoot":"","sources":["../../src/lib/semver.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE5D,eAAO,MAAM,kCAAkC,EAAE,mBAAmB,EAAgC,CAAA;AAEpG,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,KAAG,MAAM,GAAG,IAG5D,CAAA;AAED,eAAO,MAAM,cAAc,QAAO,WA2DjC,CAAA;AASD,eAAO,MAAM,yBAAyB,GAAI,WAAW,MAAM,EAAE,gBAAgB,MAAM,EAAE,aAAa,mBAAmB,KAAG,OASvH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,GAAG,IAAI,EAAE,aAAa,WAAW,EAAE,aAAa,mBAAmB,KAAG,WA4BrH,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,aAAa,WAAW,EAAE,YAAY,MAAM,KAAG,IAgCnF,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,WAAW,MAAM,GAAG,IAAI,EAAE,aAAa,WAAW,KAAG,WAkBzF,CAAA"}
|