@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
package/dist/file-selection.d.ts
CHANGED
|
@@ -82,3 +82,24 @@ export declare function isErrorCode(error: unknown, code: string): boolean;
|
|
|
82
82
|
* @throws {ValidationError} For selected symbolic links, which ZIP archives and WordPress.org SVN don't support.
|
|
83
83
|
*/
|
|
84
84
|
export declare function selectFiles(sourceDir: string, rules: FileRules): Promise<string[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Ignore a file that a command writes or reads, such as the checksums
|
|
87
|
+
* manifest, when it's inside the selected directory.
|
|
88
|
+
*
|
|
89
|
+
* @param rules Matcher from loadFileRules().
|
|
90
|
+
* @param sourceDir Selected directory.
|
|
91
|
+
* @param path Absolute file path.
|
|
92
|
+
* @return The same matcher.
|
|
93
|
+
*/
|
|
94
|
+
export declare function ignoreOwnFile(rules: FileRules, sourceDir: string, path: string): FileRules;
|
|
95
|
+
/**
|
|
96
|
+
* Ignore the signature files of every format that "wp-release sign" writes
|
|
97
|
+
* next to a file a command writes, when they're inside the selected
|
|
98
|
+
* directory.
|
|
99
|
+
*
|
|
100
|
+
* @param rules Matcher from loadFileRules().
|
|
101
|
+
* @param sourceDir Selected directory.
|
|
102
|
+
* @param path Absolute path of the signed file.
|
|
103
|
+
* @return The same matcher.
|
|
104
|
+
*/
|
|
105
|
+
export declare function ignoreOwnSignature(rules: FileRules, sourceDir: string, path: string): FileRules;
|
package/dist/file-selection.js
CHANGED
|
@@ -3,6 +3,7 @@ import { isAbsolute, join, posix, relative, resolve } from 'node:path';
|
|
|
3
3
|
import ignore from 'ignore';
|
|
4
4
|
import { ValidationError } from "./errors.js";
|
|
5
5
|
import { createGitRunner } from "./git.js";
|
|
6
|
+
import { SIGNATURE_FORMATS } from "./signing.js";
|
|
6
7
|
export const DISTIGNORE_FILENAME = '.distignore';
|
|
7
8
|
/**
|
|
8
9
|
* Version control metadata that is never released, at any depth. Without
|
|
@@ -227,3 +228,37 @@ async function findEntryFiles(sourceDir, path, entry, rules) {
|
|
|
227
228
|
}
|
|
228
229
|
return [];
|
|
229
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Ignore a file that a command writes or reads, such as the checksums
|
|
233
|
+
* manifest, when it's inside the selected directory.
|
|
234
|
+
*
|
|
235
|
+
* @param rules Matcher from loadFileRules().
|
|
236
|
+
* @param sourceDir Selected directory.
|
|
237
|
+
* @param path Absolute file path.
|
|
238
|
+
* @return The same matcher.
|
|
239
|
+
*/
|
|
240
|
+
export function ignoreOwnFile(rules, sourceDir, path) {
|
|
241
|
+
const relativePath = relative(sourceDir, path).split('\\').join('/');
|
|
242
|
+
const isInside = relativePath &&
|
|
243
|
+
'..' !== relativePath &&
|
|
244
|
+
!relativePath.startsWith('../') &&
|
|
245
|
+
!isAbsolute(relativePath);
|
|
246
|
+
if (isInside) {
|
|
247
|
+
// Escape the gitignore wildcards so that the pattern matches only this file.
|
|
248
|
+
rules.add(`/${relativePath.replace(/[\\*?[\]!#]/g, '\\$&')}`);
|
|
249
|
+
}
|
|
250
|
+
return rules;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Ignore the signature files of every format that "wp-release sign" writes
|
|
254
|
+
* next to a file a command writes, when they're inside the selected
|
|
255
|
+
* directory.
|
|
256
|
+
*
|
|
257
|
+
* @param rules Matcher from loadFileRules().
|
|
258
|
+
* @param sourceDir Selected directory.
|
|
259
|
+
* @param path Absolute path of the signed file.
|
|
260
|
+
* @return The same matcher.
|
|
261
|
+
*/
|
|
262
|
+
export function ignoreOwnSignature(rules, sourceDir, path) {
|
|
263
|
+
return Object.values(SIGNATURE_FORMATS).reduce((matcher, { extension }) => ignoreOwnFile(matcher, sourceDir, path + extension), rules);
|
|
264
|
+
}
|
package/dist/git-deploy.d.ts
CHANGED
|
@@ -28,6 +28,13 @@ export interface GitDeployInput {
|
|
|
28
28
|
excludeGitattributes?: boolean;
|
|
29
29
|
/** Commit message of the release. */
|
|
30
30
|
message?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Token for an HTTPS repository on the GitHub host, sent as an
|
|
33
|
+
* authorization header instead of in the URL. Defaults to GITHUB_TOKEN for
|
|
34
|
+
* a URL on github.com, or on the host of GITHUB_SERVER_URL, without
|
|
35
|
+
* credentials of its own.
|
|
36
|
+
*/
|
|
37
|
+
token?: string;
|
|
31
38
|
/** Run everything except the push. */
|
|
32
39
|
dryRun?: boolean;
|
|
33
40
|
}
|
|
@@ -43,6 +50,8 @@ export interface GitDeployOptions extends FileSelection {
|
|
|
43
50
|
splitPrefix: string | null;
|
|
44
51
|
sourceRef: string;
|
|
45
52
|
message: string | null;
|
|
53
|
+
/** Token sent as an authorization header to the repository. */
|
|
54
|
+
token: string | null;
|
|
46
55
|
dryRun: boolean;
|
|
47
56
|
}
|
|
48
57
|
export interface GitDeployResult {
|
|
@@ -70,6 +79,29 @@ export interface GitDeployResult {
|
|
|
70
79
|
* @return Whether the name can be used.
|
|
71
80
|
*/
|
|
72
81
|
export declare function isValidRefName(name: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Get GITHUB_TOKEN for an HTTPS repository URL on the GitHub host, like
|
|
84
|
+
* https://github.com/owner/repo.git, unless the URL has credentials.
|
|
85
|
+
*
|
|
86
|
+
* @param gitUrl Repository URL.
|
|
87
|
+
* @param env Environment variables.
|
|
88
|
+
* @return The token, or undefined for another URL or without one.
|
|
89
|
+
*/
|
|
90
|
+
export declare function getDefaultToken(gitUrl: string, env?: NodeJS.ProcessEnv): string | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Get the environment variables that make git send a token as the
|
|
93
|
+
* authorization header to a repository, like actions/checkout, so that the
|
|
94
|
+
* token stays out of the URL, the arguments and the repository config. An
|
|
95
|
+
* empty header first resets the headers that git is configured with, like
|
|
96
|
+
* the one that actions/checkout persists, since a second authorization
|
|
97
|
+
* header would fail.
|
|
98
|
+
*
|
|
99
|
+
* @param gitUrl Repository URL.
|
|
100
|
+
* @param token Token, or null for none.
|
|
101
|
+
* @param env Environment variables, for the existing GIT_CONFIG_COUNT.
|
|
102
|
+
* @return Environment variables for git.
|
|
103
|
+
*/
|
|
104
|
+
export declare function getGitAuthEnv(gitUrl: string, token: string | null, env?: NodeJS.ProcessEnv): Record<string, string>;
|
|
73
105
|
/**
|
|
74
106
|
* Apply the defaults to the Git deploy options and validate them.
|
|
75
107
|
*
|
package/dist/git-deploy.js
CHANGED
|
@@ -18,6 +18,54 @@ export function isValidRefName(name) {
|
|
|
18
18
|
return (/^[^\s~^:?*[\\]+$/.test(name) &&
|
|
19
19
|
!/(^[-/.]|\/\.|\.\.|\/\/|@\{|\.lock$|[/.]$)/.test(name));
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Get GITHUB_TOKEN for an HTTPS repository URL on the GitHub host, like
|
|
23
|
+
* https://github.com/owner/repo.git, unless the URL has credentials.
|
|
24
|
+
*
|
|
25
|
+
* @param gitUrl Repository URL.
|
|
26
|
+
* @param env Environment variables.
|
|
27
|
+
* @return The token, or undefined for another URL or without one.
|
|
28
|
+
*/
|
|
29
|
+
export function getDefaultToken(gitUrl, env = process.env) {
|
|
30
|
+
const url = URL.canParse(gitUrl) ? new URL(gitUrl) : undefined;
|
|
31
|
+
const hosts = [
|
|
32
|
+
'github.com',
|
|
33
|
+
URL.canParse(env.GITHUB_SERVER_URL ?? '')
|
|
34
|
+
? new URL(env.GITHUB_SERVER_URL ?? '').host
|
|
35
|
+
: '',
|
|
36
|
+
];
|
|
37
|
+
const isGitHub = 'https:' === url?.protocol &&
|
|
38
|
+
!url.username &&
|
|
39
|
+
hosts.includes(url.host);
|
|
40
|
+
return isGitHub ? env.GITHUB_TOKEN || undefined : undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the environment variables that make git send a token as the
|
|
44
|
+
* authorization header to a repository, like actions/checkout, so that the
|
|
45
|
+
* token stays out of the URL, the arguments and the repository config. An
|
|
46
|
+
* empty header first resets the headers that git is configured with, like
|
|
47
|
+
* the one that actions/checkout persists, since a second authorization
|
|
48
|
+
* header would fail.
|
|
49
|
+
*
|
|
50
|
+
* @param gitUrl Repository URL.
|
|
51
|
+
* @param token Token, or null for none.
|
|
52
|
+
* @param env Environment variables, for the existing GIT_CONFIG_COUNT.
|
|
53
|
+
* @return Environment variables for git.
|
|
54
|
+
*/
|
|
55
|
+
export function getGitAuthEnv(gitUrl, token, env = process.env) {
|
|
56
|
+
const count = Number(env.GIT_CONFIG_COUNT) || 0;
|
|
57
|
+
const key = token ? `http.${new URL(gitUrl).origin}/.extraheader` : '';
|
|
58
|
+
const credentials = Buffer.from(`x-access-token:${token}`).toString('base64');
|
|
59
|
+
return token
|
|
60
|
+
? {
|
|
61
|
+
GIT_CONFIG_COUNT: String(count + 2),
|
|
62
|
+
[`GIT_CONFIG_KEY_${count}`]: key,
|
|
63
|
+
[`GIT_CONFIG_VALUE_${count}`]: '',
|
|
64
|
+
[`GIT_CONFIG_KEY_${count + 1}`]: key,
|
|
65
|
+
[`GIT_CONFIG_VALUE_${count + 1}`]: `AUTHORIZATION: basic ${credentials}`,
|
|
66
|
+
}
|
|
67
|
+
: {};
|
|
68
|
+
}
|
|
21
69
|
/**
|
|
22
70
|
* Apply the defaults to the Git deploy options and validate them.
|
|
23
71
|
*
|
|
@@ -49,6 +97,7 @@ export function resolveGitDeployOptions(input = {}) {
|
|
|
49
97
|
splitPrefix: input.splitPrefix || null,
|
|
50
98
|
sourceRef: input.sourceRef || 'HEAD',
|
|
51
99
|
message: input.message || null,
|
|
100
|
+
token: input.token || getDefaultToken(input.gitUrl) || null,
|
|
52
101
|
dryRun: Boolean(input.dryRun),
|
|
53
102
|
...resolveFileSelection({
|
|
54
103
|
cwd,
|
|
@@ -415,7 +464,14 @@ export class GitDeploy {
|
|
|
415
464
|
async git(input) {
|
|
416
465
|
const cwd = await this.getRepoRoot();
|
|
417
466
|
this.logger.debug(redactUrls(`git ${input.args.join(' ')}`));
|
|
418
|
-
const { stdout } = await this.runner({
|
|
467
|
+
const { stdout } = await this.runner({
|
|
468
|
+
...input,
|
|
469
|
+
cwd,
|
|
470
|
+
env: {
|
|
471
|
+
...getGitAuthEnv(this.options.gitUrl, this.options.token),
|
|
472
|
+
...input.env,
|
|
473
|
+
},
|
|
474
|
+
});
|
|
419
475
|
return stdout.trim();
|
|
420
476
|
}
|
|
421
477
|
}
|
package/dist/git.d.ts
CHANGED
|
@@ -26,6 +26,23 @@ export type GitRunner = (input: GitCommandInput) => Promise<GitCommandOutput>;
|
|
|
26
26
|
* @return Text with the user info of URLs replaced by ***.
|
|
27
27
|
*/
|
|
28
28
|
export declare function redactUrls(text: string): string;
|
|
29
|
+
/** Host and path of a repository URL. */
|
|
30
|
+
export interface RepositoryLocation {
|
|
31
|
+
/** Host with the port, like github.com or git.example.test:8443. */
|
|
32
|
+
host: string;
|
|
33
|
+
/** Path without the leading slash and the .git suffix, like owner/repo or group/subgroup/project. */
|
|
34
|
+
path: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the host and path of a remote repository URL, like github.com and
|
|
38
|
+
* owner/repo for https://github.com/owner/repo.git or
|
|
39
|
+
* git@github.com:owner/repo.git, for steps that call the API of the forge
|
|
40
|
+
* that hosts it. Credentials in the URL aren't part of either.
|
|
41
|
+
*
|
|
42
|
+
* @param url Repository URL: HTTP(S), SSH or git, or the scp-like SSH form.
|
|
43
|
+
* @return Host and path, or undefined for a local repository or another URL.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseRepositoryUrl(url: string): RepositoryLocation | undefined;
|
|
29
46
|
/**
|
|
30
47
|
* Failed git command.
|
|
31
48
|
*/
|
package/dist/git.js
CHANGED
|
@@ -9,6 +9,29 @@ import { spawn } from 'node:child_process';
|
|
|
9
9
|
export function redactUrls(text) {
|
|
10
10
|
return text.replace(/(\w+:\/\/)[^/@\s]+@/g, '$1***@');
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Get the host and path of a remote repository URL, like github.com and
|
|
14
|
+
* owner/repo for https://github.com/owner/repo.git or
|
|
15
|
+
* git@github.com:owner/repo.git, for steps that call the API of the forge
|
|
16
|
+
* that hosts it. Credentials in the URL aren't part of either.
|
|
17
|
+
*
|
|
18
|
+
* @param url Repository URL: HTTP(S), SSH or git, or the scp-like SSH form.
|
|
19
|
+
* @return Host and path, or undefined for a local repository or another URL.
|
|
20
|
+
*/
|
|
21
|
+
export function parseRepositoryUrl(url) {
|
|
22
|
+
const scpLike = url.match(/^(?:[^@/:]+@)?([^/:\\]{2,}):(?!\/\/)(.+)$/);
|
|
23
|
+
const parsed = !scpLike && URL.canParse(url) ? new URL(url) : undefined;
|
|
24
|
+
const isRemote = ['http:', 'https:', 'ssh:', 'git:'].includes(parsed?.protocol ?? '');
|
|
25
|
+
const location = scpLike
|
|
26
|
+
? { host: scpLike[1] ?? '', path: scpLike[2] ?? '' }
|
|
27
|
+
: { host: parsed?.host ?? '', path: parsed?.pathname ?? '' };
|
|
28
|
+
const path = location.path
|
|
29
|
+
.replace(/^\/+|\/+$/g, '')
|
|
30
|
+
.replace(/\.git$/, '');
|
|
31
|
+
return (scpLike || isRemote) && location.host && path
|
|
32
|
+
? { host: location.host, path }
|
|
33
|
+
: undefined;
|
|
34
|
+
}
|
|
12
35
|
/**
|
|
13
36
|
* Failed git command.
|
|
14
37
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ export { DISTIGNORE_FILENAME, parseExclude, resolveFileSelection, loadFileRules,
|
|
|
9
9
|
export { FILENAME_FORMAT, formatFilename } from './filename.ts';
|
|
10
10
|
export { CHECKSUMS_EXTENSION, CHECKSUM_ALGORITHMS, hashFile, hashFiles, createChecksums, writeChecksums, readChecksums, parseChecksums, compareChecksums, verifyChecksums, } from './checksums.ts';
|
|
11
11
|
export { HEADER_BYTES, PLUGIN_HEADERS, THEME_HEADERS, README_HEADERS, README_FILENAMES, parseFileHeaders, parseReadmeHeaders, readFileStart, findFileHeaderLine, findReadmeHeaderLine, findMainPluginFile, readPackageMeta, } from './package-meta.ts';
|
|
12
|
-
export { SIGNATURE_EXTENSION, SIGNING_KEY_ENV, parseSigningKey, parsePublicKey, generateSigningKeyPair, getPublicKey, getFileDigest, signFile, writeSignature, verifyFileSignature, } from './signing.ts';
|
|
12
|
+
export { DEFAULT_SIGNATURE_FORMAT, SIGNATURE_EXTENSION, SIGNATURE_FORMATS, SIGNING_KEY_ENV, parseSigningKey, parsePublicKey, generateSigningKeyPair, getPublicKey, getPublicKeys, getFileDigest, getSignaturePath, isSignatureFormat, signFile, writeSignature, verifyFileSignature, } from './signing.ts';
|
|
13
|
+
export type { SignatureFormat, SignatureFormatHandler } from './signing.ts';
|
|
14
|
+
export { MINISIGN_EXTENSION, createMinisignSignature, getMinisignPublicKey, parseMinisignPublicKey, verifyMinisignSignature, } from './minisign.ts';
|
|
15
|
+
export { SSH_SIGNATURE_EXTENSION, SSH_SIGNATURE_NAMESPACE, createSshSignature, getSshPublicKey, parseSshPublicKey, verifySshSignature, } from './ssh-signature.ts';
|
|
13
16
|
export { ZIP_MTIME, ZIP_FILE_MODE, createZip } from './zip.ts';
|
|
14
17
|
export { isUrl, downloadFile } from './download.ts';
|
|
15
18
|
export { readZipEntries, getZipEntryErrors, extractZip } from './unzip.ts';
|
|
@@ -20,9 +23,14 @@ export { defineConfig, packageJsonVersion, composerJsonVersion, wordpressPluginV
|
|
|
20
23
|
export { Svn, SvnError, createSvnRunner, parseStatus, toSvnPath, } from './svn.ts';
|
|
21
24
|
export { syncDirectory, copyFileIfChanged } from './sync.ts';
|
|
22
25
|
export { ASSET_MIME_TYPES, SvnDeploy } from './svn-deploy.ts';
|
|
23
|
-
export { GitError, createGitRunner, redactUrls } from './git.ts';
|
|
24
|
-
export { GitDeploy, isValidRefName, resolveGitDeployOptions, } from './git-deploy.ts';
|
|
26
|
+
export { GitError, createGitRunner, parseRepositoryUrl, redactUrls, } from './git.ts';
|
|
27
|
+
export { GitDeploy, getDefaultToken, getGitAuthEnv, isValidRefName, resolveGitDeployOptions, } from './git-deploy.ts';
|
|
25
28
|
export { getGitDeployInputFromArgs } from './commands/deploy-git.ts';
|
|
29
|
+
export { getDeployPackages, getGitDeploys, getPackageFiles, getSvnDeploys, } from './package-deploy.ts';
|
|
30
|
+
export { zipPackage } from './package-zip.ts';
|
|
31
|
+
export type { ZipPackageInput, ZipPackageResult } from './package-zip.ts';
|
|
32
|
+
export type { PackageDeploy, PackageDeployFiles, PackageDeployOptions, PackageFileSelection, PackageDeployPlanItem, PackageDeployRelease, } from './package-deploy.ts';
|
|
33
|
+
export type { PackageDeployOutcome } from './commands/package-deploys.ts';
|
|
26
34
|
export type { CliIo, CommandResults } from './cli.ts';
|
|
27
35
|
export type { ChecksumsResult } from './commands/checksums.ts';
|
|
28
36
|
export type { SignResult } from './commands/sign.ts';
|
|
@@ -43,10 +51,10 @@ export type { ExtractZipInput, ZipEntryInfo, ZipEntryType } from './unzip.ts';
|
|
|
43
51
|
export type { FindVersionMismatchesInput, GitTagInput, VersionCheckResult, VersionMismatch, } from './version-check.ts';
|
|
44
52
|
export type { Changeset, ChangesetBump, ChangesetPackages, ChangesetConfig, ChangesetPackageType, ChangesetPackage, PackageRelease, VersionedRelease, ChangesetReleasePlan, } from './changesets.ts';
|
|
45
53
|
export type { ChangesetRepository, ChangesetReleaseOptions, ChangesetAddOptions, ChangesetVersionOptions, ChangesetTagOptions, ChangesetStatusOptions, ChangesetStatusResult, ChangesetVersionInput, VersionChangesetsResult, ChangesetTagInput, ChangesetTagResult, } from './changeset-release.ts';
|
|
46
|
-
export type { WpReleaseConfig, ChangesetPackageGroup, PackageVersionConfig, PackageVersionSource, PackageVersionTarget, PackageIdSource, NextVersionInput, ReleaseCommit, ReleaseNotesInput, ChangelogEntryInput, DependentsChangelogInput, DependentsConfig, PackageJsonVersionOptions, ComposerJsonVersionOptions, WordPressVersionFileOptions, GitTagVersionOptions, PhpConstantVersionOptions, LoadChangesetConfigInput, } from './changeset-config.ts';
|
|
54
|
+
export type { WpReleaseConfig, ChangesetPackageGroup, PackageFilesConfig, PackageDeployConfig, GitDeployTarget, SvnDeployTarget, DeployTemplate, DeployTargetInput, DeployPackage, PackageVersionConfig, PackageVersionSource, PackageVersionTarget, PackageIdSource, NextVersionInput, ReleaseCommit, ReleaseNotesInput, ChangelogEntryInput, DependentsChangelogInput, DependentsConfig, PackageJsonVersionOptions, ComposerJsonVersionOptions, WordPressVersionFileOptions, GitTagVersionOptions, PhpConstantVersionOptions, LoadChangesetConfigInput, } from './changeset-config.ts';
|
|
47
55
|
export type { SvnCheckoutInput, SvnCommandInput, SvnCommandOutput, SvnCommitInput, SvnCopyInput, SvnDepth, SvnOptions, SvnPathsInput, SvnPropsetInput, SvnRunner, SvnStatusEntry, SvnStatusType, SvnUpdateInput, } from './svn.ts';
|
|
48
56
|
export type { SyncDirectoryInput, SyncResult } from './sync.ts';
|
|
49
57
|
export type { SummaryContext } from './summary.ts';
|
|
50
58
|
export type { CheckoutPath, DeployResult } from './svn-deploy.ts';
|
|
51
|
-
export type { GitCommandInput, GitCommandOutput, GitRunner } from './git.ts';
|
|
59
|
+
export type { GitCommandInput, GitCommandOutput, GitRunner, RepositoryLocation, } from './git.ts';
|
|
52
60
|
export type { GitDeployInput, GitDeployOptions, GitDeployResult, } from './git-deploy.ts';
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,9 @@ export { DISTIGNORE_FILENAME, parseExclude, resolveFileSelection, loadFileRules,
|
|
|
9
9
|
export { FILENAME_FORMAT, formatFilename } from "./filename.js";
|
|
10
10
|
export { CHECKSUMS_EXTENSION, CHECKSUM_ALGORITHMS, hashFile, hashFiles, createChecksums, writeChecksums, readChecksums, parseChecksums, compareChecksums, verifyChecksums, } from "./checksums.js";
|
|
11
11
|
export { HEADER_BYTES, PLUGIN_HEADERS, THEME_HEADERS, README_HEADERS, README_FILENAMES, parseFileHeaders, parseReadmeHeaders, readFileStart, findFileHeaderLine, findReadmeHeaderLine, findMainPluginFile, readPackageMeta, } from "./package-meta.js";
|
|
12
|
-
export { SIGNATURE_EXTENSION, SIGNING_KEY_ENV, parseSigningKey, parsePublicKey, generateSigningKeyPair, getPublicKey, getFileDigest, signFile, writeSignature, verifyFileSignature, } from "./signing.js";
|
|
12
|
+
export { DEFAULT_SIGNATURE_FORMAT, SIGNATURE_EXTENSION, SIGNATURE_FORMATS, SIGNING_KEY_ENV, parseSigningKey, parsePublicKey, generateSigningKeyPair, getPublicKey, getPublicKeys, getFileDigest, getSignaturePath, isSignatureFormat, signFile, writeSignature, verifyFileSignature, } from "./signing.js";
|
|
13
|
+
export { MINISIGN_EXTENSION, createMinisignSignature, getMinisignPublicKey, parseMinisignPublicKey, verifyMinisignSignature, } from "./minisign.js";
|
|
14
|
+
export { SSH_SIGNATURE_EXTENSION, SSH_SIGNATURE_NAMESPACE, createSshSignature, getSshPublicKey, parseSshPublicKey, verifySshSignature, } from "./ssh-signature.js";
|
|
13
15
|
export { ZIP_MTIME, ZIP_FILE_MODE, createZip } from "./zip.js";
|
|
14
16
|
export { isUrl, downloadFile } from "./download.js";
|
|
15
17
|
export { readZipEntries, getZipEntryErrors, extractZip } from "./unzip.js";
|
|
@@ -20,6 +22,8 @@ export { defineConfig, packageJsonVersion, composerJsonVersion, wordpressPluginV
|
|
|
20
22
|
export { Svn, SvnError, createSvnRunner, parseStatus, toSvnPath, } from "./svn.js";
|
|
21
23
|
export { syncDirectory, copyFileIfChanged } from "./sync.js";
|
|
22
24
|
export { ASSET_MIME_TYPES, SvnDeploy } from "./svn-deploy.js";
|
|
23
|
-
export { GitError, createGitRunner, redactUrls } from "./git.js";
|
|
24
|
-
export { GitDeploy, isValidRefName, resolveGitDeployOptions, } from "./git-deploy.js";
|
|
25
|
+
export { GitError, createGitRunner, parseRepositoryUrl, redactUrls, } from "./git.js";
|
|
26
|
+
export { GitDeploy, getDefaultToken, getGitAuthEnv, isValidRefName, resolveGitDeployOptions, } from "./git-deploy.js";
|
|
25
27
|
export { getGitDeployInputFromArgs } from "./commands/deploy-git.js";
|
|
28
|
+
export { getDeployPackages, getGitDeploys, getPackageFiles, getSvnDeploys, } from "./package-deploy.js";
|
|
29
|
+
export { zipPackage } from "./package-zip.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { KeyObject } from 'node:crypto';
|
|
2
|
+
export declare const MINISIGN_EXTENSION = ".minisig";
|
|
3
|
+
/**
|
|
4
|
+
* Get the minisign public key of a key, the base64 line that `minisign -P`
|
|
5
|
+
* takes and that the second line of a minisign .pub file holds.
|
|
6
|
+
*
|
|
7
|
+
* @param key Private or public key.
|
|
8
|
+
* @return Base64 minisign public key.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getMinisignPublicKey(key: KeyObject): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the raw public key from a minisign public key, the base64 line or the
|
|
13
|
+
* whole two-line .pub file.
|
|
14
|
+
*
|
|
15
|
+
* @param encoded Minisign public key.
|
|
16
|
+
* @return Public key bytes, or null when it isn't a minisign public key.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseMinisignPublicKey(encoded: string): Buffer | null;
|
|
19
|
+
/**
|
|
20
|
+
* Create a minisign signature of a file: an Ed25519 signature of its
|
|
21
|
+
* BLAKE2b-512 digest, and a global signature that also covers the trusted
|
|
22
|
+
* comment with the signing time and file name.
|
|
23
|
+
*
|
|
24
|
+
* @param path File path.
|
|
25
|
+
* @param privateKey Private key.
|
|
26
|
+
* @return Contents of the .minisig file.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createMinisignSignature(path: string, privateKey: KeyObject): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Check a file against a minisign signature file, including the global
|
|
31
|
+
* signature of the trusted comment. Both the BLAKE2b-512 prehashed (ED)
|
|
32
|
+
* and the legacy (Ed) signatures of minisign are accepted. The key ID isn't
|
|
33
|
+
* compared, since it only tells minisign which key to use, so signatures of
|
|
34
|
+
* keys that minisign generated with a random ID are accepted too.
|
|
35
|
+
*
|
|
36
|
+
* @param path File path.
|
|
37
|
+
* @param signaturePath Signature file path.
|
|
38
|
+
* @param publicKey Public key.
|
|
39
|
+
* @return Whether the signature matches.
|
|
40
|
+
*/
|
|
41
|
+
export declare function verifyMinisignSignature(path: string, signaturePath: string, publicKey: KeyObject): Promise<boolean>;
|
package/dist/minisign.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createHash, sign, verify } from 'node:crypto';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { basename } from 'node:path';
|
|
4
|
+
import { PUBLIC_KEY_BYTES, digestFile, getRawPublicKey } from "./ed25519.js";
|
|
5
|
+
export const MINISIGN_EXTENSION = '.minisig';
|
|
6
|
+
// Algorithm of a public key, and of a signature of the BLAKE2b-512 digest.
|
|
7
|
+
const KEY_ALGORITHM = 'Ed';
|
|
8
|
+
const HASHED_ALGORITHM = 'ED';
|
|
9
|
+
const KEY_ID_BYTES = 8;
|
|
10
|
+
const SIGNATURE_BYTES = 64;
|
|
11
|
+
const UNTRUSTED_PREFIX = 'untrusted comment: ';
|
|
12
|
+
const TRUSTED_PREFIX = 'trusted comment: ';
|
|
13
|
+
/**
|
|
14
|
+
* Get the minisign key ID of a public key. minisign picks a random ID when
|
|
15
|
+
* it generates a key, so wp-release derives one from the public key instead,
|
|
16
|
+
* which keeps it the same for every signature of the key.
|
|
17
|
+
*
|
|
18
|
+
* @param publicKey Public key bytes.
|
|
19
|
+
* @return 8-byte key ID.
|
|
20
|
+
*/
|
|
21
|
+
function getKeyId(publicKey) {
|
|
22
|
+
return createHash('blake2b512')
|
|
23
|
+
.update(publicKey)
|
|
24
|
+
.digest()
|
|
25
|
+
.subarray(0, KEY_ID_BYTES);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format a key ID like minisign prints it: the hex of the little-endian
|
|
29
|
+
* 64-bit number.
|
|
30
|
+
*
|
|
31
|
+
* @param keyId Key ID bytes.
|
|
32
|
+
* @return Uppercase hex key ID.
|
|
33
|
+
*/
|
|
34
|
+
function formatKeyId(keyId) {
|
|
35
|
+
return Buffer.from(keyId).reverse().toString('hex').toUpperCase();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the minisign public key of a key, the base64 line that `minisign -P`
|
|
39
|
+
* takes and that the second line of a minisign .pub file holds.
|
|
40
|
+
*
|
|
41
|
+
* @param key Private or public key.
|
|
42
|
+
* @return Base64 minisign public key.
|
|
43
|
+
*/
|
|
44
|
+
export function getMinisignPublicKey(key) {
|
|
45
|
+
const publicKey = getRawPublicKey(key);
|
|
46
|
+
return Buffer.concat([
|
|
47
|
+
Buffer.from(KEY_ALGORITHM),
|
|
48
|
+
getKeyId(publicKey),
|
|
49
|
+
publicKey,
|
|
50
|
+
]).toString('base64');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the raw public key from a minisign public key, the base64 line or the
|
|
54
|
+
* whole two-line .pub file.
|
|
55
|
+
*
|
|
56
|
+
* @param encoded Minisign public key.
|
|
57
|
+
* @return Public key bytes, or null when it isn't a minisign public key.
|
|
58
|
+
*/
|
|
59
|
+
export function parseMinisignPublicKey(encoded) {
|
|
60
|
+
const line = encoded
|
|
61
|
+
.trim()
|
|
62
|
+
.split('\n')
|
|
63
|
+
.map((text) => text.trim())
|
|
64
|
+
.filter((text) => text && !text.startsWith(UNTRUSTED_PREFIX));
|
|
65
|
+
const bytes = Buffer.from(line.join(''), 'base64');
|
|
66
|
+
const isMinisign = 1 === line.length &&
|
|
67
|
+
2 + KEY_ID_BYTES + PUBLIC_KEY_BYTES === bytes.length &&
|
|
68
|
+
KEY_ALGORITHM === bytes.subarray(0, 2).toString();
|
|
69
|
+
return isMinisign ? bytes.subarray(2 + KEY_ID_BYTES) : null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a minisign signature of a file: an Ed25519 signature of its
|
|
73
|
+
* BLAKE2b-512 digest, and a global signature that also covers the trusted
|
|
74
|
+
* comment with the signing time and file name.
|
|
75
|
+
*
|
|
76
|
+
* @param path File path.
|
|
77
|
+
* @param privateKey Private key.
|
|
78
|
+
* @return Contents of the .minisig file.
|
|
79
|
+
*/
|
|
80
|
+
export async function createMinisignSignature(path, privateKey) {
|
|
81
|
+
const keyId = getKeyId(getRawPublicKey(privateKey));
|
|
82
|
+
const signature = sign(null, await digestFile(path, 'blake2b512'), privateKey);
|
|
83
|
+
const name = basename(path).replace(/[\r\n]/g, ' ');
|
|
84
|
+
const trustedComment = `timestamp:${Math.floor(Date.now() / 1000)}\tfile:${name}\thashed`;
|
|
85
|
+
const globalSignature = sign(null, Buffer.concat([signature, Buffer.from(trustedComment)]), privateKey);
|
|
86
|
+
return [
|
|
87
|
+
`${UNTRUSTED_PREFIX}signature from wp-release key ${formatKeyId(keyId)}`,
|
|
88
|
+
Buffer.concat([
|
|
89
|
+
Buffer.from(HASHED_ALGORITHM),
|
|
90
|
+
keyId,
|
|
91
|
+
signature,
|
|
92
|
+
]).toString('base64'),
|
|
93
|
+
`${TRUSTED_PREFIX}${trustedComment}`,
|
|
94
|
+
globalSignature.toString('base64'),
|
|
95
|
+
'',
|
|
96
|
+
].join('\n');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check a file against a minisign signature file, including the global
|
|
100
|
+
* signature of the trusted comment. Both the BLAKE2b-512 prehashed (ED)
|
|
101
|
+
* and the legacy (Ed) signatures of minisign are accepted. The key ID isn't
|
|
102
|
+
* compared, since it only tells minisign which key to use, so signatures of
|
|
103
|
+
* keys that minisign generated with a random ID are accepted too.
|
|
104
|
+
*
|
|
105
|
+
* @param path File path.
|
|
106
|
+
* @param signaturePath Signature file path.
|
|
107
|
+
* @param publicKey Public key.
|
|
108
|
+
* @return Whether the signature matches.
|
|
109
|
+
*/
|
|
110
|
+
export async function verifyMinisignSignature(path, signaturePath, publicKey) {
|
|
111
|
+
const [, encoded = '', trusted = '', encodedGlobal = ''] = (await readFile(signaturePath, 'utf8'))
|
|
112
|
+
.split('\n')
|
|
113
|
+
.map((line) => line.trim());
|
|
114
|
+
const bytes = Buffer.from(encoded, 'base64');
|
|
115
|
+
const algorithm = bytes.subarray(0, 2).toString();
|
|
116
|
+
const signature = bytes.subarray(2 + KEY_ID_BYTES);
|
|
117
|
+
const isValidShape = 2 + KEY_ID_BYTES + SIGNATURE_BYTES === bytes.length &&
|
|
118
|
+
[HASHED_ALGORITHM, KEY_ALGORITHM].includes(algorithm) &&
|
|
119
|
+
trusted.startsWith(TRUSTED_PREFIX);
|
|
120
|
+
return (isValidShape &&
|
|
121
|
+
verify(null, HASHED_ALGORITHM === algorithm
|
|
122
|
+
? await digestFile(path, 'blake2b512')
|
|
123
|
+
: await readFile(path), publicKey, signature) &&
|
|
124
|
+
verify(null, Buffer.concat([
|
|
125
|
+
signature,
|
|
126
|
+
Buffer.from(trusted.slice(TRUSTED_PREFIX.length)),
|
|
127
|
+
]), publicKey, Buffer.from(encodedGlobal, 'base64')));
|
|
128
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { DeployPackage } from './changeset-config.ts';
|
|
2
|
+
import type { DeployInput } from './deploy-options.ts';
|
|
3
|
+
import type { GitDeployInput } from './git-deploy.ts';
|
|
4
|
+
import type { GitRunner } from './git.ts';
|
|
5
|
+
export interface PackageDeployOptions {
|
|
6
|
+
/** Repository root with the wp-release config. */
|
|
7
|
+
cwd: string;
|
|
8
|
+
/** Config file, instead of the conventional one at the root. */
|
|
9
|
+
configFile?: string;
|
|
10
|
+
/** Tag format that replaces the tagFormat of the config. */
|
|
11
|
+
tagFormat?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Ref to deploy: a package release tag, like refs/tags/plugins/alpha/1.2.0,
|
|
14
|
+
* or a branch, like refs/heads/main. A name without refs/ is a release tag
|
|
15
|
+
* when it matches the tag format of a package, otherwise a branch.
|
|
16
|
+
*/
|
|
17
|
+
ref: string;
|
|
18
|
+
/** Deploy only these packages, by identifier or path under the root. */
|
|
19
|
+
packages?: string[];
|
|
20
|
+
/** Run everything except the writes. */
|
|
21
|
+
dryRun?: boolean;
|
|
22
|
+
/** Git runner, spawning git by default. */
|
|
23
|
+
git?: GitRunner;
|
|
24
|
+
}
|
|
25
|
+
/** The release of a package that a ref deploys. */
|
|
26
|
+
export interface PackageDeployRelease {
|
|
27
|
+
/** Released version, for a release tag. */
|
|
28
|
+
version?: string;
|
|
29
|
+
/** Deployed branch, for a branch. */
|
|
30
|
+
branch?: string;
|
|
31
|
+
}
|
|
32
|
+
/** One deploy of a package to one of its targets. */
|
|
33
|
+
export interface PackageDeploy<Input> {
|
|
34
|
+
package: DeployPackage;
|
|
35
|
+
release: PackageDeployRelease;
|
|
36
|
+
/** Repository or WordPress.org plugin of the target, with credentials redacted. */
|
|
37
|
+
target: string;
|
|
38
|
+
/** Tag or branch that the deploy writes in the target. */
|
|
39
|
+
targetRef: string;
|
|
40
|
+
/** Host of a remote target repository, like github.com. */
|
|
41
|
+
targetHost?: string;
|
|
42
|
+
/** Path of a remote target repository on its host, like owner/repo. */
|
|
43
|
+
targetPath?: string;
|
|
44
|
+
/** Package, target and ref, with credentials redacted, for logs. */
|
|
45
|
+
label: string;
|
|
46
|
+
/** Options of the deploy. */
|
|
47
|
+
input: Input;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the Git deploys of the configured packages that a ref releases: every
|
|
51
|
+
* Git target of the package of a release tag that releases tags, or of every
|
|
52
|
+
* package with a Git target that releases the branch.
|
|
53
|
+
*
|
|
54
|
+
* @param options Repository, ref and package selection.
|
|
55
|
+
* @return Deploys in the configured package and target order.
|
|
56
|
+
* @throws {ValidationError} Without a config, or for an invalid one or an unknown package.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getGitDeploys(options: PackageDeployOptions): Promise<PackageDeploy<GitDeployInput>[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Get the WordPress.org SVN deploys of the configured package that a release
|
|
61
|
+
* tag releases. A stable release syncs trunk/, the tag and the assets, and a
|
|
62
|
+
* pre-release only creates its tag. Branches aren't deployed to SVN.
|
|
63
|
+
*
|
|
64
|
+
* @param options Repository, ref and package selection.
|
|
65
|
+
* @return Deploys in the configured target order.
|
|
66
|
+
* @throws {ValidationError} Without a config, or for an invalid one or an unknown package.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getSvnDeploys(options: PackageDeployOptions): Promise<PackageDeploy<DeployInput>[]>;
|
|
69
|
+
/** A package with deploy targets and the files that its deploys ship. */
|
|
70
|
+
export interface PackageDeployFiles extends DeployPackage {
|
|
71
|
+
/** File selection of the package, for resolveFileSelection(). */
|
|
72
|
+
files: PackageFileSelection;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the packages with deploy targets and the files that their deploys
|
|
76
|
+
* ship, for example to build a ZIP with the same files.
|
|
77
|
+
*
|
|
78
|
+
* @param options Repository root and config file.
|
|
79
|
+
* @param options.cwd Repository root with the wp-release config.
|
|
80
|
+
* @param options.configFile Config file, instead of the conventional one at the root.
|
|
81
|
+
* @return Packages in the configured order.
|
|
82
|
+
* @throws {ValidationError} Without a config, or for an invalid one.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getDeployPackages(options: {
|
|
85
|
+
cwd: string;
|
|
86
|
+
configFile?: string;
|
|
87
|
+
}): Promise<PackageDeployFiles[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Get a configured package with the files that its releases ship, from the
|
|
90
|
+
* files config of its package group, which its deploys use too, for example
|
|
91
|
+
* to build its ZIP with the same files. Any package of the config works, with
|
|
92
|
+
* or without a version or deploy targets.
|
|
93
|
+
*
|
|
94
|
+
* @param options Repository root, config file and package.
|
|
95
|
+
* @param options.cwd Repository root with the wp-release config.
|
|
96
|
+
* @param options.configFile Config file, instead of the conventional one at the root.
|
|
97
|
+
* @param options.package Package identifier or path under the configured root.
|
|
98
|
+
* @return The package and its file selection.
|
|
99
|
+
* @throws {ValidationError} Without a config, for an invalid one or an unknown package.
|
|
100
|
+
*/
|
|
101
|
+
export declare function getPackageFiles(options: {
|
|
102
|
+
cwd: string;
|
|
103
|
+
configFile?: string;
|
|
104
|
+
package: string;
|
|
105
|
+
}): Promise<PackageDeployFiles>;
|
|
106
|
+
/** Ignore file and patterns that select the files of a package. */
|
|
107
|
+
export interface PackageFileSelection {
|
|
108
|
+
/** Absolute ignore file path, or false to not read one. */
|
|
109
|
+
distignore?: string | false;
|
|
110
|
+
/** Gitignore-style patterns relative to the package directory. */
|
|
111
|
+
exclude?: string[];
|
|
112
|
+
}
|
|
113
|
+
/** The deploys of one package in a deploy plan. */
|
|
114
|
+
export interface PackageDeployPlanItem extends PackageDeployRelease {
|
|
115
|
+
package: string;
|
|
116
|
+
/** Targets with the tag or branch that each deploy writes. */
|
|
117
|
+
targets: Array<{
|
|
118
|
+
target: string;
|
|
119
|
+
ref: string;
|
|
120
|
+
/** Host of a remote target repository. */
|
|
121
|
+
host?: string;
|
|
122
|
+
/** Path of a remote target repository on its host. */
|
|
123
|
+
path?: string;
|
|
124
|
+
}>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Group deploys by package, for a preview of what a ref deploys or a CI
|
|
128
|
+
* matrix with a job for each package.
|
|
129
|
+
*
|
|
130
|
+
* @param deploys Deploys from getGitDeploys() or getSvnDeploys().
|
|
131
|
+
* @return One item for each package, in the deploy order.
|
|
132
|
+
*/
|
|
133
|
+
export declare function getDeployPlan(deploys: PackageDeploy<unknown>[]): PackageDeployPlanItem[];
|