@wpelevator/wp-release 0.11.0 → 0.13.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/README.md +95 -13
- package/dist/changeset-config.d.ts +86 -2
- package/dist/changeset-config.js +101 -6
- package/dist/changeset-dependents.d.ts +19 -8
- package/dist/changeset-dependents.js +96 -34
- package/dist/changeset-files.d.ts +6 -5
- package/dist/changeset-files.js +7 -5
- package/dist/changeset-packages.d.ts +45 -8
- package/dist/changeset-packages.js +73 -14
- package/dist/changeset-prompt.d.ts +119 -0
- package/dist/changeset-prompt.js +203 -0
- package/dist/changeset-release.d.ts +38 -3
- package/dist/changeset-release.js +88 -11
- package/dist/changesets.d.ts +6 -2
- package/dist/changesets.js +18 -12
- package/dist/cli.d.ts +7 -1
- package/dist/cli.js +18 -5
- package/dist/commands/changeset-add.d.ts +5 -2
- package/dist/commands/changeset-add.js +108 -9
- package/dist/commands/changeset-args.d.ts +24 -5
- package/dist/commands/changeset-args.js +57 -14
- package/dist/commands/changeset-status.d.ts +2 -0
- package/dist/commands/changeset-tag.js +2 -1
- package/dist/commands/changeset-version.d.ts +6 -0
- package/dist/commands/changeset-version.js +15 -3
- package/dist/commands/command.d.ts +3 -0
- package/dist/commands/deploy-git.d.ts +24 -4
- package/dist/commands/deploy-git.js +56 -3
- package/dist/commands/deploy-svn.d.ts +24 -4
- package/dist/commands/deploy-svn.js +56 -2
- package/dist/commands/package-deploys.d.ts +78 -0
- package/dist/commands/package-deploys.js +108 -0
- package/dist/git-deploy.d.ts +32 -0
- package/dist/git-deploy.js +57 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -2
- package/dist/package-deploy.d.ts +105 -0
- package/dist/package-deploy.js +288 -0
- package/dist/release-repository.d.ts +14 -2
- package/dist/release-repository.js +46 -7
- package/dist/release-tags.d.ts +3 -1
- package/dist/release-tags.js +5 -2
- package/dist/tag-format.d.ts +3 -3
- package/dist/tag-format.js +1 -1
- package/dist/version-files.d.ts +2 -1
- package/dist/version-files.js +12 -7
- package/dist/versions.d.ts +28 -3
- package/dist/versions.js +84 -9
- package/package.json +1 -1
- package/dist/github.d.ts +0 -24
- package/dist/github.js +0 -30
|
@@ -11,6 +11,8 @@ export interface ChangedFilesOptions {
|
|
|
11
11
|
directory?: string;
|
|
12
12
|
/** Value of --diff-filter, like ACMR for files that still exist. */
|
|
13
13
|
diffFilter?: string;
|
|
14
|
+
/** Whether to include the uncommitted and untracked files of the working tree. */
|
|
15
|
+
uncommitted?: boolean;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* The git queries and writes of a changeset release: tags, the commits of a
|
|
@@ -85,13 +87,23 @@ export declare class ReleaseRepository {
|
|
|
85
87
|
*/
|
|
86
88
|
getDirectoryCommits(revision: string, directory: string): Promise<ReleaseCommit[]>;
|
|
87
89
|
/**
|
|
88
|
-
* List the files changed between the merge base of a ref and HEAD
|
|
90
|
+
* List the files changed between the merge base of a ref and HEAD, or the
|
|
91
|
+
* working tree with the uncommitted option, which adds untracked files.
|
|
89
92
|
*
|
|
90
93
|
* @param since Base ref, like origin/main.
|
|
91
|
-
* @param options Directory and
|
|
94
|
+
* @param options Directory, diff filter and uncommitted files.
|
|
92
95
|
* @return Changed files relative to the repository root.
|
|
93
96
|
*/
|
|
94
97
|
getChangedFiles(since: string, options?: ChangedFilesOptions): Promise<string[]>;
|
|
98
|
+
/**
|
|
99
|
+
* Read a file as of the merge base of a ref and HEAD, the side that
|
|
100
|
+
* getChangedFiles() diffs against.
|
|
101
|
+
*
|
|
102
|
+
* @param since Base ref, like origin/main.
|
|
103
|
+
* @param file Absolute or relative file path.
|
|
104
|
+
* @return File contents, or undefined when the file doesn't exist there.
|
|
105
|
+
*/
|
|
106
|
+
readFileAtMergeBase(since: string, file: string): Promise<string | undefined>;
|
|
95
107
|
/**
|
|
96
108
|
* Run git log and parse the commits.
|
|
97
109
|
*
|
|
@@ -115,25 +115,64 @@ export class ReleaseRepository {
|
|
|
115
115
|
]);
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
|
-
* List the files changed between the merge base of a ref and HEAD
|
|
118
|
+
* List the files changed between the merge base of a ref and HEAD, or the
|
|
119
|
+
* working tree with the uncommitted option, which adds untracked files.
|
|
119
120
|
*
|
|
120
121
|
* @param since Base ref, like origin/main.
|
|
121
|
-
* @param options Directory and
|
|
122
|
+
* @param options Directory, diff filter and uncommitted files.
|
|
122
123
|
* @return Changed files relative to the repository root.
|
|
123
124
|
*/
|
|
124
125
|
async getChangedFiles(since, options = {}) {
|
|
126
|
+
const pathspec = options.directory
|
|
127
|
+
? ['--', this.relativePath(options.directory)]
|
|
128
|
+
: [];
|
|
129
|
+
const range = options.uncommitted
|
|
130
|
+
? (await this.run(['merge-base', since, 'HEAD'])).trim()
|
|
131
|
+
: `${since}...HEAD`;
|
|
125
132
|
const output = await this.run([
|
|
126
133
|
'diff',
|
|
127
134
|
'--name-only',
|
|
128
135
|
...(options.diffFilter
|
|
129
136
|
? [`--diff-filter=${options.diffFilter}`]
|
|
130
137
|
: []),
|
|
131
|
-
|
|
132
|
-
...
|
|
133
|
-
? ['--', this.relativePath(options.directory)]
|
|
134
|
-
: []),
|
|
138
|
+
range,
|
|
139
|
+
...pathspec,
|
|
135
140
|
]);
|
|
136
|
-
|
|
141
|
+
const untracked = options.uncommitted
|
|
142
|
+
? await this.run([
|
|
143
|
+
'ls-files',
|
|
144
|
+
'--others',
|
|
145
|
+
'--exclude-standard',
|
|
146
|
+
'--full-name',
|
|
147
|
+
...pathspec,
|
|
148
|
+
])
|
|
149
|
+
: '';
|
|
150
|
+
const files = `${output}\n${untracked}`
|
|
151
|
+
.split(/\r?\n/)
|
|
152
|
+
.filter(Boolean);
|
|
153
|
+
return [...new Set(files)];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Read a file as of the merge base of a ref and HEAD, the side that
|
|
157
|
+
* getChangedFiles() diffs against.
|
|
158
|
+
*
|
|
159
|
+
* @param since Base ref, like origin/main.
|
|
160
|
+
* @param file Absolute or relative file path.
|
|
161
|
+
* @return File contents, or undefined when the file doesn't exist there.
|
|
162
|
+
*/
|
|
163
|
+
async readFileAtMergeBase(since, file) {
|
|
164
|
+
const base = (await this.run(['merge-base', since, 'HEAD'])).trim();
|
|
165
|
+
const relative = this.relativePath(file);
|
|
166
|
+
const listed = await this.run([
|
|
167
|
+
'ls-tree',
|
|
168
|
+
'--name-only',
|
|
169
|
+
base,
|
|
170
|
+
'--',
|
|
171
|
+
relative,
|
|
172
|
+
]);
|
|
173
|
+
return '' === listed.trim()
|
|
174
|
+
? undefined
|
|
175
|
+
: this.run(['show', `${base}:${relative}`]);
|
|
137
176
|
}
|
|
138
177
|
/**
|
|
139
178
|
* Run git log and parse the commits.
|
package/dist/release-tags.d.ts
CHANGED
|
@@ -33,7 +33,9 @@ export declare function selectTagPackages(packages: ConfiguredPackage[], names:
|
|
|
33
33
|
*/
|
|
34
34
|
export declare function getTagVersion(pkg: ConfiguredPackage, expected?: string): Promise<string>;
|
|
35
35
|
/**
|
|
36
|
-
* Find the tag of the newest release before a version.
|
|
36
|
+
* Find the tag of the newest release before a version. A stable release
|
|
37
|
+
* skips the pre-releases before it, so that it compares with the previous
|
|
38
|
+
* stable release.
|
|
37
39
|
*
|
|
38
40
|
* @param repository Repository with the tags.
|
|
39
41
|
* @param prefix Tag prefix of the package, like `plugins/alpha/`.
|
package/dist/release-tags.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readChangelogSection, getLatestChangelogVersion, } from "./changelog.js";
|
|
2
2
|
import { assertKnownPackages, toChangesetPackage, } from "./changeset-packages.js";
|
|
3
3
|
import { ValidationError } from "./errors.js";
|
|
4
|
-
import { compareVersions, isVersion } from "./versions.js";
|
|
4
|
+
import { compareVersions, isPrerelease, isVersion } from "./versions.js";
|
|
5
5
|
/**
|
|
6
6
|
* Pick the packages to tag.
|
|
7
7
|
*
|
|
@@ -37,7 +37,9 @@ export async function getTagVersion(pkg, expected) {
|
|
|
37
37
|
(await getLatestChangelogVersion(pkg.directory, pkg.currentVersion)));
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* Find the tag of the newest release before a version.
|
|
40
|
+
* Find the tag of the newest release before a version. A stable release
|
|
41
|
+
* skips the pre-releases before it, so that it compares with the previous
|
|
42
|
+
* stable release.
|
|
41
43
|
*
|
|
42
44
|
* @param repository Repository with the tags.
|
|
43
45
|
* @param prefix Tag prefix of the package, like `plugins/alpha/`.
|
|
@@ -50,6 +52,7 @@ export async function getPreviousTag(repository, prefix, version) {
|
|
|
50
52
|
.filter((tag) => tag.startsWith(prefix))
|
|
51
53
|
.map((tag) => ({ tag, version: tag.slice(prefix.length) }))
|
|
52
54
|
.filter((item) => isVersion(item.version) &&
|
|
55
|
+
(isPrerelease(version) || !isPrerelease(item.version)) &&
|
|
53
56
|
compareVersions(item.version, version) < 0)
|
|
54
57
|
.sort((a, b) => compareVersions(b.version, a.version))[0]?.tag;
|
|
55
58
|
}
|
package/dist/tag-format.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ConfiguredDeployPackage } from './changeset-packages.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Format the tag of a package release.
|
|
4
4
|
*
|
|
5
5
|
* @param format Tag format with {name}, {slug}, {path}, {type} and {version}.
|
|
6
|
-
* @param pkg Configured package.
|
|
6
|
+
* @param pkg Configured package, with or without a version.
|
|
7
7
|
* @param version Released version, empty for the tag prefix of the package.
|
|
8
8
|
* @return Tag name.
|
|
9
9
|
*/
|
|
10
|
-
export declare function formatTag(format: string, pkg:
|
|
10
|
+
export declare function formatTag(format: string, pkg: ConfiguredDeployPackage, version: string): string;
|
|
11
11
|
/**
|
|
12
12
|
* Format the tag prefix of a package before its name is known, for packages
|
|
13
13
|
* versioned by their git tags.
|
package/dist/tag-format.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
* Format the tag of a package release.
|
|
4
4
|
*
|
|
5
5
|
* @param format Tag format with {name}, {slug}, {path}, {type} and {version}.
|
|
6
|
-
* @param pkg Configured package.
|
|
6
|
+
* @param pkg Configured package, with or without a version.
|
|
7
7
|
* @param version Released version, empty for the tag prefix of the package.
|
|
8
8
|
* @return Tag name.
|
|
9
9
|
*/
|
package/dist/version-files.d.ts
CHANGED
|
@@ -26,7 +26,8 @@ export declare function readVersion(repository: ReleaseRepository, directory: st
|
|
|
26
26
|
export declare function writeVersion(directory: string, descriptor: PackageVersionTarget, version: string, journal: FileJournal): Promise<void>;
|
|
27
27
|
/**
|
|
28
28
|
* Check that every version target of a package has the expected version.
|
|
29
|
-
* Optional targets that are absent are skipped
|
|
29
|
+
* Optional targets that are absent are skipped, and so is the readme Stable
|
|
30
|
+
* tag of a pre-release.
|
|
30
31
|
*
|
|
31
32
|
* @param repository Repository, for versions stored as git tags.
|
|
32
33
|
* @param pkg Configured package.
|
package/dist/version-files.js
CHANGED
|
@@ -6,7 +6,7 @@ import { findMainPluginFile } from "./package-meta.js";
|
|
|
6
6
|
import { escapeRegExp } from "./regexp.js";
|
|
7
7
|
import { formatTemplatePrefix } from "./tag-format.js";
|
|
8
8
|
import { findConstantValues } from "./version-check.js";
|
|
9
|
-
import { compareVersions } from "./versions.js";
|
|
9
|
+
import { compareVersions, isPrerelease } from "./versions.js";
|
|
10
10
|
/**
|
|
11
11
|
* Read the current version of a package from its configured source.
|
|
12
12
|
*
|
|
@@ -32,7 +32,7 @@ export async function readVersion(repository, directory, descriptor, relativePat
|
|
|
32
32
|
const pattern = descriptor.pattern ?? '{path}/{version}';
|
|
33
33
|
const tags = await repository.listTags(formatTemplatePrefix(pattern, relativePath, tagType));
|
|
34
34
|
const versions = tags
|
|
35
|
-
.map((tag) => tag.match(/(?:^|\/|v)(\d
|
|
35
|
+
.map((tag) => tag.match(/(?:^|\/|v)(\d+(?:\.\d+){1,3})$/)?.[1])
|
|
36
36
|
.filter((item) => Boolean(item));
|
|
37
37
|
versions.sort((a, b) => compareVersions(b, a));
|
|
38
38
|
if (versions[0]) {
|
|
@@ -99,9 +99,12 @@ export async function writeVersion(directory, descriptor, version, journal) {
|
|
|
99
99
|
await writeFile(file, updated);
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
+
// The readme Stable tag keeps the last stable version for a pre-release,
|
|
103
|
+
// since WordPress.org offers the stable tag to every site.
|
|
102
104
|
if ('wordpress-stable-tag' === descriptor.kind &&
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
(isPrerelease(version) ||
|
|
106
|
+
(descriptor.ifPresent &&
|
|
107
|
+
!(await versionFileExists(directory, descriptor.kind, descriptor.file))))) {
|
|
105
108
|
return;
|
|
106
109
|
}
|
|
107
110
|
const file = path.join(directory, await getVersionFile(directory, descriptor.kind, descriptor.file));
|
|
@@ -116,7 +119,8 @@ export async function writeVersion(directory, descriptor, version, journal) {
|
|
|
116
119
|
}
|
|
117
120
|
/**
|
|
118
121
|
* Check that every version target of a package has the expected version.
|
|
119
|
-
* Optional targets that are absent are skipped
|
|
122
|
+
* Optional targets that are absent are skipped, and so is the readme Stable
|
|
123
|
+
* tag of a pre-release.
|
|
120
124
|
*
|
|
121
125
|
* @param repository Repository, for versions stored as git tags.
|
|
122
126
|
* @param pkg Configured package.
|
|
@@ -132,8 +136,9 @@ export async function verifyVersionTargets(repository, pkg, expected) {
|
|
|
132
136
|
actual = undefined;
|
|
133
137
|
}
|
|
134
138
|
else if ('wordpress-stable-tag' === target.kind &&
|
|
135
|
-
|
|
136
|
-
|
|
139
|
+
(isPrerelease(expected) ||
|
|
140
|
+
(target.ifPresent &&
|
|
141
|
+
!(await versionFileExists(pkg.directory, target.kind, target.file))))) {
|
|
137
142
|
actual = undefined;
|
|
138
143
|
}
|
|
139
144
|
else {
|
package/dist/versions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Check whether a string is a
|
|
2
|
+
* Check whether a string is a version, like 1.2.0, 1.2.0-rc.1, 2.1 or 1.2.3.4.
|
|
3
3
|
*
|
|
4
4
|
* @param version Version.
|
|
5
5
|
* @return Whether the version is valid.
|
|
@@ -15,11 +15,36 @@ export declare function isPrerelease(version: string): boolean;
|
|
|
15
15
|
/**
|
|
16
16
|
* Compare two versions with SemVer precedence, where a pre-release like
|
|
17
17
|
* 1.0.0-rc.1 comes before 1.0.0. Unlike the semver package, it doesn't throw
|
|
18
|
-
* for versions outside SemVer, like
|
|
19
|
-
*
|
|
18
|
+
* for versions outside SemVer, like 1.2 or 1.2.3.4: every part is compared,
|
|
19
|
+
* and missing parts count as 0.
|
|
20
20
|
*
|
|
21
21
|
* @param left Version.
|
|
22
22
|
* @param right Version to compare with.
|
|
23
23
|
* @return Negative when left is lower, positive when higher, otherwise 0.
|
|
24
24
|
*/
|
|
25
25
|
export declare function compareVersions(left: string, right: string): number;
|
|
26
|
+
/**
|
|
27
|
+
* Get the pre-release version of a stable release version, like 1.3.0-rc.1
|
|
28
|
+
* for 1.3.0. A pre-release with a number, like rc.2, is used as is. Without a
|
|
29
|
+
* number, like rc, the number is one above the highest existing pre-release
|
|
30
|
+
* of that identifier and stable version, so the first one is rc.1.
|
|
31
|
+
*
|
|
32
|
+
* @param stable Stable version of the release, like 1.3.0.
|
|
33
|
+
* @param prerelease Pre-release identifier with an optional number, like rc or rc.2.
|
|
34
|
+
* @param existing Existing versions of the package, like those of its tags.
|
|
35
|
+
* @return Pre-release version.
|
|
36
|
+
* @throws {ValidationError} For an invalid input, or a version that exists.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getPrereleaseVersion(stable: string, prerelease: string, existing: string[]): string;
|
|
39
|
+
/**
|
|
40
|
+
* Get the snapshot version of a stable release version, like
|
|
41
|
+
* 1.3.0-pr-251.20261012183000 for 1.3.0: the identifier and the UTC time,
|
|
42
|
+
* which keeps every snapshot unique and sorts them by time.
|
|
43
|
+
*
|
|
44
|
+
* @param stable Stable version of the release, like 1.3.0.
|
|
45
|
+
* @param id Snapshot identifier, like pr-251.
|
|
46
|
+
* @param time Time of the snapshot.
|
|
47
|
+
* @return Snapshot version.
|
|
48
|
+
* @throws {ValidationError} For an invalid identifier or a version that isn't stable.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getSnapshotVersion(stable: string, id: string, time: Date): string;
|
package/dist/versions.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
import { ValidationError } from "./errors.js";
|
|
1
2
|
/**
|
|
2
|
-
* Stable or pre-release
|
|
3
|
+
* Stable or pre-release version without build metadata: SemVer x.y.z, or the
|
|
4
|
+
* x.y and x.y.z.w versions common in WordPress plugins.
|
|
3
5
|
*/
|
|
4
|
-
const VERSION_PATTERN = /^(0|[1-9]\d*)
|
|
6
|
+
const VERSION_PATTERN = /^(?:0|[1-9]\d*)(?:\.(?:0|[1-9]\d*)){1,3}(?:-([0-9A-Za-z.-]+))?$/;
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
8
|
+
* Pre-release input: an identifier with an optional number, like rc or rc.1.
|
|
9
|
+
*/
|
|
10
|
+
const PRERELEASE_INPUT_PATTERN = /^([A-Za-z][0-9A-Za-z-]*)(?:\.(0|[1-9]\d*))?$/;
|
|
11
|
+
/**
|
|
12
|
+
* Snapshot identifier: dot-separated SemVer pre-release identifiers that start
|
|
13
|
+
* with a letter, like pr-251 or pr-251.g1a2b3c4.
|
|
14
|
+
*/
|
|
15
|
+
const SNAPSHOT_ID_PATTERN = /^[A-Za-z][0-9A-Za-z-]*(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*$/;
|
|
16
|
+
/**
|
|
17
|
+
* Check whether a string is a version, like 1.2.0, 1.2.0-rc.1, 2.1 or 1.2.3.4.
|
|
7
18
|
*
|
|
8
19
|
* @param version Version.
|
|
9
20
|
* @return Whether the version is valid.
|
|
@@ -18,13 +29,13 @@ export function isVersion(version) {
|
|
|
18
29
|
* @return Whether the version is a valid pre-release.
|
|
19
30
|
*/
|
|
20
31
|
export function isPrerelease(version) {
|
|
21
|
-
return Boolean(VERSION_PATTERN.exec(version)?.[
|
|
32
|
+
return Boolean(VERSION_PATTERN.exec(version)?.[1]);
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Compare two versions with SemVer precedence, where a pre-release like
|
|
25
36
|
* 1.0.0-rc.1 comes before 1.0.0. Unlike the semver package, it doesn't throw
|
|
26
|
-
* for versions outside SemVer, like
|
|
27
|
-
*
|
|
37
|
+
* for versions outside SemVer, like 1.2 or 1.2.3.4: every part is compared,
|
|
38
|
+
* and missing parts count as 0.
|
|
28
39
|
*
|
|
29
40
|
* @param left Version.
|
|
30
41
|
* @param right Version to compare with.
|
|
@@ -35,9 +46,7 @@ export function compareVersions(left, right) {
|
|
|
35
46
|
const [rightCore = '', rightPre] = splitPrerelease(right);
|
|
36
47
|
const a = leftCore.split('.').map(Number);
|
|
37
48
|
const b = rightCore.split('.').map(Number);
|
|
38
|
-
const core = (a
|
|
39
|
-
(a[1] ?? 0) - (b[1] ?? 0) ||
|
|
40
|
-
(a[2] ?? 0) - (b[2] ?? 0);
|
|
49
|
+
const core = compareParts(a, b);
|
|
41
50
|
if (core || leftPre === rightPre) {
|
|
42
51
|
return core;
|
|
43
52
|
}
|
|
@@ -46,6 +55,14 @@ export function compareVersions(left, right) {
|
|
|
46
55
|
}
|
|
47
56
|
return comparePrerelease(leftPre.split('.'), rightPre.split('.'));
|
|
48
57
|
}
|
|
58
|
+
function compareParts(left, right) {
|
|
59
|
+
const [a, ...leftRest] = left;
|
|
60
|
+
const [b, ...rightRest] = right;
|
|
61
|
+
if (undefined === a && undefined === b) {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
return (a ?? 0) - (b ?? 0) || compareParts(leftRest, rightRest);
|
|
65
|
+
}
|
|
49
66
|
function splitPrerelease(version) {
|
|
50
67
|
const index = version.indexOf('-');
|
|
51
68
|
return -1 === index
|
|
@@ -72,3 +89,61 @@ function compareIdentifier(a, b) {
|
|
|
72
89
|
}
|
|
73
90
|
return Number(a > b) - Number(a < b);
|
|
74
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the pre-release version of a stable release version, like 1.3.0-rc.1
|
|
94
|
+
* for 1.3.0. A pre-release with a number, like rc.2, is used as is. Without a
|
|
95
|
+
* number, like rc, the number is one above the highest existing pre-release
|
|
96
|
+
* of that identifier and stable version, so the first one is rc.1.
|
|
97
|
+
*
|
|
98
|
+
* @param stable Stable version of the release, like 1.3.0.
|
|
99
|
+
* @param prerelease Pre-release identifier with an optional number, like rc or rc.2.
|
|
100
|
+
* @param existing Existing versions of the package, like those of its tags.
|
|
101
|
+
* @return Pre-release version.
|
|
102
|
+
* @throws {ValidationError} For an invalid input, or a version that exists.
|
|
103
|
+
*/
|
|
104
|
+
export function getPrereleaseVersion(stable, prerelease, existing) {
|
|
105
|
+
const match = PRERELEASE_INPUT_PATTERN.exec(prerelease);
|
|
106
|
+
if (!match) {
|
|
107
|
+
throw new ValidationError(`Invalid pre-release "${prerelease}"; expected an identifier with an optional number, like rc or rc.1.`);
|
|
108
|
+
}
|
|
109
|
+
if (!isVersion(stable) || isPrerelease(stable)) {
|
|
110
|
+
throw new ValidationError(`Cannot release "${stable}" as a pre-release: expected a stable version.`);
|
|
111
|
+
}
|
|
112
|
+
const identifier = match[1] ?? '';
|
|
113
|
+
const version = match[2]
|
|
114
|
+
? `${stable}-${prerelease}`
|
|
115
|
+
: `${stable}-${identifier}.${getNextPrereleaseNumber(`${stable}-${identifier}.`, existing)}`;
|
|
116
|
+
if (existing.includes(version)) {
|
|
117
|
+
throw new ValidationError(`Version ${version} already exists; pass a pre-release without a number to release the next one.`);
|
|
118
|
+
}
|
|
119
|
+
return version;
|
|
120
|
+
}
|
|
121
|
+
function getNextPrereleaseNumber(prefix, existing) {
|
|
122
|
+
const numbers = existing
|
|
123
|
+
.filter((version) => version.startsWith(prefix))
|
|
124
|
+
.map((version) => version.slice(prefix.length))
|
|
125
|
+
.filter((number) => /^\d+$/.test(number))
|
|
126
|
+
.map(Number);
|
|
127
|
+
return Math.max(0, ...numbers) + 1;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the snapshot version of a stable release version, like
|
|
131
|
+
* 1.3.0-pr-251.20261012183000 for 1.3.0: the identifier and the UTC time,
|
|
132
|
+
* which keeps every snapshot unique and sorts them by time.
|
|
133
|
+
*
|
|
134
|
+
* @param stable Stable version of the release, like 1.3.0.
|
|
135
|
+
* @param id Snapshot identifier, like pr-251.
|
|
136
|
+
* @param time Time of the snapshot.
|
|
137
|
+
* @return Snapshot version.
|
|
138
|
+
* @throws {ValidationError} For an invalid identifier or a version that isn't stable.
|
|
139
|
+
*/
|
|
140
|
+
export function getSnapshotVersion(stable, id, time) {
|
|
141
|
+
if (!SNAPSHOT_ID_PATTERN.test(id)) {
|
|
142
|
+
throw new ValidationError(`Invalid snapshot "${id}"; expected SemVer pre-release identifiers that start with a letter, like pr-251.`);
|
|
143
|
+
}
|
|
144
|
+
if (!isVersion(stable) || isPrerelease(stable)) {
|
|
145
|
+
throw new ValidationError(`Cannot release "${stable}" as a snapshot: expected a stable version.`);
|
|
146
|
+
}
|
|
147
|
+
const timestamp = time.toISOString().replace(/\D/g, '').slice(0, 14);
|
|
148
|
+
return `${stable}-${id}.${timestamp}`;
|
|
149
|
+
}
|
package/package.json
CHANGED
package/dist/github.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A GitHub pull request of a commit.
|
|
3
|
-
*/
|
|
4
|
-
export interface GitHubPullRequest {
|
|
5
|
-
number: number;
|
|
6
|
-
url: string;
|
|
7
|
-
/** GitHub handle of the pull request author, without the @. */
|
|
8
|
-
author: string;
|
|
9
|
-
}
|
|
10
|
-
export interface GetGitHubPullRequestInput {
|
|
11
|
-
/** Directory of the repository, whose GitHub remote `gh` uses. */
|
|
12
|
-
cwd: string;
|
|
13
|
-
/** Commit hash. */
|
|
14
|
-
commit: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Find the pull request that merged a commit, with the authenticated `gh`
|
|
18
|
-
* command line client.
|
|
19
|
-
*
|
|
20
|
-
* @param input Repository directory and commit.
|
|
21
|
-
* @return The first pull request of the commit, or undefined without one.
|
|
22
|
-
* @throws {ValidationError} If `gh` fails, like without authentication.
|
|
23
|
-
*/
|
|
24
|
-
export declare function getGitHubPullRequest(input: GetGitHubPullRequestInput): Promise<GitHubPullRequest | undefined>;
|
package/dist/github.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { execFile } from 'node:child_process';
|
|
2
|
-
import { promisify } from 'node:util';
|
|
3
|
-
import { ValidationError } from "./errors.js";
|
|
4
|
-
const execFileAsync = promisify(execFile);
|
|
5
|
-
/**
|
|
6
|
-
* Find the pull request that merged a commit, with the authenticated `gh`
|
|
7
|
-
* command line client.
|
|
8
|
-
*
|
|
9
|
-
* @param input Repository directory and commit.
|
|
10
|
-
* @return The first pull request of the commit, or undefined without one.
|
|
11
|
-
* @throws {ValidationError} If `gh` fails, like without authentication.
|
|
12
|
-
*/
|
|
13
|
-
export async function getGitHubPullRequest(input) {
|
|
14
|
-
let stdout;
|
|
15
|
-
try {
|
|
16
|
-
({ stdout } = await execFileAsync('gh', ['api', `repos/{owner}/{repo}/commits/${input.commit}/pulls`], { cwd: input.cwd }));
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
-
throw new ValidationError(`Could not find the pull request of commit ${input.commit}: ${message}`);
|
|
21
|
-
}
|
|
22
|
-
const [pullRequest] = JSON.parse(stdout);
|
|
23
|
-
return pullRequest
|
|
24
|
-
? {
|
|
25
|
-
number: pullRequest.number,
|
|
26
|
-
url: pullRequest.html_url,
|
|
27
|
-
author: pullRequest.user?.login ?? '',
|
|
28
|
-
}
|
|
29
|
-
: undefined;
|
|
30
|
-
}
|