@wpelevator/wp-release 0.13.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 +67 -20
- package/dist/changeset-config.d.ts +8 -6
- package/dist/changeset-config.js +7 -5
- package/dist/changeset-packages.d.ts +12 -2
- package/dist/changeset-packages.js +13 -1
- package/dist/changeset-release.d.ts +5 -2
- package/dist/changeset-release.js +12 -6
- package/dist/cli.js +33 -9
- package/dist/commands/args.d.ts +0 -21
- package/dist/commands/args.js +1 -35
- package/dist/commands/changeset-add.d.ts +1 -1
- package/dist/commands/changeset-add.js +3 -2
- package/dist/commands/changeset-status.d.ts +1 -1
- package/dist/commands/changeset-status.js +2 -1
- package/dist/commands/changeset-tag.d.ts +1 -1
- package/dist/commands/changeset-tag.js +4 -2
- package/dist/commands/changeset-version.d.ts +1 -1
- package/dist/commands/changeset-version.js +2 -1
- package/dist/commands/checksums.js +2 -2
- package/dist/commands/command.d.ts +2 -0
- package/dist/commands/deploy-git.d.ts +1 -1
- package/dist/commands/deploy-git.js +2 -1
- package/dist/commands/deploy-svn.d.ts +1 -1
- package/dist/commands/deploy-svn.js +2 -1
- package/dist/commands/keygen.d.ts +3 -0
- package/dist/commands/keygen.js +6 -1
- package/dist/commands/package-deploys.d.ts +8 -0
- package/dist/commands/package-deploys.js +5 -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.d.ts +17 -0
- package/dist/git.js +23 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +6 -3
- package/dist/minisign.d.ts +41 -0
- package/dist/minisign.js +128 -0
- package/dist/package-deploy.d.ts +28 -0
- package/dist/package-deploy.js +41 -6
- package/dist/package-zip.d.ts +52 -0
- package/dist/package-zip.js +78 -0
- package/dist/release-repository.d.ts +4 -3
- package/dist/release-repository.js +5 -4
- 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 +21 -12
- package/dist/tag-format.js +25 -39
- package/dist/version-files.d.ts +6 -7
- package/dist/version-files.js +10 -11
- package/package.json +2 -2
package/dist/commands/zip.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import type { ZipPackageResult } from '../package-zip.ts';
|
|
1
2
|
import type { CommandOutcome } from './command.ts';
|
|
2
3
|
/** Result of the zip command. */
|
|
3
|
-
export interface ZipResult {
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
|
|
4
|
+
export interface ZipResult extends ZipPackageResult {
|
|
5
|
+
/** Plugin or theme slug. */
|
|
6
|
+
slug: string;
|
|
7
|
+
/** Version in the filename and the checksums manifest, null when it's unknown. */
|
|
8
|
+
version: string | null;
|
|
9
|
+
/** Zipped package, with --package. */
|
|
10
|
+
package?: string;
|
|
10
11
|
}
|
|
11
12
|
declare const _default: {
|
|
12
13
|
name: string;
|
|
@@ -14,6 +15,9 @@ declare const _default: {
|
|
|
14
15
|
summary: string;
|
|
15
16
|
help: string;
|
|
16
17
|
options: {
|
|
18
|
+
package: {
|
|
19
|
+
type: "string";
|
|
20
|
+
};
|
|
17
21
|
checksums: {
|
|
18
22
|
type: "boolean";
|
|
19
23
|
};
|
|
@@ -39,6 +43,6 @@ declare const _default: {
|
|
|
39
43
|
type: "string";
|
|
40
44
|
};
|
|
41
45
|
};
|
|
42
|
-
run({ values, positionals, cwd, logger, }: import("./command.ts").CommandContext): Promise<CommandOutcome<ZipResult>>;
|
|
46
|
+
run({ values, positionals, cwd, configFile, logger, }: import("./command.ts").CommandContext): Promise<CommandOutcome<ZipResult>>;
|
|
43
47
|
};
|
|
44
48
|
export default _default;
|
package/dist/commands/zip.js
CHANGED
|
@@ -1,49 +1,122 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
1
|
import { basename, resolve } from 'node:path';
|
|
3
|
-
import { CHECKSUMS_EXTENSION, createChecksums, writeChecksums, } from "../checksums.js";
|
|
4
2
|
import { ValidationError } from "../errors.js";
|
|
5
|
-
import {
|
|
3
|
+
import { resolveFileSelection } from "../file-selection.js";
|
|
6
4
|
import { FILENAME_FORMAT, formatFilename } from "../filename.js";
|
|
5
|
+
import { getPackageFiles } from "../package-deploy.js";
|
|
7
6
|
import { readPackageMeta } from "../package-meta.js";
|
|
7
|
+
import { zipPackage } from "../package-zip.js";
|
|
8
8
|
import { getZipSummary } from "../summary.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
const
|
|
9
|
+
import { checkDirectory, fileSelectionArgs, getFileSelectionInput, getSourceDirArg, resolveOutput, sourceDirArgs, } from "./args.js";
|
|
10
|
+
import { getBoolean, getString, getStrings } from "./command.js";
|
|
11
|
+
/** Options of a source directory and its files, which --package takes from the config. */
|
|
12
|
+
const SOURCE_FLAGS = [
|
|
13
|
+
'source-dir',
|
|
14
|
+
'distignore',
|
|
15
|
+
'no-distignore',
|
|
16
|
+
'exclude',
|
|
17
|
+
'exclude-gitattributes',
|
|
18
|
+
];
|
|
13
19
|
/**
|
|
14
|
-
* Get the
|
|
15
|
-
*
|
|
20
|
+
* Get the configured package to zip, failing for the options that set the
|
|
21
|
+
* source directory and the files instead.
|
|
16
22
|
*
|
|
17
|
-
* @param
|
|
18
|
-
* @
|
|
23
|
+
* @param values Parsed CLI values.
|
|
24
|
+
* @param positionals Positional arguments.
|
|
25
|
+
* @return The package identifier or path, or undefined without --package.
|
|
26
|
+
* @throws {ValidationError} For an empty --package, or --package with a source directory or file selection option.
|
|
19
27
|
*/
|
|
20
|
-
function
|
|
21
|
-
const name =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
function getPackageArg(values, positionals) {
|
|
29
|
+
const name = getString(values, 'package')?.trim();
|
|
30
|
+
const conflicts = SOURCE_FLAGS.filter((flag) => undefined !== getString(values, flag) ||
|
|
31
|
+
getBoolean(values, flag) ||
|
|
32
|
+
getStrings(values, flag).length);
|
|
33
|
+
if ('' === name) {
|
|
34
|
+
throw new ValidationError('--package <name> must not be empty.');
|
|
35
|
+
}
|
|
36
|
+
if (name && (positionals.length || conflicts.length)) {
|
|
37
|
+
throw new ValidationError(`--package takes the directory and files of the package from the config, so it can't be combined with ${positionals.length
|
|
38
|
+
? 'a source directory'
|
|
39
|
+
: conflicts.map((flag) => `--${flag}`).join(', ')}.`);
|
|
40
|
+
}
|
|
41
|
+
return name;
|
|
25
42
|
}
|
|
26
43
|
/**
|
|
27
|
-
*
|
|
44
|
+
* Describe the files of a directory with the slug and the version from the
|
|
45
|
+
* options, or from the plugin or theme headers.
|
|
28
46
|
*
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
-
* @
|
|
47
|
+
* @param values Parsed CLI values.
|
|
48
|
+
* @param sourceDir Directory to zip.
|
|
49
|
+
* @param selection File selection.
|
|
50
|
+
* @param slug Default slug.
|
|
51
|
+
* @return Source directory, file selection, slug, version and type.
|
|
32
52
|
*/
|
|
33
|
-
function
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
async function describeSource(values, sourceDir, selection, slug) {
|
|
54
|
+
const name = getString(values, 'slug') ?? slug;
|
|
55
|
+
const meta = await readPackageMeta({ dir: sourceDir, slug: name });
|
|
56
|
+
return {
|
|
57
|
+
sourceDir,
|
|
58
|
+
selection,
|
|
59
|
+
slug: name,
|
|
60
|
+
version: getString(values, 'version') ?? meta?.version ?? null,
|
|
61
|
+
...(meta ? { type: meta.type } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the files of a source directory from the CLI options.
|
|
66
|
+
*
|
|
67
|
+
* @param values Parsed CLI values.
|
|
68
|
+
* @param positionals Positional arguments.
|
|
69
|
+
* @param cwd Working directory.
|
|
70
|
+
* @return Source directory, file selection, slug and version.
|
|
71
|
+
*/
|
|
72
|
+
async function getDirectorySource(values, positionals, cwd) {
|
|
73
|
+
const sourceDir = resolve(cwd, getSourceDirArg(values, positionals));
|
|
74
|
+
await checkDirectory(sourceDir);
|
|
75
|
+
return describeSource(values, sourceDir, resolveFileSelection({
|
|
76
|
+
cwd,
|
|
77
|
+
sourceDir,
|
|
78
|
+
...getFileSelectionInput(values),
|
|
79
|
+
}), basename(cwd));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get the directory of a configured package with the files config of its
|
|
83
|
+
* package group, which its deploys use too.
|
|
84
|
+
*
|
|
85
|
+
* @param values Parsed CLI values.
|
|
86
|
+
* @param cwd Repository root with the wp-release config.
|
|
87
|
+
* @param name Package identifier or path under the configured root.
|
|
88
|
+
* @param configFile Config file, instead of the conventional one.
|
|
89
|
+
* @return Source directory, file selection, slug, version and package.
|
|
90
|
+
* @throws {ValidationError} Without a config or for an unknown package.
|
|
91
|
+
*/
|
|
92
|
+
async function getPackageSource(values, cwd, name, configFile) {
|
|
93
|
+
const pkg = await getPackageFiles({
|
|
94
|
+
cwd,
|
|
95
|
+
package: name,
|
|
96
|
+
...(configFile ? { configFile } : {}),
|
|
97
|
+
});
|
|
98
|
+
const source = await describeSource(values, pkg.directory, resolveFileSelection({
|
|
99
|
+
cwd,
|
|
100
|
+
sourceDir: pkg.directory,
|
|
101
|
+
...pkg.files,
|
|
102
|
+
}), basename(pkg.directory));
|
|
103
|
+
return { ...source, package: pkg.name };
|
|
38
104
|
}
|
|
39
105
|
export default {
|
|
40
106
|
name: 'zip',
|
|
41
|
-
usage: 'zip [<source-dir>] [options]',
|
|
107
|
+
usage: 'zip [<source-dir>] [options] | zip --package <name> [options]',
|
|
42
108
|
summary: 'Create a ZIP archive of a plugin or theme with a {slug}/ root folder.',
|
|
43
109
|
help: `Arguments:
|
|
44
110
|
<source-dir> Directory to archive (default: .), also accepted
|
|
45
111
|
as --source-dir <dir>
|
|
46
112
|
|
|
113
|
+
Configured packages (instead of the source directory and the file selection
|
|
114
|
+
options):
|
|
115
|
+
--package <name> Zip this package of the wp-release config, by
|
|
116
|
+
identifier or path under the configured root,
|
|
117
|
+
like plugins/alpha, with the files config of its
|
|
118
|
+
package group, the same files as its deploys
|
|
119
|
+
|
|
47
120
|
Options:
|
|
48
121
|
--output <file> ZIP file (default: the --filename-format name with
|
|
49
122
|
.zip in the current directory)
|
|
@@ -64,7 +137,13 @@ Options:
|
|
|
64
137
|
--force Overwrite existing output files
|
|
65
138
|
|
|
66
139
|
Entries are sorted and use a fixed timestamp and file mode, so the same files
|
|
67
|
-
always give the same ZIP
|
|
140
|
+
always give the same ZIP.
|
|
141
|
+
|
|
142
|
+
Examples:
|
|
143
|
+
wp-release zip dist --slug my-plugin --checksums
|
|
144
|
+
Zip a build with its checksums manifest
|
|
145
|
+
wp-release zip --package plugins/alpha --checksums
|
|
146
|
+
Zip a package of the config with its configured files`,
|
|
68
147
|
options: {
|
|
69
148
|
slug: { type: 'string' },
|
|
70
149
|
version: { type: 'string' },
|
|
@@ -74,65 +153,43 @@ always give the same ZIP.`,
|
|
|
74
153
|
output: { type: 'string' },
|
|
75
154
|
...sourceDirArgs,
|
|
76
155
|
...fileSelectionArgs,
|
|
156
|
+
package: { type: 'string' },
|
|
77
157
|
checksums: { type: 'boolean' },
|
|
78
158
|
force: { type: 'boolean' },
|
|
79
159
|
},
|
|
80
|
-
async run({ values, positionals, cwd, logger, }) {
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
? getChecksumsPath(zipPath)
|
|
95
|
-
: null;
|
|
96
|
-
const selection = resolveFileSelection({
|
|
97
|
-
cwd,
|
|
98
|
-
sourceDir,
|
|
99
|
-
...getFileSelectionInput(values),
|
|
100
|
-
});
|
|
101
|
-
const rules = ignoreOwnSignature(ignoreOwnFile(await loadFileRules(selection), sourceDir, zipPath), sourceDir, zipPath);
|
|
102
|
-
if (checksumsPath) {
|
|
103
|
-
ignoreOwnSignature(ignoreOwnFile(rules, sourceDir, checksumsPath), sourceDir, checksumsPath);
|
|
104
|
-
}
|
|
105
|
-
const files = await selectFiles(sourceDir, rules);
|
|
106
|
-
if (!files.length) {
|
|
107
|
-
throw new ValidationError(`No files to archive in ${sourceDir}.`);
|
|
108
|
-
}
|
|
109
|
-
checkOverwrite([zipPath, checksumsPath ?? ''].filter(Boolean), force);
|
|
110
|
-
await createZip({
|
|
111
|
-
sourceDir,
|
|
112
|
-
files,
|
|
113
|
-
zipPath,
|
|
160
|
+
async run({ values, positionals, cwd, configFile, logger, }) {
|
|
161
|
+
const name = getPackageArg(values, positionals);
|
|
162
|
+
const source = name
|
|
163
|
+
? await getPackageSource(values, cwd, name, configFile)
|
|
164
|
+
: await getDirectorySource(values, positionals, cwd);
|
|
165
|
+
const filename = formatFilename(getString(values, 'filename-format') ?? FILENAME_FORMAT, { slug: source.slug, version: source.version });
|
|
166
|
+
const zipped = await zipPackage({
|
|
167
|
+
sourceDir: source.sourceDir,
|
|
168
|
+
selection: source.selection,
|
|
169
|
+
zipPath: resolveOutput({
|
|
170
|
+
cwd,
|
|
171
|
+
output: getString(values, 'output'),
|
|
172
|
+
filename: `${filename}.zip`,
|
|
173
|
+
}),
|
|
114
174
|
rootFolder: getBoolean(values, 'no-root-folder')
|
|
115
175
|
? null
|
|
116
|
-
: getString(values, 'root-folder') ?? slug,
|
|
117
|
-
|
|
176
|
+
: getString(values, 'root-folder') ?? source.slug,
|
|
177
|
+
slug: source.slug,
|
|
178
|
+
version: source.version,
|
|
179
|
+
...(source.type ? { type: source.type } : {}),
|
|
180
|
+
checksums: getBoolean(values, 'checksums'),
|
|
181
|
+
force: getBoolean(values, 'force'),
|
|
118
182
|
});
|
|
119
|
-
logger.debug(`Archived ${files
|
|
120
|
-
logger.info(zipPath);
|
|
121
|
-
if (checksumsPath) {
|
|
122
|
-
|
|
123
|
-
sourceDir,
|
|
124
|
-
rules,
|
|
125
|
-
slug,
|
|
126
|
-
version,
|
|
127
|
-
type: meta?.type,
|
|
128
|
-
});
|
|
129
|
-
await writeChecksums(checksumsPath, manifest, force);
|
|
130
|
-
logger.info(checksumsPath);
|
|
183
|
+
logger.debug(`Archived ${zipped.files} files from ${source.sourceDir}.`);
|
|
184
|
+
logger.info(zipped.zipPath);
|
|
185
|
+
if (zipped.checksumsPath) {
|
|
186
|
+
logger.info(zipped.checksumsPath);
|
|
131
187
|
}
|
|
132
188
|
const result = {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
189
|
+
...zipped,
|
|
190
|
+
slug: source.slug,
|
|
191
|
+
version: source.version,
|
|
192
|
+
...(source.package ? { package: source.package } : {}),
|
|
136
193
|
};
|
|
137
194
|
logger.summary((context) => getZipSummary(context, result));
|
|
138
195
|
return { exitCode: 0, result };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { KeyObject } from 'node:crypto';
|
|
2
|
+
export declare const PUBLIC_KEY_BYTES = 32;
|
|
3
|
+
/**
|
|
4
|
+
* Get the raw 32 bytes of an Ed25519 public key.
|
|
5
|
+
*
|
|
6
|
+
* @param key Private or public key.
|
|
7
|
+
* @return Public key bytes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getRawPublicKey(key: KeyObject): Buffer;
|
|
10
|
+
/**
|
|
11
|
+
* Get an Ed25519 public key from its raw 32 bytes.
|
|
12
|
+
*
|
|
13
|
+
* @param bytes Public key bytes.
|
|
14
|
+
* @return Public key.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createRawPublicKey(bytes: Buffer): KeyObject;
|
|
17
|
+
/**
|
|
18
|
+
* Get the raw digest of a file, which the signature formats sign instead of
|
|
19
|
+
* the whole file.
|
|
20
|
+
*
|
|
21
|
+
* @param path File path.
|
|
22
|
+
* @param algorithm Node.js hash algorithm, like sha384 or blake2b512.
|
|
23
|
+
* @return Digest bytes.
|
|
24
|
+
*/
|
|
25
|
+
export declare function digestFile(path: string, algorithm: string): Promise<Buffer>;
|
package/dist/ed25519.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createHash, createPublicKey } from 'node:crypto';
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
export const PUBLIC_KEY_BYTES = 32;
|
|
4
|
+
// DER prefix of a SPKI Ed25519 public key, followed by the 32-byte key.
|
|
5
|
+
const SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');
|
|
6
|
+
/**
|
|
7
|
+
* Get the raw 32 bytes of an Ed25519 public key.
|
|
8
|
+
*
|
|
9
|
+
* @param key Private or public key.
|
|
10
|
+
* @return Public key bytes.
|
|
11
|
+
*/
|
|
12
|
+
export function getRawPublicKey(key) {
|
|
13
|
+
return ('private' === key.type ? createPublicKey(key) : key)
|
|
14
|
+
.export({ format: 'der', type: 'spki' })
|
|
15
|
+
.subarray(SPKI_PREFIX.length);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get an Ed25519 public key from its raw 32 bytes.
|
|
19
|
+
*
|
|
20
|
+
* @param bytes Public key bytes.
|
|
21
|
+
* @return Public key.
|
|
22
|
+
*/
|
|
23
|
+
export function createRawPublicKey(bytes) {
|
|
24
|
+
return createPublicKey({
|
|
25
|
+
key: Buffer.concat([SPKI_PREFIX, bytes]),
|
|
26
|
+
format: 'der',
|
|
27
|
+
type: 'spki',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the raw digest of a file, which the signature formats sign instead of
|
|
32
|
+
* the whole file.
|
|
33
|
+
*
|
|
34
|
+
* @param path File path.
|
|
35
|
+
* @param algorithm Node.js hash algorithm, like sha384 or blake2b512.
|
|
36
|
+
* @return Digest bytes.
|
|
37
|
+
*/
|
|
38
|
+
export async function digestFile(path, algorithm) {
|
|
39
|
+
const hash = createHash(algorithm);
|
|
40
|
+
for await (const chunk of createReadStream(path)) {
|
|
41
|
+
hash.update(chunk);
|
|
42
|
+
}
|
|
43
|
+
return hash.digest();
|
|
44
|
+
}
|
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.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,10 +23,12 @@ 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';
|
|
26
|
+
export { GitError, createGitRunner, parseRepositoryUrl, redactUrls, } from './git.ts';
|
|
24
27
|
export { GitDeploy, getDefaultToken, getGitAuthEnv, isValidRefName, resolveGitDeployOptions, } from './git-deploy.ts';
|
|
25
28
|
export { getGitDeployInputFromArgs } from './commands/deploy-git.ts';
|
|
26
|
-
export { getDeployPackages, getGitDeploys, getSvnDeploys, } from './package-deploy.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';
|
|
27
32
|
export type { PackageDeploy, PackageDeployFiles, PackageDeployOptions, PackageFileSelection, PackageDeployPlanItem, PackageDeployRelease, } from './package-deploy.ts';
|
|
28
33
|
export type { PackageDeployOutcome } from './commands/package-deploys.ts';
|
|
29
34
|
export type { CliIo, CommandResults } from './cli.ts';
|
|
@@ -51,5 +56,5 @@ export type { SvnCheckoutInput, SvnCommandInput, SvnCommandOutput, SvnCommitInpu
|
|
|
51
56
|
export type { SyncDirectoryInput, SyncResult } from './sync.ts';
|
|
52
57
|
export type { SummaryContext } from './summary.ts';
|
|
53
58
|
export type { CheckoutPath, DeployResult } from './svn-deploy.ts';
|
|
54
|
-
export type { GitCommandInput, GitCommandOutput, GitRunner } from './git.ts';
|
|
59
|
+
export type { GitCommandInput, GitCommandOutput, GitRunner, RepositoryLocation, } from './git.ts';
|
|
55
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,7 +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";
|
|
25
|
+
export { GitError, createGitRunner, parseRepositoryUrl, redactUrls, } from "./git.js";
|
|
24
26
|
export { GitDeploy, getDefaultToken, getGitAuthEnv, isValidRefName, resolveGitDeployOptions, } from "./git-deploy.js";
|
|
25
27
|
export { getGitDeployInputFromArgs } from "./commands/deploy-git.js";
|
|
26
|
-
export { getDeployPackages, getGitDeploys, getSvnDeploys, } from "./package-deploy.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>;
|