@wpelevator/wp-release 0.14.0 → 0.16.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 +256 -36
- package/dist/changeset-config.d.ts +3 -0
- package/dist/changeset-release.d.ts +9 -3
- package/dist/changeset-release.js +23 -14
- package/dist/cli.d.ts +17 -7
- package/dist/cli.js +27 -2
- package/dist/commands/args.d.ts +11 -0
- package/dist/commands/args.js +23 -0
- package/dist/commands/artifact-signing.d.ts +20 -0
- package/dist/commands/artifact-signing.js +42 -0
- package/dist/commands/build.d.ts +32 -0
- package/dist/commands/build.js +91 -0
- package/dist/commands/changeset-add.d.ts +55 -6
- package/dist/commands/changeset-add.js +12 -3
- package/dist/commands/changeset-args.js +2 -2
- package/dist/commands/changeset-project-args.d.ts +63 -0
- package/dist/commands/changeset-project-args.js +114 -0
- package/dist/commands/changeset-status.d.ts +50 -1
- package/dist/commands/changeset-status.js +4 -2
- package/dist/commands/changeset-tag.d.ts +55 -6
- package/dist/commands/changeset-tag.js +7 -4
- package/dist/commands/changeset-version.d.ts +55 -6
- package/dist/commands/changeset-version.js +4 -2
- package/dist/commands/checksums.d.ts +4 -1
- package/dist/commands/checksums.js +27 -6
- package/dist/commands/command.d.ts +3 -0
- package/dist/commands/deploy-svn.d.ts +11 -15
- package/dist/commands/deploy-svn.js +25 -5
- package/dist/commands/package-source.d.ts +43 -0
- package/dist/commands/package-source.js +101 -0
- package/dist/commands/sign.d.ts +0 -9
- package/dist/commands/sign.js +10 -47
- package/dist/commands/verify.d.ts +7 -1
- package/dist/commands/verify.js +53 -17
- package/dist/commands/zip.d.ts +25 -2
- package/dist/commands/zip.js +136 -110
- package/dist/index.d.ts +9 -2
- package/dist/index.js +3 -1
- package/dist/integrity.d.ts +33 -0
- package/dist/integrity.js +115 -0
- package/dist/output-files.d.ts +7 -0
- package/dist/output-files.js +25 -0
- package/dist/package-build.d.ts +33 -0
- package/dist/package-build.js +112 -0
- package/dist/package-files.d.ts +25 -0
- package/dist/package-files.js +24 -0
- package/dist/package-zip.d.ts +14 -2
- package/dist/package-zip.js +129 -38
- package/dist/release-tags.js +6 -0
- package/dist/signing.d.ts +36 -0
- package/dist/signing.js +52 -1
- package/dist/single-project.d.ts +32 -0
- package/dist/single-project.js +144 -0
- package/dist/summary.d.ts +9 -0
- package/dist/summary.js +25 -0
- package/dist/zip.d.ts +3 -0
- package/dist/zip.js +16 -6
- package/package.json +6 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveSingleProjectConfig } from "./single-project.js";
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
import { getVersionedReleases, prependChangelog } from "./changelog.js";
|
|
3
4
|
import { loadChangesetConfig } from "./changeset-config.js";
|
|
@@ -12,7 +13,7 @@ import { ReleaseRepository } from "./release-repository.js";
|
|
|
12
13
|
import { DEFAULT_TAG_FORMAT, formatTag } from "./tag-format.js";
|
|
13
14
|
import { verifyVersionTargets, writeVersion } from "./version-files.js";
|
|
14
15
|
import { getPrereleaseVersion, getSnapshotVersion, isPrerelease, } from "./versions.js";
|
|
15
|
-
const MISSING_CONFIG = 'No wp-release config found.
|
|
16
|
+
const MISSING_CONFIG = 'No wp-release config or root project found. Pass --version-* descriptors, add wp-release.config.js or pass --config <path>.';
|
|
16
17
|
/**
|
|
17
18
|
* Changeset releases of a repository: recording changesets, versioning the
|
|
18
19
|
* packages they name and tagging the releases.
|
|
@@ -24,6 +25,7 @@ const MISSING_CONFIG = 'No wp-release config found. Add wp-release.config.js or
|
|
|
24
25
|
export class ChangesetRelease {
|
|
25
26
|
cwd;
|
|
26
27
|
configFile;
|
|
28
|
+
singleProject;
|
|
27
29
|
tagFormat;
|
|
28
30
|
repository;
|
|
29
31
|
/**
|
|
@@ -32,6 +34,7 @@ export class ChangesetRelease {
|
|
|
32
34
|
constructor(options) {
|
|
33
35
|
this.cwd = options.cwd;
|
|
34
36
|
this.configFile = options.configFile;
|
|
37
|
+
this.singleProject = options.singleProject;
|
|
35
38
|
this.tagFormat = options.tagFormat;
|
|
36
39
|
this.repository = new ReleaseRepository({
|
|
37
40
|
cwd: options.cwd,
|
|
@@ -42,7 +45,7 @@ export class ChangesetRelease {
|
|
|
42
45
|
* Discover configured packages, pending changesets, and their proposed
|
|
43
46
|
* versions.
|
|
44
47
|
*
|
|
45
|
-
* @return A release plan; `undefined`
|
|
48
|
+
* @return A release plan; `undefined` without a config or a recognized root project.
|
|
46
49
|
*/
|
|
47
50
|
async getPlan() {
|
|
48
51
|
const context = await this.loadContext();
|
|
@@ -361,19 +364,14 @@ export class ChangesetRelease {
|
|
|
361
364
|
* Load the configuration, discover the packages and plan the releases of
|
|
362
365
|
* the pending changesets, including the releases of their dependents.
|
|
363
366
|
*
|
|
364
|
-
* @return Release context, undefined without a config.
|
|
367
|
+
* @return Release context, undefined without a config or a recognized root project.
|
|
365
368
|
* @throws {ValidationError} For an invalid config, plan or changeset.
|
|
366
369
|
*/
|
|
367
370
|
async loadContext() {
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
...(this.configFile ? { configFile: this.configFile } : {}),
|
|
371
|
-
...(this.tagFormat ? { tagFormat: this.tagFormat } : {}),
|
|
372
|
-
});
|
|
373
|
-
if (!loaded) {
|
|
371
|
+
const config = await this.loadConfig();
|
|
372
|
+
if (!config) {
|
|
374
373
|
return undefined;
|
|
375
374
|
}
|
|
376
|
-
const config = loaded.config;
|
|
377
375
|
const packages = await discoverPackages(this.repository, config);
|
|
378
376
|
const changesets = await readChangesets(this.getChangesetDirectory(config));
|
|
379
377
|
const releases = [];
|
|
@@ -431,15 +429,26 @@ export class ChangesetRelease {
|
|
|
431
429
|
* @throws {ValidationError} Without a config.
|
|
432
430
|
*/
|
|
433
431
|
async requireConfig() {
|
|
432
|
+
const config = await this.loadConfig();
|
|
433
|
+
if (!config) {
|
|
434
|
+
throw new ValidationError(MISSING_CONFIG);
|
|
435
|
+
}
|
|
436
|
+
return config;
|
|
437
|
+
}
|
|
438
|
+
/** Load an explicit/discovered config, otherwise resolve one root project. */
|
|
439
|
+
async loadConfig() {
|
|
434
440
|
const loaded = await loadChangesetConfig({
|
|
435
441
|
cwd: this.cwd,
|
|
436
442
|
...(this.configFile ? { configFile: this.configFile } : {}),
|
|
437
443
|
...(this.tagFormat ? { tagFormat: this.tagFormat } : {}),
|
|
438
444
|
});
|
|
439
|
-
if (
|
|
440
|
-
|
|
445
|
+
if (loaded) {
|
|
446
|
+
if (this.singleProject) {
|
|
447
|
+
throw new ValidationError('Single-project options cannot be combined with a wp-release config. Set these options in the config instead.');
|
|
448
|
+
}
|
|
449
|
+
return loaded.config;
|
|
441
450
|
}
|
|
442
|
-
return
|
|
451
|
+
return resolveSingleProjectConfig(this.cwd, this.singleProject, this.tagFormat);
|
|
443
452
|
}
|
|
444
453
|
/**
|
|
445
454
|
* Get the directory of the changeset files.
|
|
@@ -455,7 +464,7 @@ export class ChangesetRelease {
|
|
|
455
464
|
* Discover configured packages, pending changesets, and their proposed versions.
|
|
456
465
|
*
|
|
457
466
|
* @param input Repository root and optional explicit config file.
|
|
458
|
-
* @return A release plan; `undefined`
|
|
467
|
+
* @return A release plan; `undefined` without a config or a recognized root project.
|
|
459
468
|
*/
|
|
460
469
|
export async function getChangesetReleasePlan(input) {
|
|
461
470
|
return new ChangesetRelease(input).getPlan();
|
package/dist/cli.d.ts
CHANGED
|
@@ -3,9 +3,8 @@ import type { SignResult } from './commands/sign.ts';
|
|
|
3
3
|
import type { KeygenResult } from './commands/keygen.ts';
|
|
4
4
|
import type { ZipResult } from './commands/zip.ts';
|
|
5
5
|
import type { ChangesetVersionResult } from './commands/changeset-version.ts';
|
|
6
|
-
import { Logger } from './logger.ts';
|
|
7
6
|
import type { OutputStream } from './logger.ts';
|
|
8
|
-
import type { Command, CommandOutcome } from './commands/command.ts';
|
|
7
|
+
import type { CommandContext, Command, CommandOutcome } from './commands/command.ts';
|
|
9
8
|
/** Input stream that interactive prompts read from in a terminal. */
|
|
10
9
|
export type InputStream = NodeJS.ReadableStream & {
|
|
11
10
|
isTTY?: boolean;
|
|
@@ -44,10 +43,24 @@ export declare function getCommandHelp(command: Command): string;
|
|
|
44
43
|
* @return Command definition.
|
|
45
44
|
*/
|
|
46
45
|
export declare function findCommand(args: string[]): Command | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Format the result of a command as GitHub Actions step outputs: the whole
|
|
48
|
+
* result as JSON in "result", and each top-level string, number or boolean
|
|
49
|
+
* as its own output, like "zipPath", so that a workflow reads it without
|
|
50
|
+
* fromJSON(). Lists and objects are only in "result". Every value but the
|
|
51
|
+
* compact JSON, which has no line breaks, uses a random delimiter, so that a
|
|
52
|
+
* value with line breaks can't set other outputs.
|
|
53
|
+
*
|
|
54
|
+
* @param result Command result.
|
|
55
|
+
* @return Lines for the GITHUB_OUTPUT file.
|
|
56
|
+
*/
|
|
57
|
+
export declare function formatGitHubOutputs(result: unknown): string;
|
|
47
58
|
/**
|
|
48
59
|
* Results of the commands that can be run with execute(), by command name.
|
|
49
60
|
*/
|
|
50
61
|
export interface CommandResults {
|
|
62
|
+
build: import('./commands/build.ts').BuildResult;
|
|
63
|
+
'deploy-svn': import('./commands/deploy-svn.ts').DeploySvnResult;
|
|
51
64
|
zip: ZipResult;
|
|
52
65
|
checksums: ChecksumsResult;
|
|
53
66
|
sign: SignResult;
|
|
@@ -68,14 +81,11 @@ export interface CommandResults {
|
|
|
68
81
|
* @param context.cwd Working directory that relative paths resolve against.
|
|
69
82
|
* @param context.configFile Explicit config file path, when supplied by a wrapper.
|
|
70
83
|
* @param context.logger Logger for the command output.
|
|
84
|
+
* @param context.svnRunner Optional SVN command runner supplied by a wrapper.
|
|
71
85
|
* @return Exit code and result of the command.
|
|
72
86
|
* @throws {Error} If the command is unknown, the arguments are invalid or the command fails.
|
|
73
87
|
*/
|
|
74
|
-
export declare function execute<Name extends keyof CommandResults>(name: Name, args: string[], context:
|
|
75
|
-
cwd: string;
|
|
76
|
-
logger: Logger;
|
|
77
|
-
configFile?: string;
|
|
78
|
-
}): Promise<CommandOutcome<CommandResults[Name]>>;
|
|
88
|
+
export declare function execute<Name extends keyof CommandResults>(name: Name, args: string[], context: Pick<CommandContext, 'cwd' | 'logger' | 'configFile' | 'svnRunner'>): Promise<CommandOutcome<CommandResults[Name]>>;
|
|
79
89
|
/**
|
|
80
90
|
* Run the CLI.
|
|
81
91
|
*
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { appendFileSync } from 'node:fs';
|
|
2
3
|
import { parseArgs } from 'node:util';
|
|
3
4
|
import zip from "./commands/zip.js";
|
|
5
|
+
import build from "./commands/build.js";
|
|
4
6
|
import checksums from "./commands/checksums.js";
|
|
5
7
|
import sign from "./commands/sign.js";
|
|
6
8
|
import keygen from "./commands/keygen.js";
|
|
@@ -21,6 +23,7 @@ export const EXIT_SUCCESS = 0;
|
|
|
21
23
|
export const EXIT_FAILURE = 1;
|
|
22
24
|
export const EXIT_INVALID = 2;
|
|
23
25
|
export const commands = [
|
|
26
|
+
build,
|
|
24
27
|
zip,
|
|
25
28
|
checksums,
|
|
26
29
|
sign,
|
|
@@ -177,6 +180,28 @@ function createLogWriter(values, streams) {
|
|
|
177
180
|
}
|
|
178
181
|
return create(streams);
|
|
179
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Format the result of a command as GitHub Actions step outputs: the whole
|
|
185
|
+
* result as JSON in "result", and each top-level string, number or boolean
|
|
186
|
+
* as its own output, like "zipPath", so that a workflow reads it without
|
|
187
|
+
* fromJSON(). Lists and objects are only in "result". Every value but the
|
|
188
|
+
* compact JSON, which has no line breaks, uses a random delimiter, so that a
|
|
189
|
+
* value with line breaks can't set other outputs.
|
|
190
|
+
*
|
|
191
|
+
* @param result Command result.
|
|
192
|
+
* @return Lines for the GITHUB_OUTPUT file.
|
|
193
|
+
*/
|
|
194
|
+
export function formatGitHubOutputs(result) {
|
|
195
|
+
const values = 'object' === typeof result && null !== result
|
|
196
|
+
? Object.entries(result).filter(([name, value]) => 'result' !== name &&
|
|
197
|
+
['string', 'number', 'boolean'].includes(typeof value))
|
|
198
|
+
: [];
|
|
199
|
+
const delimiter = `ghadelimiter_${randomUUID()}`;
|
|
200
|
+
return [
|
|
201
|
+
`result=${JSON.stringify(result)}\n`,
|
|
202
|
+
...values.map(([name, value]) => `${name}<<${delimiter}\n${String(value)}\n${delimiter}\n`),
|
|
203
|
+
].join('');
|
|
204
|
+
}
|
|
180
205
|
/**
|
|
181
206
|
* Get the GitHub Actions step output file for --github-output, checked before
|
|
182
207
|
* the command runs.
|
|
@@ -241,8 +266,7 @@ async function runCommand(command, args, io) {
|
|
|
241
266
|
stdout.write(JSON.stringify(result, null, '\t') + '\n');
|
|
242
267
|
}
|
|
243
268
|
if (githubOutputFile) {
|
|
244
|
-
|
|
245
|
-
appendFileSync(githubOutputFile, `result=${JSON.stringify(result)}\n`);
|
|
269
|
+
appendFileSync(githubOutputFile, formatGitHubOutputs(result));
|
|
246
270
|
}
|
|
247
271
|
return exitCode;
|
|
248
272
|
}
|
|
@@ -262,6 +286,7 @@ async function runCommand(command, args, io) {
|
|
|
262
286
|
* @param context.cwd Working directory that relative paths resolve against.
|
|
263
287
|
* @param context.configFile Explicit config file path, when supplied by a wrapper.
|
|
264
288
|
* @param context.logger Logger for the command output.
|
|
289
|
+
* @param context.svnRunner Optional SVN command runner supplied by a wrapper.
|
|
265
290
|
* @return Exit code and result of the command.
|
|
266
291
|
* @throws {Error} If the command is unknown, the arguments are invalid or the command fails.
|
|
267
292
|
*/
|
package/dist/commands/args.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ParseArgsOptionsConfig } from 'node:util';
|
|
2
|
+
import type { SignatureFormat } from '../signing.ts';
|
|
2
3
|
import type { ParsedValues } from './command.ts';
|
|
3
4
|
/**
|
|
4
5
|
* Options shared by the commands that select files with .distignore and
|
|
@@ -69,3 +70,13 @@ export interface ResolveOutputInput {
|
|
|
69
70
|
* @return Absolute file path.
|
|
70
71
|
*/
|
|
71
72
|
export declare function resolveOutput(input: ResolveOutputInput): string;
|
|
73
|
+
/**
|
|
74
|
+
* Get the signature formats from the --format values of sign or the
|
|
75
|
+
* --sign-format values of zip, which can be repeated
|
|
76
|
+
* or comma-separated.
|
|
77
|
+
*
|
|
78
|
+
* @param values Option values.
|
|
79
|
+
* @return Unique formats, the default when none are given.
|
|
80
|
+
* @throws {ValidationError} If a format is unknown.
|
|
81
|
+
*/
|
|
82
|
+
export declare function parseSignatureFormats(values: string[]): SignatureFormat[];
|
package/dist/commands/args.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { stat } from 'node:fs/promises';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { ValidationError } from "../errors.js";
|
|
4
|
+
import { DEFAULT_SIGNATURE_FORMAT, SIGNATURE_FORMATS, isSignatureFormat, } from "../signing.js";
|
|
4
5
|
import { getBoolean, getString, getStrings } from "./command.js";
|
|
5
6
|
/**
|
|
6
7
|
* Options shared by the commands that select files with .distignore and
|
|
@@ -95,3 +96,25 @@ export function getSourceDirArg(values, positionals) {
|
|
|
95
96
|
export function resolveOutput(input) {
|
|
96
97
|
return resolve(input.cwd, input.output ?? input.filename);
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the signature formats from the --format values of sign or the
|
|
101
|
+
* --sign-format values of zip, which can be repeated
|
|
102
|
+
* or comma-separated.
|
|
103
|
+
*
|
|
104
|
+
* @param values Option values.
|
|
105
|
+
* @return Unique formats, the default when none are given.
|
|
106
|
+
* @throws {ValidationError} If a format is unknown.
|
|
107
|
+
*/
|
|
108
|
+
export function parseSignatureFormats(values) {
|
|
109
|
+
const names = values
|
|
110
|
+
.flatMap((value) => value.split(','))
|
|
111
|
+
.map((name) => name.trim())
|
|
112
|
+
.filter(Boolean);
|
|
113
|
+
const unknown = names.filter((name) => !isSignatureFormat(name));
|
|
114
|
+
if (unknown.length) {
|
|
115
|
+
throw new ValidationError(`Unknown signature format ${unknown.join(', ')}, use ${Object.keys(SIGNATURE_FORMATS).join(', ')}.`);
|
|
116
|
+
}
|
|
117
|
+
return names.length
|
|
118
|
+
? [...new Set(names.filter(isSignatureFormat))]
|
|
119
|
+
: [DEFAULT_SIGNATURE_FORMAT];
|
|
120
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ParseArgsOptionsConfig } from 'node:util';
|
|
2
|
+
import type { SignFilesInput, SignatureFormat } from '../signing.ts';
|
|
3
|
+
import type { ParsedValues } from './command.ts';
|
|
4
|
+
export declare const checksumSigningArgs: ParseArgsOptionsConfig;
|
|
5
|
+
interface SigningPaths {
|
|
6
|
+
artifact?: string;
|
|
7
|
+
checksums: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve explicit signing targets and validate them before creating artifacts.
|
|
11
|
+
*
|
|
12
|
+
* @param values Parsed CLI flags.
|
|
13
|
+
* @param paths Artifact and manifest paths that can be signed.
|
|
14
|
+
* @return Signing input, or undefined when no signing is requested.
|
|
15
|
+
* @throws {ValidationError} For formats without a signing target or invalid signing input.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getArtifactSigning(values: ParsedValues, paths: SigningPaths): (SignFilesInput & {
|
|
18
|
+
formats: SignatureFormat[];
|
|
19
|
+
}) | undefined;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ValidationError } from "../errors.js";
|
|
2
|
+
import { checkSigningInput } from "../signing.js";
|
|
3
|
+
import { parseSignatureFormats } from "./args.js";
|
|
4
|
+
import { getBoolean, getStrings } from "./command.js";
|
|
5
|
+
export const checksumSigningArgs = {
|
|
6
|
+
checksums: { type: 'boolean' },
|
|
7
|
+
'sign-checksums': { type: 'boolean' },
|
|
8
|
+
'sign-format': { type: 'string', multiple: true },
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Resolve explicit signing targets and validate them before creating artifacts.
|
|
12
|
+
*
|
|
13
|
+
* @param values Parsed CLI flags.
|
|
14
|
+
* @param paths Artifact and manifest paths that can be signed.
|
|
15
|
+
* @return Signing input, or undefined when no signing is requested.
|
|
16
|
+
* @throws {ValidationError} For formats without a signing target or invalid signing input.
|
|
17
|
+
*/
|
|
18
|
+
export function getArtifactSigning(values, paths) {
|
|
19
|
+
const names = getStrings(values, 'sign-format');
|
|
20
|
+
const targets = [
|
|
21
|
+
...(getBoolean(values, 'sign') && paths.artifact
|
|
22
|
+
? [paths.artifact]
|
|
23
|
+
: []),
|
|
24
|
+
...(getBoolean(values, 'sign-checksums')
|
|
25
|
+
? [paths.checksums]
|
|
26
|
+
: []),
|
|
27
|
+
];
|
|
28
|
+
if (names.length && !targets.length) {
|
|
29
|
+
throw new ValidationError('--sign-format requires --sign or --sign-checksums; it does not enable signing.');
|
|
30
|
+
}
|
|
31
|
+
const signing = targets.length
|
|
32
|
+
? {
|
|
33
|
+
paths: targets,
|
|
34
|
+
formats: parseSignatureFormats(names),
|
|
35
|
+
force: getBoolean(values, 'force'),
|
|
36
|
+
}
|
|
37
|
+
: undefined;
|
|
38
|
+
if (signing) {
|
|
39
|
+
checkSigningInput(signing);
|
|
40
|
+
}
|
|
41
|
+
return signing;
|
|
42
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { BuildPackageResult } from '../package-build.ts';
|
|
2
|
+
import type { CommandOutcome } from './command.ts';
|
|
3
|
+
export interface BuildResult extends BuildPackageResult {
|
|
4
|
+
package?: string;
|
|
5
|
+
signatures?: string[];
|
|
6
|
+
publicKey?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: {
|
|
9
|
+
name: string;
|
|
10
|
+
usage: string;
|
|
11
|
+
summary: string;
|
|
12
|
+
help: string;
|
|
13
|
+
options: {
|
|
14
|
+
package: {
|
|
15
|
+
type: "string";
|
|
16
|
+
};
|
|
17
|
+
force: {
|
|
18
|
+
type: "boolean";
|
|
19
|
+
};
|
|
20
|
+
output: {
|
|
21
|
+
type: "string";
|
|
22
|
+
};
|
|
23
|
+
slug: {
|
|
24
|
+
type: "string";
|
|
25
|
+
};
|
|
26
|
+
version: {
|
|
27
|
+
type: "string";
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
run({ values, positionals, cwd, configFile, logger, }: import("./command.ts").CommandContext): Promise<CommandOutcome<BuildResult>>;
|
|
31
|
+
};
|
|
32
|
+
export default _default;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { checksumSigningArgs, getArtifactSigning } from "./artifact-signing.js";
|
|
2
|
+
import { signFiles } from "../signing.js";
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { getBuildSummary, getSignSummary } from "../summary.js";
|
|
5
|
+
import { ValidationError } from "../errors.js";
|
|
6
|
+
import { buildPackage, getBuildChecksumsPath } from "../package-build.js";
|
|
7
|
+
import { fileSelectionArgs, sourceDirArgs } from "./args.js";
|
|
8
|
+
import { getBoolean, getString } from "./command.js";
|
|
9
|
+
import { getDirectorySource, getPackageArg, getPackageSource, } from "./package-source.js";
|
|
10
|
+
export default {
|
|
11
|
+
name: 'build',
|
|
12
|
+
usage: 'build [<source-dir>] --output <dir> [options] | build --package <name> --output <dir>',
|
|
13
|
+
summary: 'Copy the selected release files into an output directory.',
|
|
14
|
+
help: `Options:
|
|
15
|
+
--output <dir> Required destination; files go directly inside it
|
|
16
|
+
--source-dir <dir> Source directory (default: .), or a positional argument
|
|
17
|
+
--package <name> Use the configured package directory and file rules
|
|
18
|
+
--distignore <file> Ignore file (default: <source-dir>/.distignore)
|
|
19
|
+
--no-distignore Don't read an ignore file
|
|
20
|
+
--exclude <patterns> Extra patterns, comma-separated or repeated
|
|
21
|
+
--exclude-gitattributes Exclude Git export-ignore paths
|
|
22
|
+
--slug <slug> Slug in the manifest (default: project directory name)
|
|
23
|
+
--version <version> Manifest version (default: Version header)
|
|
24
|
+
--checksums Write <output-dir>.checksums.json beside the directory
|
|
25
|
+
--sign-checksums Generate and sign the manifest; implies --checksums
|
|
26
|
+
--sign-format <names> Formats: wordpress,minisign,ssh; requires --sign-checksums
|
|
27
|
+
--force Replace an existing output directory, removing stale files
|
|
28
|
+
|
|
29
|
+
The output directory is excluded from the source selection. It cannot be the
|
|
30
|
+
source directory or an ancestor. --sign is unsupported for directories.
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
wp-release build --output dist/my-plugin
|
|
34
|
+
wp-release build --package plugins/alpha --output dist/alpha`,
|
|
35
|
+
options: {
|
|
36
|
+
output: { type: 'string' },
|
|
37
|
+
slug: { type: 'string' },
|
|
38
|
+
version: { type: 'string' },
|
|
39
|
+
...checksumSigningArgs,
|
|
40
|
+
...sourceDirArgs,
|
|
41
|
+
...fileSelectionArgs,
|
|
42
|
+
package: { type: 'string' },
|
|
43
|
+
force: { type: 'boolean' },
|
|
44
|
+
},
|
|
45
|
+
async run({ values, positionals, cwd, configFile, logger, }) {
|
|
46
|
+
const output = getString(values, 'output');
|
|
47
|
+
if (!output?.trim()) {
|
|
48
|
+
throw new ValidationError('build requires --output <dir>.');
|
|
49
|
+
}
|
|
50
|
+
const name = getPackageArg(values, positionals);
|
|
51
|
+
const source = name
|
|
52
|
+
? await getPackageSource(values, cwd, name, configFile)
|
|
53
|
+
: await getDirectorySource(values, positionals, cwd);
|
|
54
|
+
const outputDir = resolve(cwd, output);
|
|
55
|
+
const signing = getArtifactSigning(values, {
|
|
56
|
+
checksums: getBuildChecksumsPath(outputDir),
|
|
57
|
+
});
|
|
58
|
+
const built = await buildPackage({
|
|
59
|
+
sourceDir: source.sourceDir,
|
|
60
|
+
selection: source.selection,
|
|
61
|
+
outputDir,
|
|
62
|
+
checksums: getBoolean(values, 'checksums') ||
|
|
63
|
+
getBoolean(values, 'sign-checksums'),
|
|
64
|
+
slug: source.slug,
|
|
65
|
+
version: source.version,
|
|
66
|
+
...(source.type ? { type: source.type } : {}),
|
|
67
|
+
force: getBoolean(values, 'force'),
|
|
68
|
+
});
|
|
69
|
+
const signed = signing
|
|
70
|
+
? { ...(await signFiles(signing)), formats: signing.formats }
|
|
71
|
+
: undefined;
|
|
72
|
+
const result = {
|
|
73
|
+
...built,
|
|
74
|
+
...(signed
|
|
75
|
+
? { signatures: signed.signatures, publicKey: signed.publicKey }
|
|
76
|
+
: {}),
|
|
77
|
+
...(source.package ? { package: source.package } : {}),
|
|
78
|
+
};
|
|
79
|
+
logger.debug(`Built ${built.files} files from ${source.sourceDir}.`);
|
|
80
|
+
logger.info(built.outputDir);
|
|
81
|
+
if (built.checksumsPath) {
|
|
82
|
+
logger.info(built.checksumsPath);
|
|
83
|
+
}
|
|
84
|
+
signed?.signatures.forEach((path) => logger.info(path));
|
|
85
|
+
logger.summary((context) => getBuildSummary(context, result));
|
|
86
|
+
if (signed) {
|
|
87
|
+
logger.summary((context) => getSignSummary(context, signed));
|
|
88
|
+
}
|
|
89
|
+
return { exitCode: 0, result };
|
|
90
|
+
},
|
|
91
|
+
};
|
|
@@ -8,24 +8,73 @@ declare const _default: {
|
|
|
8
8
|
summary: string;
|
|
9
9
|
help: string;
|
|
10
10
|
options: {
|
|
11
|
-
|
|
11
|
+
'version-package-json': {
|
|
12
12
|
readonly type: "string";
|
|
13
13
|
readonly multiple: true;
|
|
14
14
|
};
|
|
15
|
-
|
|
15
|
+
'version-composer-json': {
|
|
16
16
|
readonly type: "string";
|
|
17
17
|
readonly multiple: true;
|
|
18
18
|
};
|
|
19
|
-
|
|
19
|
+
'version-wordpress-plugin': {
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
readonly multiple: true;
|
|
22
|
+
};
|
|
23
|
+
'version-wordpress-theme': {
|
|
24
|
+
readonly type: "string";
|
|
25
|
+
readonly multiple: true;
|
|
26
|
+
};
|
|
27
|
+
'version-wordpress-stable-tag': {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly multiple: true;
|
|
30
|
+
};
|
|
31
|
+
'version-php-constant': {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
readonly multiple: true;
|
|
34
|
+
};
|
|
35
|
+
'version-git-tag': {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
readonly multiple: true;
|
|
38
|
+
};
|
|
39
|
+
'version-from': {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
};
|
|
42
|
+
'base-branch': {
|
|
43
|
+
readonly type: "string";
|
|
44
|
+
};
|
|
45
|
+
remote: {
|
|
46
|
+
readonly type: "string";
|
|
47
|
+
};
|
|
48
|
+
'changesets-dir': {
|
|
49
|
+
readonly type: "string";
|
|
50
|
+
};
|
|
51
|
+
'readme-changelog': {
|
|
52
|
+
readonly type: "boolean";
|
|
53
|
+
};
|
|
54
|
+
'no-readme-changelog': {
|
|
55
|
+
readonly type: "boolean";
|
|
56
|
+
};
|
|
57
|
+
'changelog-insert-after': {
|
|
58
|
+
readonly type: "string";
|
|
59
|
+
};
|
|
60
|
+
package: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
readonly multiple: true;
|
|
63
|
+
};
|
|
64
|
+
bump: {
|
|
65
|
+
readonly type: "string";
|
|
66
|
+
readonly multiple: true;
|
|
67
|
+
};
|
|
68
|
+
summary: {
|
|
20
69
|
readonly type: "string";
|
|
21
70
|
};
|
|
22
|
-
|
|
71
|
+
empty: {
|
|
23
72
|
readonly type: "boolean";
|
|
24
73
|
};
|
|
25
|
-
|
|
74
|
+
since: {
|
|
26
75
|
readonly type: "string";
|
|
27
76
|
};
|
|
28
|
-
|
|
77
|
+
name: {
|
|
29
78
|
readonly type: "string";
|
|
30
79
|
};
|
|
31
80
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { changesetProjectArgs, changesetProjectHelp, parseChangesetProjectArgs, } from "./changeset-project-args.js";
|
|
1
2
|
import { resolvePackageNames } from "../changeset-packages.js";
|
|
2
3
|
import { ChangesetPrompt } from "../changeset-prompt.js";
|
|
3
4
|
import { ChangesetRelease } from "../changeset-release.js";
|
|
@@ -13,6 +14,12 @@ import { parseChangesetAddArgs, changesetAddArgs } from "./changeset-args.js";
|
|
|
13
14
|
* @throws {ValidationError} If no changed package needs a changeset.
|
|
14
15
|
*/
|
|
15
16
|
async function getChangedPackageBumps(release, input, bump) {
|
|
17
|
+
const packages = await release.getPackages();
|
|
18
|
+
if (!input.since &&
|
|
19
|
+
1 === packages.length &&
|
|
20
|
+
'.' === packages[0]?.path) {
|
|
21
|
+
return { [packages[0].name]: bump };
|
|
22
|
+
}
|
|
16
23
|
const status = await release.getStatus({
|
|
17
24
|
...(input.since ? { since: input.since } : {}),
|
|
18
25
|
uncommitted: true,
|
|
@@ -99,15 +106,17 @@ export default {
|
|
|
99
106
|
|
|
100
107
|
Use --package and --bump pairs for package releases, or --empty for changes
|
|
101
108
|
that should pass the status check without producing a release. A single
|
|
102
|
-
--bump without --package
|
|
109
|
+
--bump without --package selects the sole root package, or releases packages
|
|
110
|
+
that changed since the base
|
|
103
111
|
ref, including uncommitted files, and have no changeset yet. Without
|
|
104
112
|
--package and --bump in a terminal, the command asks for the packages, with
|
|
105
|
-
the changed ones preselected, their bumps and the release note
|
|
106
|
-
options: changesetAddArgs,
|
|
113
|
+
the changed ones preselected, their bumps and the release note.${changesetProjectHelp}`,
|
|
114
|
+
options: { ...changesetAddArgs, ...changesetProjectArgs },
|
|
107
115
|
async run({ values, cwd, configFile, tagFormat, logger, terminal }) {
|
|
108
116
|
const input = parseChangesetAddArgs(values);
|
|
109
117
|
const release = new ChangesetRelease({
|
|
110
118
|
cwd,
|
|
119
|
+
...parseChangesetProjectArgs(values),
|
|
111
120
|
...(configFile ? { configFile } : {}),
|
|
112
121
|
...(tagFormat ? { tagFormat } : {}),
|
|
113
122
|
});
|
|
@@ -193,8 +193,8 @@ export function parseChangesetTagArgs(values) {
|
|
|
193
193
|
if ('' === args.version) {
|
|
194
194
|
throw new ValidationError('--version <version> must not be empty.');
|
|
195
195
|
}
|
|
196
|
-
if (undefined !== args.version &&
|
|
197
|
-
throw new ValidationError('--version <version>
|
|
196
|
+
if (undefined !== args.version && args.packages.length > 1) {
|
|
197
|
+
throw new ValidationError('--version <version> accepts at most one --package <name>.');
|
|
198
198
|
}
|
|
199
199
|
if (args.untagged && args.push) {
|
|
200
200
|
throw new ValidationError('--untagged cannot be combined with --push.');
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { SingleProjectOptions } from '../single-project.ts';
|
|
2
|
+
import type { ParsedValues } from './command.ts';
|
|
3
|
+
export declare const changesetProjectArgs: {
|
|
4
|
+
readonly 'version-package-json': {
|
|
5
|
+
readonly type: "string";
|
|
6
|
+
readonly multiple: true;
|
|
7
|
+
};
|
|
8
|
+
readonly 'version-composer-json': {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly multiple: true;
|
|
11
|
+
};
|
|
12
|
+
readonly 'version-wordpress-plugin': {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly multiple: true;
|
|
15
|
+
};
|
|
16
|
+
readonly 'version-wordpress-theme': {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
readonly multiple: true;
|
|
19
|
+
};
|
|
20
|
+
readonly 'version-wordpress-stable-tag': {
|
|
21
|
+
readonly type: "string";
|
|
22
|
+
readonly multiple: true;
|
|
23
|
+
};
|
|
24
|
+
readonly 'version-php-constant': {
|
|
25
|
+
readonly type: "string";
|
|
26
|
+
readonly multiple: true;
|
|
27
|
+
};
|
|
28
|
+
readonly 'version-git-tag': {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
readonly multiple: true;
|
|
31
|
+
};
|
|
32
|
+
readonly 'version-from': {
|
|
33
|
+
readonly type: "string";
|
|
34
|
+
};
|
|
35
|
+
readonly 'base-branch': {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
};
|
|
38
|
+
readonly remote: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
};
|
|
41
|
+
readonly 'changesets-dir': {
|
|
42
|
+
readonly type: "string";
|
|
43
|
+
};
|
|
44
|
+
readonly 'readme-changelog': {
|
|
45
|
+
readonly type: "boolean";
|
|
46
|
+
};
|
|
47
|
+
readonly 'no-readme-changelog': {
|
|
48
|
+
readonly type: "boolean";
|
|
49
|
+
};
|
|
50
|
+
readonly 'changelog-insert-after': {
|
|
51
|
+
readonly type: "string";
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare const changesetProjectHelp = "\nSingle-project options (without a release config file):\n --version-package-json <file> npm version source/target (repeatable)\n --version-composer-json <file> Composer source/target (repeatable)\n --version-wordpress-plugin <file> Plugin header source/target (repeatable)\n --version-wordpress-theme <file> Theme header source/target (repeatable)\n --version-wordpress-stable-tag <file> Readme Stable tag source/target (repeatable)\n --version-php-constant <file>#<constant> PHP constant source/target (repeatable)\n --version-git-tag <pattern> Git tag source only; use {version}\n --version-from <kind>[:<file>] Choose the source; constants use file#constant\n --base-branch <branch> Default comparison branch on the remote\n --remote <name> Git remote (default: origin)\n --changesets-dir <dir> Changeset directory (default: .changeset)\n --readme-changelog / --no-readme-changelog\n Enable/disable readme changelog updates\n --changelog-insert-after <marker> Insert changelog entries after this marker\n\nExplicit descriptors define all version targets. Without them, detect one root\nproject. A unique non-Stable-tag descriptor is the inferred source; otherwise\npass --version-from, qualifying it with :file when its kind is repeated.\nUse the same project options for every changeset command.";
|
|
55
|
+
/**
|
|
56
|
+
* Parse shared single-project settings; operation flags stay command-specific.
|
|
57
|
+
*
|
|
58
|
+
* @param values Parsed command arguments.
|
|
59
|
+
* @return Fallback settings when explicitly supplied.
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseChangesetProjectArgs(values: ParsedValues): {
|
|
62
|
+
singleProject?: SingleProjectOptions;
|
|
63
|
+
};
|