@wpelevator/wp-release 0.12.0 → 0.14.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 +150 -19
- package/dist/changeset-config.d.ts +91 -5
- package/dist/changeset-config.js +108 -11
- 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 +55 -8
- package/dist/changeset-packages.js +85 -14
- package/dist/changeset-prompt.d.ts +119 -0
- package/dist/changeset-prompt.js +203 -0
- package/dist/changeset-release.d.ts +43 -5
- package/dist/changeset-release.js +99 -16
- package/dist/changesets.d.ts +6 -2
- package/dist/changesets.js +18 -12
- package/dist/cli.d.ts +7 -1
- package/dist/cli.js +51 -14
- package/dist/commands/args.d.ts +0 -21
- package/dist/commands/args.js +1 -35
- package/dist/commands/changeset-add.d.ts +5 -2
- package/dist/commands/changeset-add.js +109 -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 +3 -1
- package/dist/commands/changeset-status.js +2 -1
- package/dist/commands/changeset-tag.d.ts +1 -1
- package/dist/commands/changeset-tag.js +6 -3
- package/dist/commands/changeset-version.d.ts +7 -1
- package/dist/commands/changeset-version.js +17 -4
- package/dist/commands/checksums.js +2 -2
- package/dist/commands/command.d.ts +5 -0
- package/dist/commands/deploy-git.d.ts +24 -4
- package/dist/commands/deploy-git.js +57 -3
- package/dist/commands/deploy-svn.d.ts +24 -4
- package/dist/commands/deploy-svn.js +57 -2
- package/dist/commands/keygen.d.ts +3 -0
- package/dist/commands/keygen.js +6 -1
- package/dist/commands/package-deploys.d.ts +86 -0
- package/dist/commands/package-deploys.js +113 -0
- package/dist/commands/sign.d.ts +19 -1
- package/dist/commands/sign.js +47 -12
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.js +43 -24
- package/dist/commands/zip.d.ts +12 -8
- package/dist/commands/zip.js +135 -78
- package/dist/ed25519.d.ts +25 -0
- package/dist/ed25519.js +44 -0
- package/dist/file-selection.d.ts +21 -0
- package/dist/file-selection.js +35 -0
- package/dist/git-deploy.d.ts +32 -0
- package/dist/git-deploy.js +57 -1
- package/dist/git.d.ts +17 -0
- package/dist/git.js +23 -0
- package/dist/index.d.ts +13 -5
- package/dist/index.js +7 -3
- package/dist/minisign.d.ts +41 -0
- package/dist/minisign.js +128 -0
- package/dist/package-deploy.d.ts +133 -0
- package/dist/package-deploy.js +323 -0
- package/dist/package-zip.d.ts +52 -0
- package/dist/package-zip.js +78 -0
- package/dist/release-repository.d.ts +18 -5
- package/dist/release-repository.js +51 -11
- package/dist/release-tags.d.ts +3 -1
- package/dist/release-tags.js +5 -2
- package/dist/signing.d.ts +64 -9
- package/dist/signing.js +113 -40
- package/dist/ssh-signature.d.ts +43 -0
- package/dist/ssh-signature.js +156 -0
- package/dist/summary.d.ts +3 -3
- package/dist/summary.js +2 -2
- package/dist/tag-format.d.ts +23 -14
- package/dist/tag-format.js +26 -40
- package/dist/version-files.d.ts +8 -8
- package/dist/version-files.js +22 -18
- package/dist/versions.d.ts +28 -3
- package/dist/versions.js +84 -9
- package/package.json +2 -2
|
@@ -29,8 +29,14 @@ declare const _default: {
|
|
|
29
29
|
readonly 'no-dependents': {
|
|
30
30
|
readonly type: "boolean";
|
|
31
31
|
};
|
|
32
|
+
readonly prerelease: {
|
|
33
|
+
readonly type: "string";
|
|
34
|
+
};
|
|
35
|
+
readonly snapshot: {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
};
|
|
32
38
|
};
|
|
33
|
-
run({ values, cwd, configFile, logger }: import("./command.ts").CommandContext): Promise<{
|
|
39
|
+
run({ values, cwd, configFile, tagFormat, logger }: import("./command.ts").CommandContext): Promise<{
|
|
34
40
|
exitCode: number;
|
|
35
41
|
result: {
|
|
36
42
|
date: string;
|
|
@@ -3,24 +3,37 @@ import { getChangesetVersionSummary } from "../summary.js";
|
|
|
3
3
|
import { parseChangesetVersionArgs, changesetVersionArgs, } from "./changeset-args.js";
|
|
4
4
|
export default {
|
|
5
5
|
name: 'changeset-version',
|
|
6
|
-
usage: 'changeset-version [--dry-run] [--date <YYYY-MM-DD>] [--package <name>] [--no-dependents]',
|
|
6
|
+
usage: 'changeset-version [--dry-run] [--date <YYYY-MM-DD>] [--package <name>] [--no-dependents] [--prerelease <id> | --snapshot <id>]',
|
|
7
7
|
summary: 'Apply pending version bumps and changelog entries.',
|
|
8
8
|
help: `Options:
|
|
9
9
|
--dry-run Print the release plan without writing files
|
|
10
10
|
--date <YYYY-MM-DD> Changelog date (default: today)
|
|
11
|
-
--package <name> Version only this package
|
|
11
|
+
--package <name> Version only this package, by identifier or path
|
|
12
|
+
under the configured root (repeatable)
|
|
12
13
|
--no-dependents Leave the configured dependents of the selected sources out
|
|
14
|
+
--prerelease <id> Release pre-releases like 1.3.0-rc.1, with an identifier
|
|
15
|
+
like rc (numbered from the tags) or rc.1
|
|
16
|
+
--snapshot <id> Release snapshots like 1.3.0-pr-251.20261012183000,
|
|
17
|
+
with an identifier like pr-251 and the UTC time
|
|
13
18
|
|
|
14
19
|
Updates configured version files, prepends changelog entries and removes the
|
|
15
20
|
applied changeset files. With --package, a changeset that also names other
|
|
16
21
|
packages keeps only their entries, so it still applies to their releases, and
|
|
17
|
-
changesets without packages are left for a run without --package
|
|
22
|
+
changesets without packages are left for a run without --package.
|
|
23
|
+
|
|
24
|
+
With --prerelease, run it on a branch that isn't merged and tag that branch,
|
|
25
|
+
since the pre-release consumes the changesets that the stable release needs.
|
|
26
|
+
The readme Stable tag keeps the last stable version.
|
|
27
|
+
|
|
28
|
+
With --snapshot, build and publish the versioned files without committing
|
|
29
|
+
them, for example to test a pull request.`,
|
|
18
30
|
options: changesetVersionArgs,
|
|
19
|
-
async run({ values, cwd, configFile, logger }) {
|
|
31
|
+
async run({ values, cwd, configFile, tagFormat, logger }) {
|
|
20
32
|
const args = parseChangesetVersionArgs(values);
|
|
21
33
|
const result = await versionChangesets({
|
|
22
34
|
cwd,
|
|
23
35
|
...(configFile ? { configFile } : {}),
|
|
36
|
+
...(tagFormat ? { tagFormat } : {}),
|
|
24
37
|
...args,
|
|
25
38
|
});
|
|
26
39
|
result.releases.forEach((release) => logger.info(`${release.package.name}: ${release.currentVersion} → ${release.nextVersion} (${release.bump})`));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { basename, resolve } from 'node:path';
|
|
2
2
|
import { CHECKSUMS_EXTENSION, createChecksums, writeChecksums, } from "../checksums.js";
|
|
3
|
-
import { loadFileRules, resolveFileSelection } from "../file-selection.js";
|
|
3
|
+
import { ignoreOwnFile, ignoreOwnSignature, loadFileRules, resolveFileSelection, } from "../file-selection.js";
|
|
4
4
|
import { FILENAME_FORMAT, formatFilename } from "../filename.js";
|
|
5
5
|
import { readPackageMeta } from "../package-meta.js";
|
|
6
6
|
import { getChecksumsSummary } from "../summary.js";
|
|
7
|
-
import { checkDirectory, fileSelectionArgs, getFileSelectionInput, getSourceDirArg,
|
|
7
|
+
import { checkDirectory, fileSelectionArgs, getFileSelectionInput, getSourceDirArg, resolveOutput, sourceDirArgs, } from "./args.js";
|
|
8
8
|
import { getBoolean, getString } from "./command.js";
|
|
9
9
|
export default {
|
|
10
10
|
name: 'checksums',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ParseArgsOptionsConfig } from 'node:util';
|
|
2
|
+
import type { PromptTerminal } from '../changeset-prompt.ts';
|
|
2
3
|
import type { Logger } from '../logger.ts';
|
|
3
4
|
/**
|
|
4
5
|
* Parsed option values from node:util parseArgs().
|
|
@@ -13,8 +14,12 @@ export interface CommandContext {
|
|
|
13
14
|
cwd: string;
|
|
14
15
|
/** Explicit JavaScript release config path from --config, if supplied. */
|
|
15
16
|
configFile?: string;
|
|
17
|
+
/** Tag format from --tag-format, which replaces the tagFormat of the config. */
|
|
18
|
+
tagFormat?: string;
|
|
16
19
|
/** Logger for the command output. */
|
|
17
20
|
logger: Logger;
|
|
21
|
+
/** Terminal for interactive prompts, only when the CLI runs in one and prints no JSON. */
|
|
22
|
+
terminal?: PromptTerminal;
|
|
18
23
|
}
|
|
19
24
|
export interface CommandOutcome<Result = unknown> {
|
|
20
25
|
/** Process exit code. */
|
|
@@ -15,12 +15,22 @@ declare const _default: {
|
|
|
15
15
|
summary: string;
|
|
16
16
|
help: string;
|
|
17
17
|
options: {
|
|
18
|
-
message: {
|
|
19
|
-
type: "string";
|
|
20
|
-
};
|
|
21
18
|
'dry-run': {
|
|
22
19
|
type: "boolean";
|
|
23
20
|
};
|
|
21
|
+
'release-ref': {
|
|
22
|
+
readonly type: "string";
|
|
23
|
+
};
|
|
24
|
+
package: {
|
|
25
|
+
readonly type: "string";
|
|
26
|
+
readonly multiple: true;
|
|
27
|
+
};
|
|
28
|
+
list: {
|
|
29
|
+
readonly type: "boolean";
|
|
30
|
+
};
|
|
31
|
+
message: {
|
|
32
|
+
type: "string";
|
|
33
|
+
};
|
|
24
34
|
'git-url': {
|
|
25
35
|
type: "string";
|
|
26
36
|
};
|
|
@@ -37,7 +47,17 @@ declare const _default: {
|
|
|
37
47
|
type: "string";
|
|
38
48
|
};
|
|
39
49
|
};
|
|
40
|
-
run({ values, positionals, cwd, logger }: import("./command.ts").CommandContext): Promise<{
|
|
50
|
+
run({ values, positionals, cwd, configFile, tagFormat, logger }: import("./command.ts").CommandContext): Promise<{
|
|
51
|
+
exitCode: number;
|
|
52
|
+
result: {
|
|
53
|
+
packages: import("../package-deploy.ts").PackageDeployPlanItem[];
|
|
54
|
+
};
|
|
55
|
+
} | {
|
|
56
|
+
exitCode: number;
|
|
57
|
+
result: {
|
|
58
|
+
deploys: import("./package-deploys.ts").PackageDeployOutcome<import("../git-deploy.ts").GitDeployResult>[];
|
|
59
|
+
};
|
|
60
|
+
} | {
|
|
41
61
|
exitCode: number;
|
|
42
62
|
result: import("../git-deploy.ts").GitDeployResult;
|
|
43
63
|
}>;
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import { GitDeploy, resolveGitDeployOptions } from "../git-deploy.js";
|
|
2
|
+
import { getGitDeploys } from "../package-deploy.js";
|
|
2
3
|
import { fileSelectionArgs, getFileSelectionInput, getSourceDirArg, sourceDirArgs, } from "./args.js";
|
|
3
4
|
import { getBoolean, getString } from "./command.js";
|
|
5
|
+
import { getPackageDeployArgs, listPackageDeploys, packageDeployArgs, runPackageDeploys, } from "./package-deploys.js";
|
|
6
|
+
/** Options of a single deploy target, which --release-ref takes from the config. */
|
|
7
|
+
const TARGET_FLAGS = [
|
|
8
|
+
'source-dir',
|
|
9
|
+
'git-url',
|
|
10
|
+
'branch',
|
|
11
|
+
'tag',
|
|
12
|
+
'split-prefix',
|
|
13
|
+
'source-ref',
|
|
14
|
+
'distignore',
|
|
15
|
+
'no-distignore',
|
|
16
|
+
'exclude',
|
|
17
|
+
'exclude-gitattributes',
|
|
18
|
+
'message',
|
|
19
|
+
];
|
|
4
20
|
/**
|
|
5
21
|
* Map the parsed "deploy-git" arguments to resolveGitDeployOptions() input.
|
|
6
22
|
*
|
|
@@ -25,7 +41,7 @@ export function getGitDeployInputFromArgs(values, positionals, cwd) {
|
|
|
25
41
|
}
|
|
26
42
|
export default {
|
|
27
43
|
name: 'deploy-git',
|
|
28
|
-
usage: 'deploy-git [<source-dir>] --git-url <url> [options]',
|
|
44
|
+
usage: 'deploy-git [<source-dir>] --git-url <url> [options] | deploy-git --release-ref <ref> [--package <name>] [--list] [--dry-run]',
|
|
29
45
|
summary: 'Deploy the files of a plugin, theme or package to a Git repository as a release commit.',
|
|
30
46
|
help: `Arguments:
|
|
31
47
|
<source-dir> Directory with the files to release (default: .),
|
|
@@ -37,6 +53,17 @@ Writes (none by default):
|
|
|
37
53
|
--tag <name> Create this tag for the release, on top of --branch
|
|
38
54
|
or the default branch of the repository
|
|
39
55
|
|
|
56
|
+
Configured packages (instead of the options above):
|
|
57
|
+
--release-ref <ref> Deploy the packages that this ref releases to the Git
|
|
58
|
+
targets in the config: the package of a release tag,
|
|
59
|
+
like refs/tags/plugins/alpha/1.2.0, or every package
|
|
60
|
+
for a branch, like refs/heads/main
|
|
61
|
+
--package <name> Deploy only this package (repeatable), for example
|
|
62
|
+
in a CI job for each package or to retry one
|
|
63
|
+
--list List the deploys without running them, with the
|
|
64
|
+
deploys of each package as the result for --json
|
|
65
|
+
and --github-output, for a CI matrix
|
|
66
|
+
|
|
40
67
|
Options:
|
|
41
68
|
--git-url <url> Repository to deploy to
|
|
42
69
|
--split-prefix <dir> Use the history of this directory of the source
|
|
@@ -56,9 +83,21 @@ branch only moves forward, a release without changes isn't pushed again, an
|
|
|
56
83
|
older build doesn't move a branch that has newer source history, a tag that
|
|
57
84
|
already has the same files is reused, and a tag with other files
|
|
58
85
|
fails with exit code 2 (delete it in the repository to release it again). The source directory must be inside a Git repository.
|
|
59
|
-
Credentials come from git, like a
|
|
86
|
+
Credentials come from git, like a credential helper or an SSH key. For an
|
|
87
|
+
HTTPS repository on github.com, or on the host of GITHUB_SERVER_URL, the
|
|
88
|
+
GITHUB_TOKEN environment variable is sent as an authorization header, so the
|
|
89
|
+
token stays out of the URL.
|
|
90
|
+
|
|
91
|
+
With --release-ref, each package deploys to every Git target of its
|
|
92
|
+
deploy.git config, with the history of its directory, in one log group for
|
|
93
|
+
each package, and a failed deploy doesn't stop the others but exits with 1. A release tag creates the tag of each target on top
|
|
94
|
+
of its default branch, and a branch releases to the same branch.
|
|
60
95
|
|
|
61
96
|
Examples:
|
|
97
|
+
wp-release deploy-git --release-ref "$GITHUB_REF"
|
|
98
|
+
Deploy the configured packages of a tag or branch push
|
|
99
|
+
wp-release deploy-git --release-ref refs/heads/main --list
|
|
100
|
+
Preview what a push to main deploys
|
|
62
101
|
wp-release deploy-git build --git-url git@github.com:me/my-plugin-dist.git --branch main --tag 1.2.0
|
|
63
102
|
Release a build to a distribution repository and tag it
|
|
64
103
|
wp-release deploy-git packages/my-plugin --split-prefix packages/my-plugin --git-url … --branch main
|
|
@@ -72,9 +111,24 @@ Examples:
|
|
|
72
111
|
'source-ref': { type: 'string' },
|
|
73
112
|
...fileSelectionArgs,
|
|
74
113
|
message: { type: 'string' },
|
|
114
|
+
...packageDeployArgs,
|
|
75
115
|
'dry-run': { type: 'boolean' },
|
|
76
116
|
},
|
|
77
|
-
async run({ values, positionals, cwd, logger }) {
|
|
117
|
+
async run({ values, positionals, cwd, configFile, tagFormat, logger }) {
|
|
118
|
+
const { ref, packages, list } = getPackageDeployArgs(values, positionals, TARGET_FLAGS);
|
|
119
|
+
if (ref) {
|
|
120
|
+
const deploys = await getGitDeploys({
|
|
121
|
+
cwd,
|
|
122
|
+
ref,
|
|
123
|
+
packages,
|
|
124
|
+
dryRun: getBoolean(values, 'dry-run'),
|
|
125
|
+
...(configFile ? { configFile } : {}),
|
|
126
|
+
...(tagFormat ? { tagFormat } : {}),
|
|
127
|
+
});
|
|
128
|
+
return list
|
|
129
|
+
? listPackageDeploys(deploys, logger, ref)
|
|
130
|
+
: runPackageDeploys(deploys, (input) => new GitDeploy(resolveGitDeployOptions(input), logger).run(), logger, ref);
|
|
131
|
+
}
|
|
78
132
|
const options = resolveGitDeployOptions(getGitDeployInputFromArgs(values, positionals, cwd));
|
|
79
133
|
const result = await new GitDeploy(options, logger).run();
|
|
80
134
|
return { exitCode: 0, result };
|
|
@@ -23,6 +23,19 @@ declare const _default: {
|
|
|
23
23
|
summary: string;
|
|
24
24
|
help: string;
|
|
25
25
|
options: {
|
|
26
|
+
'dry-run': {
|
|
27
|
+
type: "boolean";
|
|
28
|
+
};
|
|
29
|
+
'release-ref': {
|
|
30
|
+
readonly type: "string";
|
|
31
|
+
};
|
|
32
|
+
package: {
|
|
33
|
+
readonly type: "string";
|
|
34
|
+
readonly multiple: true;
|
|
35
|
+
};
|
|
36
|
+
list: {
|
|
37
|
+
readonly type: "boolean";
|
|
38
|
+
};
|
|
26
39
|
'svn-url': {
|
|
27
40
|
type: "string";
|
|
28
41
|
};
|
|
@@ -35,9 +48,6 @@ declare const _default: {
|
|
|
35
48
|
force: {
|
|
36
49
|
type: "boolean";
|
|
37
50
|
};
|
|
38
|
-
'dry-run': {
|
|
39
|
-
type: "boolean";
|
|
40
|
-
};
|
|
41
51
|
trunk: {
|
|
42
52
|
type: "boolean";
|
|
43
53
|
};
|
|
@@ -66,7 +76,17 @@ declare const _default: {
|
|
|
66
76
|
type: "string";
|
|
67
77
|
};
|
|
68
78
|
};
|
|
69
|
-
run({ values, positionals, cwd, logger }: import("./command.ts").CommandContext): Promise<{
|
|
79
|
+
run({ values, positionals, cwd, configFile, tagFormat, logger }: import("./command.ts").CommandContext): Promise<{
|
|
80
|
+
exitCode: number;
|
|
81
|
+
result: {
|
|
82
|
+
packages: import("../package-deploy.ts").PackageDeployPlanItem[];
|
|
83
|
+
};
|
|
84
|
+
} | {
|
|
85
|
+
exitCode: number;
|
|
86
|
+
result: {
|
|
87
|
+
deploys: import("./package-deploys.ts").PackageDeployOutcome<import("../svn-deploy.ts").DeployResult>[];
|
|
88
|
+
};
|
|
89
|
+
} | {
|
|
70
90
|
exitCode: number;
|
|
71
91
|
result: import("../svn-deploy.ts").DeployResult;
|
|
72
92
|
}>;
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { resolveDeployOptions } from "../deploy-options.js";
|
|
2
|
+
import { getSvnDeploys } from "../package-deploy.js";
|
|
2
3
|
import { SvnDeploy } from "../svn-deploy.js";
|
|
3
4
|
import { fileSelectionArgs, getFileSelectionInput, getSourceDirArg, sourceDirArgs, } from "./args.js";
|
|
4
5
|
import { getBoolean, getString } from "./command.js";
|
|
6
|
+
import { getPackageDeployArgs, listPackageDeploys, packageDeployArgs, runPackageDeploys, } from "./package-deploys.js";
|
|
7
|
+
/** Options of a single deploy, which --release-ref takes from the config. */
|
|
8
|
+
const TARGET_FLAGS = [
|
|
9
|
+
'source-dir',
|
|
10
|
+
'trunk',
|
|
11
|
+
'readme-only',
|
|
12
|
+
'svn-tag',
|
|
13
|
+
'assets-dir',
|
|
14
|
+
'no-assets',
|
|
15
|
+
'slug',
|
|
16
|
+
'version',
|
|
17
|
+
'readme',
|
|
18
|
+
'from-zip',
|
|
19
|
+
'distignore',
|
|
20
|
+
'no-distignore',
|
|
21
|
+
'exclude',
|
|
22
|
+
'exclude-gitattributes',
|
|
23
|
+
'svn-url',
|
|
24
|
+
'message',
|
|
25
|
+
];
|
|
5
26
|
/**
|
|
6
27
|
* Map the parsed "deploy-svn" arguments to resolveDeployOptions() input.
|
|
7
28
|
* Flags that aren't passed stay undefined, so that the same defaults apply
|
|
@@ -35,7 +56,7 @@ export function getDeployInputFromArgs(input) {
|
|
|
35
56
|
}
|
|
36
57
|
export default {
|
|
37
58
|
name: 'deploy-svn',
|
|
38
|
-
usage: 'deploy-svn [<source-dir>] [options]',
|
|
59
|
+
usage: 'deploy-svn [<source-dir>] [options] | deploy-svn --release-ref <ref> [--package <name>] [--list] [--dry-run]',
|
|
39
60
|
summary: 'Deploy a plugin to the WordPress.org plugin SVN repository.',
|
|
40
61
|
help: `Arguments:
|
|
41
62
|
<source-dir> Directory with the plugin files (default: .), also
|
|
@@ -51,6 +72,15 @@ Writes (none by default, assets only with --assets-dir):
|
|
|
51
72
|
screenshots to assets/
|
|
52
73
|
--no-assets Don't sync --assets-dir for this run
|
|
53
74
|
|
|
75
|
+
Configured packages (instead of the writes and the source options):
|
|
76
|
+
--release-ref <ref> Deploy the package that this release tag releases,
|
|
77
|
+
like refs/tags/plugins/alpha/1.2.0, to the SVN
|
|
78
|
+
targets in the config. Branches aren't deployed.
|
|
79
|
+
--package <name> Deploy only this package (repeatable)
|
|
80
|
+
--list List the deploys without running them, with the
|
|
81
|
+
deploys of each package as the result for --json
|
|
82
|
+
and --github-output, for a CI matrix
|
|
83
|
+
|
|
54
84
|
Options:
|
|
55
85
|
--slug <slug> Plugin slug (default: project directory name)
|
|
56
86
|
--version <version> Version to check (default: --svn-tag, then the Version header)
|
|
@@ -71,7 +101,13 @@ Options:
|
|
|
71
101
|
Credentials are only needed to commit. Exits with 3 when they're missing
|
|
72
102
|
or rejected.
|
|
73
103
|
|
|
104
|
+
With --release-ref, a stable release syncs trunk/, creates its tag and syncs
|
|
105
|
+
the assetsDir of each deploy.svn target, while a pre-release only creates its
|
|
106
|
+
tag. A failed deploy doesn't stop the others and exits with 1.
|
|
107
|
+
|
|
74
108
|
Examples:
|
|
109
|
+
wp-release deploy-svn --release-ref "$GITHUB_REF"
|
|
110
|
+
Deploy the configured plugin of a release tag push
|
|
75
111
|
wp-release deploy-svn dist --trunk --svn-tag 1.2.0 --assets-dir .wordpress-org
|
|
76
112
|
Deploy 1.2.0 to trunk and the tag, and update the assets
|
|
77
113
|
wp-release deploy-svn dist --svn-tag 1.2.0-rc.1
|
|
@@ -96,9 +132,28 @@ Examples:
|
|
|
96
132
|
'svn-username': { type: 'string' },
|
|
97
133
|
message: { type: 'string' },
|
|
98
134
|
force: { type: 'boolean' },
|
|
135
|
+
...packageDeployArgs,
|
|
99
136
|
'dry-run': { type: 'boolean' },
|
|
100
137
|
},
|
|
101
|
-
async run({ values, positionals, cwd, logger }) {
|
|
138
|
+
async run({ values, positionals, cwd, configFile, tagFormat, logger }) {
|
|
139
|
+
const { ref, packages, list } = getPackageDeployArgs(values, positionals, TARGET_FLAGS);
|
|
140
|
+
if (ref) {
|
|
141
|
+
const deploys = await getSvnDeploys({
|
|
142
|
+
cwd,
|
|
143
|
+
ref,
|
|
144
|
+
packages,
|
|
145
|
+
dryRun: getBoolean(values, 'dry-run'),
|
|
146
|
+
...(configFile ? { configFile } : {}),
|
|
147
|
+
...(tagFormat ? { tagFormat } : {}),
|
|
148
|
+
});
|
|
149
|
+
return list
|
|
150
|
+
? listPackageDeploys(deploys, logger, ref)
|
|
151
|
+
: runPackageDeploys(deploys, (input) => new SvnDeploy(resolveDeployOptions({
|
|
152
|
+
...input,
|
|
153
|
+
svnUsername: getString(values, 'svn-username'),
|
|
154
|
+
force: getBoolean(values, 'force'),
|
|
155
|
+
}), logger).run(), logger, ref);
|
|
156
|
+
}
|
|
102
157
|
const options = resolveDeployOptions(getDeployInputFromArgs({ values, positionals, cwd }));
|
|
103
158
|
const result = await new SvnDeploy(options, logger).run();
|
|
104
159
|
return { exitCode: 0, result };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SignatureFormat } from '../signing.ts';
|
|
1
2
|
import type { CommandOutcome } from './command.ts';
|
|
2
3
|
/** Generated Ed25519 signing keys. */
|
|
3
4
|
export interface KeygenResult {
|
|
@@ -5,6 +6,8 @@ export interface KeygenResult {
|
|
|
5
6
|
privateKey: string;
|
|
6
7
|
/** Base64 Ed25519 public key for verification. */
|
|
7
8
|
publicKey: string;
|
|
9
|
+
/** Public key in the form of each signature format. */
|
|
10
|
+
publicKeys: Record<SignatureFormat, string>;
|
|
8
11
|
}
|
|
9
12
|
declare const _default: {
|
|
10
13
|
name: string;
|
package/dist/commands/keygen.js
CHANGED
|
@@ -8,7 +8,10 @@ export default {
|
|
|
8
8
|
help: `Generate a signing key pair for "wp-release sign" and "wp-release verify".
|
|
9
9
|
|
|
10
10
|
The private seed is printed once as WP_RELEASE_SIGNING_KEY. Store it securely
|
|
11
|
-
and never commit it or share it. The public key can be distributed to verifiers
|
|
11
|
+
and never commit it or share it. The public key can be distributed to verifiers.
|
|
12
|
+
It's also printed as a minisign public key for "minisign -V -P" and as an
|
|
13
|
+
ssh-ed25519 public key for the allowed_signers file of "ssh-keygen -Y verify",
|
|
14
|
+
since the same key signs every format of "wp-release sign".`,
|
|
12
15
|
options: {},
|
|
13
16
|
async run({ values, logger }) {
|
|
14
17
|
if (getBoolean(values, 'github-output')) {
|
|
@@ -17,6 +20,8 @@ and never commit it or share it. The public key can be distributed to verifiers.
|
|
|
17
20
|
const result = generateSigningKeyPair();
|
|
18
21
|
logger.info(`WP_RELEASE_SIGNING_KEY=${result.privateKey}`);
|
|
19
22
|
logger.info(`Public key: ${result.publicKey}`);
|
|
23
|
+
logger.info(`Minisign public key: ${result.publicKeys.minisign}`);
|
|
24
|
+
logger.info(`SSH public key: ${result.publicKeys.ssh}`);
|
|
20
25
|
logger.info('Store the private seed securely; it cannot be recovered from the public key.');
|
|
21
26
|
return { exitCode: 0, result };
|
|
22
27
|
},
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Logger } from '../logger.ts';
|
|
2
|
+
import type { PackageDeploy, PackageDeployPlanItem } from '../package-deploy.ts';
|
|
3
|
+
import type { ParsedValues } from './command.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Options of the deploy commands that deploy the configured packages of a
|
|
6
|
+
* ref, in node:util parseArgs() format.
|
|
7
|
+
*/
|
|
8
|
+
export declare const packageDeployArgs: {
|
|
9
|
+
readonly 'release-ref': {
|
|
10
|
+
readonly type: "string";
|
|
11
|
+
};
|
|
12
|
+
readonly package: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly multiple: true;
|
|
15
|
+
};
|
|
16
|
+
readonly list: {
|
|
17
|
+
readonly type: "boolean";
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/** Result of one deploy of a configured package. */
|
|
21
|
+
export interface PackageDeployOutcome<Result> {
|
|
22
|
+
package: string;
|
|
23
|
+
/** Package, target and ref, with credentials redacted. */
|
|
24
|
+
label: string;
|
|
25
|
+
/** Repository or WordPress.org plugin of the target, with credentials redacted. */
|
|
26
|
+
target: string;
|
|
27
|
+
/** Tag or branch that the deploy writes in the target. */
|
|
28
|
+
targetRef: string;
|
|
29
|
+
/** Host of a remote target repository, like github.com. */
|
|
30
|
+
targetHost?: string;
|
|
31
|
+
/** Path of a remote target repository on its host, like owner/repo. */
|
|
32
|
+
targetPath?: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
branch?: string;
|
|
35
|
+
/** Deploy result, unless it failed. */
|
|
36
|
+
result?: Result;
|
|
37
|
+
/** Error message of a failed deploy. */
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get the ref and the packages to deploy from the config, failing for the
|
|
42
|
+
* options that set a single deploy target instead.
|
|
43
|
+
*
|
|
44
|
+
* @param values Parsed CLI values.
|
|
45
|
+
* @param positionals Positional arguments.
|
|
46
|
+
* @param targetFlags Options of a single deploy target.
|
|
47
|
+
* @return The ref and the selected packages.
|
|
48
|
+
* @throws {ValidationError} For --package without --release-ref, or a single target option with it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getPackageDeployArgs(values: ParsedValues, positionals: string[], targetFlags: string[]): {
|
|
51
|
+
ref?: string;
|
|
52
|
+
packages: string[];
|
|
53
|
+
list: boolean;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Run the deploys of the configured packages one at a time, in one log group
|
|
57
|
+
* for each package, continuing after a failed deploy so that one package or
|
|
58
|
+
* target doesn't block the others.
|
|
59
|
+
*
|
|
60
|
+
* @param deploys Deploys from getGitDeploys() or getSvnDeploys().
|
|
61
|
+
* @param deploy Runs one deploy.
|
|
62
|
+
* @param logger Logger.
|
|
63
|
+
* @param ref Deployed ref, for the log.
|
|
64
|
+
* @return Exit code 1 when a deploy failed, and the result of each deploy.
|
|
65
|
+
*/
|
|
66
|
+
export declare function runPackageDeploys<Input, Result>(deploys: PackageDeploy<Input>[], deploy: (input: Input) => Promise<Result>, logger: Logger, ref: string): Promise<{
|
|
67
|
+
exitCode: number;
|
|
68
|
+
result: {
|
|
69
|
+
deploys: PackageDeployOutcome<Result>[];
|
|
70
|
+
};
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* List the deploys of the configured packages without running them, one line
|
|
74
|
+
* for each deploy, with the plan as the result for --json and --github-output.
|
|
75
|
+
*
|
|
76
|
+
* @param deploys Deploys from getGitDeploys() or getSvnDeploys().
|
|
77
|
+
* @param logger Logger.
|
|
78
|
+
* @param ref Deployed ref, for the log.
|
|
79
|
+
* @return Exit code 0 and the deploys of each package.
|
|
80
|
+
*/
|
|
81
|
+
export declare function listPackageDeploys(deploys: PackageDeploy<unknown>[], logger: Logger, ref: string): {
|
|
82
|
+
exitCode: number;
|
|
83
|
+
result: {
|
|
84
|
+
packages: PackageDeployPlanItem[];
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ValidationError } from "../errors.js";
|
|
2
|
+
import { getDeployPlan } from "../package-deploy.js";
|
|
3
|
+
import { logError } from "../report.js";
|
|
4
|
+
import { getBoolean, getString, getStrings } from "./command.js";
|
|
5
|
+
/**
|
|
6
|
+
* Options of the deploy commands that deploy the configured packages of a
|
|
7
|
+
* ref, in node:util parseArgs() format.
|
|
8
|
+
*/
|
|
9
|
+
export const packageDeployArgs = {
|
|
10
|
+
'release-ref': { type: 'string' },
|
|
11
|
+
package: { type: 'string', multiple: true },
|
|
12
|
+
list: { type: 'boolean' },
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Get the ref and the packages to deploy from the config, failing for the
|
|
16
|
+
* options that set a single deploy target instead.
|
|
17
|
+
*
|
|
18
|
+
* @param values Parsed CLI values.
|
|
19
|
+
* @param positionals Positional arguments.
|
|
20
|
+
* @param targetFlags Options of a single deploy target.
|
|
21
|
+
* @return The ref and the selected packages.
|
|
22
|
+
* @throws {ValidationError} For --package without --release-ref, or a single target option with it.
|
|
23
|
+
*/
|
|
24
|
+
export function getPackageDeployArgs(values, positionals, targetFlags) {
|
|
25
|
+
const ref = getString(values, 'release-ref')?.trim();
|
|
26
|
+
const packages = getStrings(values, 'package');
|
|
27
|
+
const list = getBoolean(values, 'list');
|
|
28
|
+
const conflicts = targetFlags.filter((flag) => undefined !== getString(values, flag) ||
|
|
29
|
+
getBoolean(values, flag) ||
|
|
30
|
+
getStrings(values, flag).length);
|
|
31
|
+
if ('' === ref) {
|
|
32
|
+
throw new ValidationError('--release-ref <ref> must not be empty.');
|
|
33
|
+
}
|
|
34
|
+
if ((packages.length || list) && !ref) {
|
|
35
|
+
throw new ValidationError(`${list ? '--list' : '--package'} requires --release-ref <ref>.`);
|
|
36
|
+
}
|
|
37
|
+
if (ref && (positionals.length || conflicts.length)) {
|
|
38
|
+
throw new ValidationError(`--release-ref deploys the configured packages and targets, so it can't be combined with ${positionals.length
|
|
39
|
+
? 'a source directory'
|
|
40
|
+
: conflicts.map((flag) => `--${flag}`).join(', ')}.`);
|
|
41
|
+
}
|
|
42
|
+
return { ...(ref ? { ref } : {}), packages, list };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Run the deploys of the configured packages one at a time, in one log group
|
|
46
|
+
* for each package, continuing after a failed deploy so that one package or
|
|
47
|
+
* target doesn't block the others.
|
|
48
|
+
*
|
|
49
|
+
* @param deploys Deploys from getGitDeploys() or getSvnDeploys().
|
|
50
|
+
* @param deploy Runs one deploy.
|
|
51
|
+
* @param logger Logger.
|
|
52
|
+
* @param ref Deployed ref, for the log.
|
|
53
|
+
* @return Exit code 1 when a deploy failed, and the result of each deploy.
|
|
54
|
+
*/
|
|
55
|
+
export async function runPackageDeploys(deploys, deploy, logger, ref) {
|
|
56
|
+
const outcomes = [];
|
|
57
|
+
const names = [
|
|
58
|
+
...new Set(deploys.map((item) => item.package.name)),
|
|
59
|
+
];
|
|
60
|
+
if (!deploys.length) {
|
|
61
|
+
logger.info(`No configured package deploys ${ref}.`);
|
|
62
|
+
}
|
|
63
|
+
for (const name of names) {
|
|
64
|
+
const items = deploys.filter((item) => item.package.name === name);
|
|
65
|
+
const release = items[0]?.release ?? {};
|
|
66
|
+
await logger.group(`${name} ${release.version ?? release.branch ?? ''}`.trim(), async () => {
|
|
67
|
+
for (const item of items) {
|
|
68
|
+
outcomes.push(await runDeploy(item, deploy, logger));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
exitCode: outcomes.some((outcome) => outcome.error) ? 1 : 0,
|
|
74
|
+
result: { deploys: outcomes },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function runDeploy(item, deploy, logger) {
|
|
78
|
+
const outcome = {
|
|
79
|
+
package: item.package.name,
|
|
80
|
+
label: item.label,
|
|
81
|
+
target: item.target,
|
|
82
|
+
targetRef: item.targetRef,
|
|
83
|
+
...(item.targetHost
|
|
84
|
+
? { targetHost: item.targetHost, targetPath: item.targetPath }
|
|
85
|
+
: {}),
|
|
86
|
+
...item.release,
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
outcome.result = await deploy(item.input);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
outcome.error =
|
|
93
|
+
error instanceof Error ? error.message : String(error);
|
|
94
|
+
logError(logger, error, `Deploy of ${item.label}`);
|
|
95
|
+
}
|
|
96
|
+
return outcome;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* List the deploys of the configured packages without running them, one line
|
|
100
|
+
* for each deploy, with the plan as the result for --json and --github-output.
|
|
101
|
+
*
|
|
102
|
+
* @param deploys Deploys from getGitDeploys() or getSvnDeploys().
|
|
103
|
+
* @param logger Logger.
|
|
104
|
+
* @param ref Deployed ref, for the log.
|
|
105
|
+
* @return Exit code 0 and the deploys of each package.
|
|
106
|
+
*/
|
|
107
|
+
export function listPackageDeploys(deploys, logger, ref) {
|
|
108
|
+
if (!deploys.length) {
|
|
109
|
+
logger.info(`No configured package deploys ${ref}.`);
|
|
110
|
+
}
|
|
111
|
+
deploys.forEach((item) => logger.info(item.label));
|
|
112
|
+
return { exitCode: 0, result: { packages: getDeployPlan(deploys) } };
|
|
113
|
+
}
|
package/dist/commands/sign.d.ts
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
|
+
import type { SignatureFormat } from '../signing.ts';
|
|
1
2
|
import type { CommandOutcome } from './command.ts';
|
|
2
3
|
/** Result of the sign command. */
|
|
3
4
|
export interface SignResult {
|
|
4
|
-
/** Absolute paths of the written
|
|
5
|
+
/** Absolute paths of the written signature files. */
|
|
5
6
|
signatures: string[];
|
|
7
|
+
/** Signature formats that were written. */
|
|
8
|
+
formats: SignatureFormat[];
|
|
6
9
|
/** Base64 public key of the signing key. */
|
|
7
10
|
publicKey: string;
|
|
11
|
+
/** Public key of the signing key in the form of each signature format. */
|
|
12
|
+
publicKeys: Record<SignatureFormat, string>;
|
|
8
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the signature formats from the --format values, which can be repeated
|
|
16
|
+
* or comma-separated.
|
|
17
|
+
*
|
|
18
|
+
* @param values Option values.
|
|
19
|
+
* @return Unique formats, the default when none are given.
|
|
20
|
+
* @throws {ValidationError} If a format is unknown.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseSignatureFormats(values: string[]): SignatureFormat[];
|
|
9
23
|
declare const _default: {
|
|
10
24
|
name: string;
|
|
11
25
|
usage: string;
|
|
12
26
|
summary: string;
|
|
13
27
|
help: string;
|
|
14
28
|
options: {
|
|
29
|
+
format: {
|
|
30
|
+
type: "string";
|
|
31
|
+
multiple: true;
|
|
32
|
+
};
|
|
15
33
|
force: {
|
|
16
34
|
type: "boolean";
|
|
17
35
|
};
|