-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathsemver.ts
98 lines (83 loc) · 2.59 KB
/
semver.ts
1
2
3
4
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import semver from "semver";
import consola from "consola";
import type { ChangelogConfig } from "./config";
import type { GitCommit } from "./git";
import { readPackageJSON, writePackageJSON } from "./package";
export type SemverBumpType =
| "major"
| "premajor"
| "minor"
| "preminor"
| "patch"
| "prepatch"
| "prerelease";
export function determineSemverChange(
commits: GitCommit[],
config: ChangelogConfig
): SemverBumpType | null {
let [hasMajor, hasMinor, hasPatch] = [false, false, false];
for (const commit of commits) {
const semverType = config.types[commit.type]?.semver;
if (semverType === "major" || commit.isBreaking) {
hasMajor = true;
} else if (semverType === "minor") {
hasMinor = true;
} else if (semverType === "patch") {
hasPatch = true;
}
}
// eslint-disable-next-line unicorn/no-nested-ternary
return hasMajor ? "major" : hasMinor ? "minor" : hasPatch ? "patch" : null;
}
export type BumpVersionOptions = {
type?: SemverBumpType;
preid?: string;
suffix?: boolean;
};
export async function bumpVersion(
commits: GitCommit[],
config: ChangelogConfig,
opts: BumpVersionOptions = {}
): Promise<string | false> {
let type = opts.type || determineSemverChange(commits, config) || "patch";
const originalType = type;
const pkg = await readPackageJSON(config);
const currentVersion = pkg.version || "0.0.0";
if (currentVersion.startsWith("0.")) {
if (type === "major") {
type = "minor";
} else if (type === "minor") {
type = "patch";
}
}
if (config.newVersion) {
pkg.version = config.newVersion;
} else if (type || opts.preid) {
pkg.version = semver.inc(currentVersion, type, opts.preid);
config.newVersion = pkg.version;
}
if (opts.suffix) {
const suffix =
typeof opts.suffix === "string"
? `-${opts.suffix}`
: `-${fmtDate(new Date())}-${commits[0].shortHash}`;
pkg.version = config.newVersion = config.newVersion.split("-")[0] + suffix;
}
if (pkg.version === currentVersion) {
return false;
}
consola.info(
`Bumping npm package version from \`${currentVersion}\` to \`${pkg.version}\` (${originalType})`
);
await writePackageJSON(config, pkg);
return pkg.version;
}
function fmtDate(d: Date): string {
// YYMMDD-HHMMSS: 20240919-140954
const date = joinNumbers([d.getFullYear(), d.getMonth() + 1, d.getDate()]);
const time = joinNumbers([d.getHours(), d.getMinutes(), d.getSeconds()]);
return `${date}-${time}`;
}
function joinNumbers(items: number[]): string {
return items.map((i) => (i + "").padStart(2, "0")).join("");
}