@git.zone/cli 6.1.2 → 6.2.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/.smartconfig.json +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/mod_release/helpers.npmartifact.d.ts +2 -2
- package/dist_ts/mod_release/helpers.npmartifact.js +35 -14
- package/dist_ts/mod_services/classes.dockercontainer.d.ts +6 -3
- package/dist_ts/mod_services/classes.dockercontainer.js +9 -5
- package/dist_ts/mod_services/classes.servicemanager.js +22 -3
- package/package.json +1 -1
- package/readme.md +15 -7
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mod_release/helpers.npmartifact.ts +41 -16
- package/ts/mod_services/classes.dockercontainer.ts +20 -9
- package/ts/mod_services/classes.servicemanager.ts +34 -2
- /package/{license → license.md} +0 -0
|
@@ -5,7 +5,33 @@ import {
|
|
|
5
5
|
} from "./classes.releasejournal.js";
|
|
6
6
|
import { assertCredentialFreeGitPushDestination } from "./helpers.releasebranch.js";
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const supportedPnpmVersions = ["11.25.0", "12.3.4"] as const;
|
|
9
|
+
const pnpmHelpRequirements = {
|
|
10
|
+
"11.25.0": {
|
|
11
|
+
pack: ["--out <path>", "--json"],
|
|
12
|
+
publish: [
|
|
13
|
+
"publish [<tarball>|<dir>]",
|
|
14
|
+
"--no-git-checks",
|
|
15
|
+
"--ignore-scripts",
|
|
16
|
+
"--json",
|
|
17
|
+
"--tag <tag>",
|
|
18
|
+
"--access <public|restricted>",
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
"12.3.4": {
|
|
22
|
+
pack: ["Usage: pnpm pack [OPTIONS]", "--out <OUT>", "--json"],
|
|
23
|
+
publish: [
|
|
24
|
+
"Usage: pnpm publish [OPTIONS] [PACKAGE]",
|
|
25
|
+
"Tarball or directory to publish",
|
|
26
|
+
"--no-git-checks",
|
|
27
|
+
"--ignore-scripts",
|
|
28
|
+
"--json",
|
|
29
|
+
"--tag <TAG>",
|
|
30
|
+
"--access <ACCESS>",
|
|
31
|
+
"[possible values: public, restricted]",
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
} as const;
|
|
9
35
|
const maximumMetadataResponseBytes = 8 * 1024 * 1024;
|
|
10
36
|
const capabilityCommandTimeoutMs = 30_000;
|
|
11
37
|
const packCommandTimeoutMs = 10 * 60_000;
|
|
@@ -13,7 +39,7 @@ const publishCommandTimeoutMs = 5 * 60_000;
|
|
|
13
39
|
const packageNameRegex = /^(?:@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*|[a-z0-9][a-z0-9._-]*)$/;
|
|
14
40
|
|
|
15
41
|
export interface IPnpmReleaseCapability {
|
|
16
|
-
version: typeof
|
|
42
|
+
version: (typeof supportedPnpmVersions)[number];
|
|
17
43
|
}
|
|
18
44
|
|
|
19
45
|
export type TNpmArtifactProbeStatus =
|
|
@@ -72,10 +98,12 @@ const readPackageIdentity = async (
|
|
|
72
98
|
|
|
73
99
|
const requireHelpFragments = (
|
|
74
100
|
outputArg: string,
|
|
75
|
-
fragmentsArg: string[],
|
|
101
|
+
fragmentsArg: readonly string[],
|
|
76
102
|
commandArg: string,
|
|
77
103
|
): void => {
|
|
78
|
-
const missing = fragmentsArg.filter(
|
|
104
|
+
const missing = fragmentsArg.filter(
|
|
105
|
+
(fragmentArg) => !outputArg.includes(fragmentArg),
|
|
106
|
+
);
|
|
79
107
|
if (missing.length > 0) {
|
|
80
108
|
throw new Error(
|
|
81
109
|
`pnpm ${commandArg} is missing required exact-release capabilities: ${missing.join(", ")}.`,
|
|
@@ -94,11 +122,15 @@ export const assertPnpmReleaseCapability = async (
|
|
|
94
122
|
timeoutKillGraceMs: 5_000,
|
|
95
123
|
});
|
|
96
124
|
const version = versionResult.stdout.trim();
|
|
97
|
-
|
|
125
|
+
const supportedVersion = supportedPnpmVersions.find(
|
|
126
|
+
(candidateArg) => candidateArg === version,
|
|
127
|
+
);
|
|
128
|
+
if (versionResult.exitCode !== 0 || !supportedVersion) {
|
|
98
129
|
throw new Error(
|
|
99
|
-
`Exact release packaging requires
|
|
130
|
+
`Exact release packaging requires a verified pnpm version (${supportedPnpmVersions.join(", ")}); resolved ${version || "unknown"}.`,
|
|
100
131
|
);
|
|
101
132
|
}
|
|
133
|
+
const requirements = pnpmHelpRequirements[supportedVersion];
|
|
102
134
|
|
|
103
135
|
const packHelp = await smartshellArg.execSpawn("pnpm", ["pack", "--help"], {
|
|
104
136
|
cwd: cwdArg,
|
|
@@ -109,7 +141,7 @@ export const assertPnpmReleaseCapability = async (
|
|
|
109
141
|
if (packHelp.exitCode !== 0) {
|
|
110
142
|
throw new Error("Unable to inspect pnpm pack capabilities.");
|
|
111
143
|
}
|
|
112
|
-
requireHelpFragments(packHelp.combinedOutput,
|
|
144
|
+
requireHelpFragments(packHelp.combinedOutput, requirements.pack, "pack");
|
|
113
145
|
|
|
114
146
|
const publishHelp = await smartshellArg.execSpawn(
|
|
115
147
|
"pnpm",
|
|
@@ -126,17 +158,10 @@ export const assertPnpmReleaseCapability = async (
|
|
|
126
158
|
}
|
|
127
159
|
requireHelpFragments(
|
|
128
160
|
publishHelp.combinedOutput,
|
|
129
|
-
|
|
130
|
-
"publish [<tarball>|<dir>]",
|
|
131
|
-
"--no-git-checks",
|
|
132
|
-
"--ignore-scripts",
|
|
133
|
-
"--json",
|
|
134
|
-
"--tag <tag>",
|
|
135
|
-
"--access <public|restricted>",
|
|
136
|
-
],
|
|
161
|
+
requirements.publish,
|
|
137
162
|
"publish",
|
|
138
163
|
);
|
|
139
|
-
return { version:
|
|
164
|
+
return { version: supportedVersion };
|
|
140
165
|
};
|
|
141
166
|
|
|
142
167
|
const legacyPublishWorkflowPaths = [
|
|
@@ -60,15 +60,19 @@ export interface IDockerArgvExecutionErrorOptions {
|
|
|
60
60
|
signal?: NodeJS.Signals;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
export interface
|
|
63
|
+
export interface IFencedBindOperationSpecification {
|
|
64
|
+
entrypoint: string;
|
|
65
|
+
command: readonly string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface IFencedBindOperationOptions extends IFencedBindOperationSpecification {
|
|
64
69
|
image: string;
|
|
65
70
|
hostPath: string;
|
|
66
71
|
containerPath: string;
|
|
67
|
-
entrypoint: string;
|
|
68
|
-
command: readonly string[];
|
|
69
72
|
labels: Record<string, string>;
|
|
70
73
|
executionOptions: () => IDockerExecArgvOptions;
|
|
71
74
|
rollbackTimeoutMs?: number;
|
|
75
|
+
recoverablePredecessors?: readonly IFencedBindOperationSpecification[];
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
interface IFencedBindRuntimeOptions extends IFencedBindOperationOptions {
|
|
@@ -607,16 +611,23 @@ export class DockerContainer {
|
|
|
607
611
|
inspectionArg.mounts.length === 1 &&
|
|
608
612
|
inspectionArg.mounts[0].source === plugins.path.resolve(optionsArg.hostPath) &&
|
|
609
613
|
inspectionArg.mounts[0].readWrite;
|
|
614
|
+
const operationMatches = [
|
|
615
|
+
{ entrypoint: optionsArg.entrypoint, command: optionsArg.command },
|
|
616
|
+
...(optionsArg.recoverablePredecessors ?? []),
|
|
617
|
+
].some(
|
|
618
|
+
(specificationArg) =>
|
|
619
|
+
inspectionArg.entrypoint.length === 1 &&
|
|
620
|
+
inspectionArg.entrypoint[0] === specificationArg.entrypoint &&
|
|
621
|
+
inspectionArg.command.length === specificationArg.command.length &&
|
|
622
|
+
inspectionArg.command.every(
|
|
623
|
+
(entryArg, indexArg) => entryArg === specificationArg.command[indexArg],
|
|
624
|
+
),
|
|
625
|
+
);
|
|
610
626
|
if (
|
|
611
627
|
inspectionArg.name !== expectedNameArg ||
|
|
612
628
|
inspectionArg.image !== optionsArg.image ||
|
|
613
629
|
inspectionArg.user !== '0' ||
|
|
614
|
-
|
|
615
|
-
inspectionArg.entrypoint[0] !== optionsArg.entrypoint ||
|
|
616
|
-
inspectionArg.command.length !== optionsArg.command.length ||
|
|
617
|
-
!inspectionArg.command.every(
|
|
618
|
-
(entryArg, indexArg) => entryArg === optionsArg.command[indexArg],
|
|
619
|
-
) ||
|
|
630
|
+
!operationMatches ||
|
|
620
631
|
!labelsMatch ||
|
|
621
632
|
!mountMatches ||
|
|
622
633
|
inspectionArg.mounts[0].destination !== optionsArg.containerPath
|
|
@@ -1315,8 +1315,11 @@ export class ServiceManager {
|
|
|
1315
1315
|
image: objectStorageImage,
|
|
1316
1316
|
hostPath: dataPath,
|
|
1317
1317
|
containerPath: '/data',
|
|
1318
|
-
entrypoint: '/bin/
|
|
1319
|
-
command: [
|
|
1318
|
+
entrypoint: '/bin/sh',
|
|
1319
|
+
command: [
|
|
1320
|
+
'-c',
|
|
1321
|
+
'/bin/chown -R objectstorage:objectstorage /data && /bin/chmod 0700 /data',
|
|
1322
|
+
],
|
|
1320
1323
|
labels: {
|
|
1321
1324
|
'git.zone.tool': serviceToolLabel,
|
|
1322
1325
|
'git.zone.service': 'objectstorage',
|
|
@@ -1327,6 +1330,12 @@ export class ServiceManager {
|
|
|
1327
1330
|
},
|
|
1328
1331
|
executionOptions: dockerTimeoutArg,
|
|
1329
1332
|
rollbackTimeoutMs: objectStorageRollbackTimeoutMs,
|
|
1333
|
+
recoverablePredecessors: [
|
|
1334
|
+
{
|
|
1335
|
+
entrypoint: '/bin/chown',
|
|
1336
|
+
command: ['-R', 'objectstorage:objectstorage', '/data'],
|
|
1337
|
+
},
|
|
1338
|
+
],
|
|
1330
1339
|
});
|
|
1331
1340
|
return labels;
|
|
1332
1341
|
}
|
|
@@ -1590,6 +1599,28 @@ export class ServiceManager {
|
|
|
1590
1599
|
await this.config.validateObjectStoragePorts();
|
|
1591
1600
|
}
|
|
1592
1601
|
|
|
1602
|
+
if (initialInspection?.status === 'restarting') {
|
|
1603
|
+
logger.log('note', ' Stopping restart loop before securing data...');
|
|
1604
|
+
await this.revalidateObjectStorageContainer(
|
|
1605
|
+
initialInspection.id,
|
|
1606
|
+
containers.objectstorage,
|
|
1607
|
+
expectedLabels,
|
|
1608
|
+
dockerTimeout,
|
|
1609
|
+
);
|
|
1610
|
+
await this.docker.execArgv(['stop', initialInspection.id], dockerTimeout());
|
|
1611
|
+
initialInspection = await this.revalidateObjectStorageContainer(
|
|
1612
|
+
initialInspection.id,
|
|
1613
|
+
containers.objectstorage,
|
|
1614
|
+
expectedLabels,
|
|
1615
|
+
dockerTimeout,
|
|
1616
|
+
);
|
|
1617
|
+
if (initialInspection.running || initialInspection.status === 'restarting') {
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
`ObjectStorage container ${containers.objectstorage} remained in its restart loop.`,
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1593
1624
|
const needsRecreate =
|
|
1594
1625
|
!!initialInspection &&
|
|
1595
1626
|
!this.objectStorageConfigurationMatches(initialInspection, expectedLabels);
|
|
@@ -1614,6 +1645,7 @@ export class ServiceManager {
|
|
|
1614
1645
|
? 'Recreated with canonical configuration and reconciled'
|
|
1615
1646
|
: 'Created, started, and reconciled';
|
|
1616
1647
|
} else if (!initialInspection.running) {
|
|
1648
|
+
await this.prepareObjectStorageDataDirectory(dockerTimeout);
|
|
1617
1649
|
logger.log('note', ' Starting existing container...');
|
|
1618
1650
|
activeInspection = initialInspection;
|
|
1619
1651
|
await startById(activeInspection.id, false);
|
/package/{license → license.md}
RENAMED
|
File without changes
|