@git.zone/cli 6.0.1 → 6.1.1
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/helpers.workflow.d.ts +2 -0
- package/dist_ts/helpers.workflow.js +96 -25
- package/dist_ts/mod_config/index.js +176 -88
- package/dist_ts/mod_release/classes.releasejournal.d.ts +60 -10
- package/dist_ts/mod_release/classes.releasejournal.js +513 -21
- package/dist_ts/mod_release/helpers.releasepublication.d.ts +5 -3
- package/dist_ts/mod_release/helpers.releasepublication.js +390 -13
- package/dist_ts/mod_release/helpers.tsdockerprotocol.d.ts +60 -0
- package/dist_ts/mod_release/helpers.tsdockerprotocol.js +442 -0
- package/dist_ts/mod_release/index.d.ts +1 -1
- package/dist_ts/mod_release/index.js +101 -19
- package/dist_ts/plugins.d.ts +5 -1
- package/dist_ts/plugins.js +5 -2
- package/package.json +2 -1
- package/readme.hints.md +43 -17
- package/readme.md +83 -75
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/helpers.workflow.ts +191 -49
- package/ts/mod_config/index.ts +320 -146
- package/ts/mod_release/classes.releasejournal.ts +939 -70
- package/ts/mod_release/helpers.releasepublication.ts +786 -49
- package/ts/mod_release/helpers.tsdockerprotocol.ts +806 -0
- package/ts/mod_release/index.ts +231 -74
- package/ts/plugins.ts +20 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as plugins from "./mod.plugins.js";
|
|
2
|
+
import type { IReleaseCapabilitiesResult, IReleaseCleanupResult, IReleaseDestinationEvidence, IReleaseProbeResult, IReleasePromotionContext, IReleasePromotionResult, IReleaseQualificationRequest, IReleaseQualificationResult, IReleaseValidationResult, TReleasePromotionEvidence, TReleaseProtocolCommand } from "./mod.plugins.js";
|
|
3
|
+
export type { IReleaseCapabilitiesResult, IReleaseCleanupResult, IReleaseDestinationEvidence, IReleaseProbeResult, IReleasePromotionContext, IReleasePromotionResult, IReleaseQualificationRequest, IReleaseQualificationResult, IReleaseValidationResult, TReleasePromotionEvidence, TReleaseProtocolCommand, } from "./mod.plugins.js";
|
|
4
|
+
export declare const assertReleaseCleanupResult: (valueArg: unknown, requestArg: Pick<IReleaseQualificationRequest, "candidateId" | "projectId">) => IReleaseCleanupResult;
|
|
5
|
+
export declare const assertReleasePromotionEvidence: (valueArg: unknown, requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext) => TReleasePromotionEvidence;
|
|
6
|
+
export declare const assertReleaseProbeResult: (valueArg: unknown, requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext) => IReleaseProbeResult;
|
|
7
|
+
export declare const assertReleasePromotionResult: (valueArg: unknown, requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext) => IReleasePromotionResult;
|
|
8
|
+
export declare const assertReleaseQualificationRequest: (valueArg: unknown) => IReleaseQualificationRequest;
|
|
9
|
+
export declare const assertReleaseQualificationResult: (valueArg: unknown, requestArg: IReleaseQualificationRequest) => IReleaseQualificationResult;
|
|
10
|
+
export declare const canonicalReleaseJson: (valueArg: unknown) => string;
|
|
11
|
+
export declare const canonicalReleaseJsonDocument: (valueArg: unknown) => string;
|
|
12
|
+
export declare const classifyReleasePromotionEvidence: (evidenceArg: TReleasePromotionEvidence) => "exact" | "pending" | "conflict" | "inconclusive";
|
|
13
|
+
export declare const createReleaseProjectId: (cwdArg: string) => string;
|
|
14
|
+
export declare const createReleasePromotionId: (candidateIdArg: string, imageIdArg: string, destinationArg: Pick<IReleaseDestinationEvidence, "registry" | "repository" | "alias">) => string;
|
|
15
|
+
export declare const createReleaseQualificationRequest: (optionsArg: import("@git.zone/tsdocker/dist_ts/interfaces/index.js").ICreateReleaseQualificationRequestOptions) => IReleaseQualificationRequest;
|
|
16
|
+
export declare const getReleasePromotionContexts: (resultArg: IReleaseQualificationResult) => IReleasePromotionContext[];
|
|
17
|
+
export declare class TsdockerReleaseCommandError extends Error {
|
|
18
|
+
readonly command: TReleaseProtocolCommand;
|
|
19
|
+
readonly code: string;
|
|
20
|
+
constructor(command: TReleaseProtocolCommand, code: string, messageArg: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class TsdockerReleaseRequestCleanupError extends Error {
|
|
23
|
+
readonly command: TReleaseProtocolCommand;
|
|
24
|
+
readonly requestPath: string;
|
|
25
|
+
readonly commandError: unknown | undefined;
|
|
26
|
+
readonly result: unknown | undefined;
|
|
27
|
+
readonly cleanupError: unknown;
|
|
28
|
+
reclamationError: unknown | undefined;
|
|
29
|
+
constructor(command: TReleaseProtocolCommand, requestPath: string, commandError: unknown | undefined, result: unknown | undefined, cleanupError: unknown);
|
|
30
|
+
}
|
|
31
|
+
export interface ITsdockerReleaseClient {
|
|
32
|
+
assertCapabilities: () => Promise<IReleaseCapabilitiesResult>;
|
|
33
|
+
validate: (requestArg: IReleaseQualificationRequest, requestDirectoryArg?: string) => Promise<IReleaseValidationResult>;
|
|
34
|
+
qualify: (requestArg: IReleaseQualificationRequest, requestDirectoryArg: string, requestOwnerIdArg: string) => Promise<IReleaseQualificationResult>;
|
|
35
|
+
probe: (requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext, requestDirectoryArg?: string, requestOwnerIdArg?: string) => Promise<IReleaseProbeResult>;
|
|
36
|
+
promote: (requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext, requestDirectoryArg: string, requestOwnerIdArg: string) => Promise<IReleasePromotionResult>;
|
|
37
|
+
cleanup: (requestArg: IReleaseQualificationRequest, requestDirectoryArg: string, requestOwnerIdArg: string) => Promise<IReleaseCleanupResult>;
|
|
38
|
+
reclaimRequestFiles: (requestDirectoryArg: string, retiredOwnerIdsArg: string[]) => Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare class TsdockerReleaseClient implements ITsdockerReleaseClient {
|
|
41
|
+
private readonly smartshell;
|
|
42
|
+
private readonly binaryPath;
|
|
43
|
+
private readonly cwd;
|
|
44
|
+
private readonly packageJsonPath;
|
|
45
|
+
constructor(smartshell: plugins.smartshell.Smartshell, cwdArg: string);
|
|
46
|
+
assertCapabilities(): Promise<IReleaseCapabilitiesResult>;
|
|
47
|
+
validate(requestArg: IReleaseQualificationRequest, requestDirectoryArg?: string): Promise<IReleaseValidationResult>;
|
|
48
|
+
qualify(requestArg: IReleaseQualificationRequest, requestDirectoryArg: string, requestOwnerIdArg: string): Promise<IReleaseQualificationResult>;
|
|
49
|
+
probe(requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext, requestDirectoryArg?: string, requestOwnerIdArg?: string): Promise<IReleaseProbeResult>;
|
|
50
|
+
promote(requestArg: IReleaseQualificationRequest, contextArg: IReleasePromotionContext, requestDirectoryArg: string, requestOwnerIdArg: string): Promise<IReleasePromotionResult>;
|
|
51
|
+
cleanup(requestArg: IReleaseQualificationRequest, requestDirectoryArg: string, requestOwnerIdArg: string): Promise<IReleaseCleanupResult>;
|
|
52
|
+
reclaimRequestFiles(requestDirectoryArg: string, retiredOwnerIdsArg: string[]): Promise<void>;
|
|
53
|
+
private readInstalledVersion;
|
|
54
|
+
private assertRequestForProject;
|
|
55
|
+
private assertPromotionInvocation;
|
|
56
|
+
private createPromotionRequest;
|
|
57
|
+
private assertRequestDirectory;
|
|
58
|
+
private runWithTemporaryRequestDirectory;
|
|
59
|
+
private run;
|
|
60
|
+
}
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import * as plugins from "./mod.plugins.js";
|
|
2
|
+
import { getProjectTsdockerBinPath } from "../helpers.tsdocker.js";
|
|
3
|
+
import { supportsTsdockerMinimumVersion } from "../helpers.workflow.js";
|
|
4
|
+
export const assertReleaseCleanupResult = plugins.tsdockerReleaseProtocol.assertReleaseCleanupResult;
|
|
5
|
+
export const assertReleasePromotionEvidence = plugins.tsdockerReleaseProtocol.assertReleasePromotionEvidence;
|
|
6
|
+
export const assertReleaseProbeResult = plugins.tsdockerReleaseProtocol.assertReleaseProbeResult;
|
|
7
|
+
export const assertReleasePromotionResult = plugins.tsdockerReleaseProtocol.assertReleasePromotionResult;
|
|
8
|
+
export const assertReleaseQualificationRequest = plugins.tsdockerReleaseProtocol.assertReleaseQualificationRequest;
|
|
9
|
+
export const assertReleaseQualificationResult = plugins.tsdockerReleaseProtocol.assertReleaseQualificationResult;
|
|
10
|
+
export const canonicalReleaseJson = plugins.tsdockerReleaseProtocol.canonicalReleaseJson;
|
|
11
|
+
export const canonicalReleaseJsonDocument = plugins.tsdockerReleaseProtocol.canonicalReleaseJsonDocument;
|
|
12
|
+
export const classifyReleasePromotionEvidence = plugins.tsdockerReleaseProtocol.classifyReleasePromotionEvidence;
|
|
13
|
+
export const createReleaseProjectId = plugins.tsdockerReleaseProtocol.createReleaseProjectId;
|
|
14
|
+
export const createReleasePromotionId = plugins.tsdockerReleaseProtocol.createReleasePromotionId;
|
|
15
|
+
export const createReleaseQualificationRequest = plugins.tsdockerReleaseProtocol.createReleaseQualificationRequest;
|
|
16
|
+
export const getReleasePromotionContexts = plugins.tsdockerReleaseProtocol.getReleasePromotionContexts;
|
|
17
|
+
const responseByteLimit = 1024 * 1024;
|
|
18
|
+
const requestByteLimit = 64 * 1024;
|
|
19
|
+
const packageJsonByteLimit = 64 * 1024;
|
|
20
|
+
const requestOwnerIdPattern = /^[a-f0-9]{32}$/;
|
|
21
|
+
const requestFilePattern = /^\.tsdocker-request\.([a-f0-9]{32})\.(release-(?:validate|qualify|probe|promote|cleanup))\.([a-f0-9]{24})\.json$/;
|
|
22
|
+
const minimumReleaseVersion = [3, 5, 1];
|
|
23
|
+
const commandTimeouts = {
|
|
24
|
+
"release-capabilities": 30_000,
|
|
25
|
+
"release-validate": 2 * 60_000,
|
|
26
|
+
"release-qualify": 6 * 60 * 60_000,
|
|
27
|
+
"release-probe": 5 * 60_000,
|
|
28
|
+
"release-promote": 2 * 60 * 60_000,
|
|
29
|
+
"release-cleanup": 10 * 60_000,
|
|
30
|
+
};
|
|
31
|
+
const isPlainObject = (valueArg) => typeof valueArg === "object" && valueArg !== null && !Array.isArray(valueArg);
|
|
32
|
+
export class TsdockerReleaseCommandError extends Error {
|
|
33
|
+
command;
|
|
34
|
+
code;
|
|
35
|
+
constructor(command, code, messageArg) {
|
|
36
|
+
super(messageArg);
|
|
37
|
+
this.command = command;
|
|
38
|
+
this.code = code;
|
|
39
|
+
this.name = "TsdockerReleaseCommandError";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export class TsdockerReleaseRequestCleanupError extends Error {
|
|
43
|
+
command;
|
|
44
|
+
requestPath;
|
|
45
|
+
commandError;
|
|
46
|
+
result;
|
|
47
|
+
cleanupError;
|
|
48
|
+
reclamationError;
|
|
49
|
+
constructor(command, requestPath, commandError, result, cleanupError) {
|
|
50
|
+
super(`tSDocker ${command} request cleanup failed.`);
|
|
51
|
+
this.command = command;
|
|
52
|
+
this.requestPath = requestPath;
|
|
53
|
+
this.commandError = commandError;
|
|
54
|
+
this.result = result;
|
|
55
|
+
this.cleanupError = cleanupError;
|
|
56
|
+
this.name = "TsdockerReleaseRequestCleanupError";
|
|
57
|
+
this.reclamationError = undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const parseProtocolOutput = (resultArg, commandArg) => {
|
|
61
|
+
if (resultArg.timedOut) {
|
|
62
|
+
throw new TsdockerReleaseCommandError(commandArg, "COMMAND_TIMEOUT", `tSDocker ${commandArg} timed out with an unresolved outcome.`);
|
|
63
|
+
}
|
|
64
|
+
if (resultArg.signal) {
|
|
65
|
+
throw new TsdockerReleaseCommandError(commandArg, "COMMAND_SIGNALLED", `tSDocker ${commandArg} was terminated with an unresolved outcome.`);
|
|
66
|
+
}
|
|
67
|
+
if (resultArg.stderr !== "") {
|
|
68
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} wrote non-protocol stderr output.`);
|
|
69
|
+
}
|
|
70
|
+
if (Buffer.byteLength(resultArg.stdout) > responseByteLimit ||
|
|
71
|
+
!resultArg.stdout.endsWith("\n")) {
|
|
72
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} returned an invalid response envelope.`);
|
|
73
|
+
}
|
|
74
|
+
let parsed;
|
|
75
|
+
try {
|
|
76
|
+
parsed = JSON.parse(resultArg.stdout);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} returned invalid JSON.`);
|
|
80
|
+
}
|
|
81
|
+
if (canonicalReleaseJsonDocument(parsed) !== resultArg.stdout) {
|
|
82
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} returned noncanonical JSON.`);
|
|
83
|
+
}
|
|
84
|
+
if (resultArg.exitCode !== 0) {
|
|
85
|
+
try {
|
|
86
|
+
const protocolError = plugins.tsdockerReleaseProtocol.assertReleaseErrorResult(parsed, commandArg);
|
|
87
|
+
throw new TsdockerReleaseCommandError(commandArg, protocolError.error.code, protocolError.error.message);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error instanceof TsdockerReleaseCommandError)
|
|
91
|
+
throw error;
|
|
92
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} failed without a valid protocol error.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (isPlainObject(parsed) &&
|
|
96
|
+
parsed.kind === "tsdocker-release-error-result") {
|
|
97
|
+
throw new TsdockerReleaseCommandError(commandArg, "INVALID_PROTOCOL_OUTPUT", `tSDocker ${commandArg} returned an error result with exit code 0.`);
|
|
98
|
+
}
|
|
99
|
+
return parsed;
|
|
100
|
+
};
|
|
101
|
+
export class TsdockerReleaseClient {
|
|
102
|
+
smartshell;
|
|
103
|
+
binaryPath;
|
|
104
|
+
cwd;
|
|
105
|
+
packageJsonPath;
|
|
106
|
+
constructor(smartshell, cwdArg) {
|
|
107
|
+
this.smartshell = smartshell;
|
|
108
|
+
this.cwd = plugins.path.resolve(cwdArg);
|
|
109
|
+
this.binaryPath = getProjectTsdockerBinPath(this.cwd);
|
|
110
|
+
this.packageJsonPath = plugins.path.join(this.cwd, "node_modules", "@git.zone", "tsdocker", "package.json");
|
|
111
|
+
}
|
|
112
|
+
async assertCapabilities() {
|
|
113
|
+
const installedVersion = await this.readInstalledVersion();
|
|
114
|
+
await plugins.fs.access(this.binaryPath);
|
|
115
|
+
const versionResult = await this.smartshell.execSpawn(this.binaryPath, ["--version"], {
|
|
116
|
+
cwd: this.cwd,
|
|
117
|
+
maxBuffer: 4096,
|
|
118
|
+
silent: true,
|
|
119
|
+
timeout: 30_000,
|
|
120
|
+
timeoutKillGraceMs: 5_000,
|
|
121
|
+
});
|
|
122
|
+
if (versionResult.exitCode !== 0 ||
|
|
123
|
+
versionResult.timedOut ||
|
|
124
|
+
versionResult.signal ||
|
|
125
|
+
versionResult.stderr !== "" ||
|
|
126
|
+
versionResult.stdout.trim() !== installedVersion) {
|
|
127
|
+
throw new Error("Docker release journal schema 2 requires one matching project-local @git.zone/tsdocker package and binary.");
|
|
128
|
+
}
|
|
129
|
+
const parsed = await this.run("release-capabilities");
|
|
130
|
+
return plugins.tsdockerReleaseProtocol.assertReleaseCapabilitiesResult(parsed, this.cwd, {
|
|
131
|
+
requiredCommands: [
|
|
132
|
+
...plugins.tsdockerReleaseProtocol.releaseProtocolCommands,
|
|
133
|
+
],
|
|
134
|
+
requiredFeatures: [
|
|
135
|
+
...plugins.tsdockerReleaseProtocol.releaseProtocolFeatures,
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async validate(requestArg, requestDirectoryArg) {
|
|
140
|
+
const request = this.assertRequestForProject(requestArg);
|
|
141
|
+
const runValidation = async (requestDirectory, requestOwnerId) => {
|
|
142
|
+
const parsed = await this.run("release-validate", request, requestDirectory, requestOwnerId);
|
|
143
|
+
return plugins.tsdockerReleaseProtocol.assertReleaseValidationResult(parsed, request);
|
|
144
|
+
};
|
|
145
|
+
if (requestDirectoryArg) {
|
|
146
|
+
return runValidation(requestDirectoryArg, plugins.crypto.randomBytes(16).toString("hex"));
|
|
147
|
+
}
|
|
148
|
+
return this.runWithTemporaryRequestDirectory("release-validate", runValidation, (valueArg) => plugins.tsdockerReleaseProtocol.assertReleaseValidationResult(valueArg, request));
|
|
149
|
+
}
|
|
150
|
+
async qualify(requestArg, requestDirectoryArg, requestOwnerIdArg) {
|
|
151
|
+
const request = this.assertRequestForProject(requestArg);
|
|
152
|
+
const parsed = await this.run("release-qualify", request, requestDirectoryArg, requestOwnerIdArg, ["--classified-errors"]);
|
|
153
|
+
return assertReleaseQualificationResult(parsed, request);
|
|
154
|
+
}
|
|
155
|
+
async probe(requestArg, contextArg, requestDirectoryArg, requestOwnerIdArg) {
|
|
156
|
+
const request = this.assertPromotionInvocation(requestArg, contextArg);
|
|
157
|
+
const runProbe = async (requestDirectory, requestOwnerId) => {
|
|
158
|
+
const parsed = await this.run("release-probe", this.createPromotionRequest("tsdocker-release-probe-request", request, contextArg.promotionId), requestDirectory, requestOwnerId);
|
|
159
|
+
return plugins.tsdockerReleaseProtocol.assertReleaseProbeResult(parsed, request, contextArg);
|
|
160
|
+
};
|
|
161
|
+
if ((requestDirectoryArg === undefined) !==
|
|
162
|
+
(requestOwnerIdArg === undefined)) {
|
|
163
|
+
throw new Error("tSDocker release probes require both request storage and owner, or neither.");
|
|
164
|
+
}
|
|
165
|
+
if (requestDirectoryArg && requestOwnerIdArg) {
|
|
166
|
+
return runProbe(requestDirectoryArg, requestOwnerIdArg);
|
|
167
|
+
}
|
|
168
|
+
return this.runWithTemporaryRequestDirectory("release-probe", runProbe, (valueArg) => plugins.tsdockerReleaseProtocol.assertReleaseProbeResult(valueArg, request, contextArg));
|
|
169
|
+
}
|
|
170
|
+
async promote(requestArg, contextArg, requestDirectoryArg, requestOwnerIdArg) {
|
|
171
|
+
const request = this.assertPromotionInvocation(requestArg, contextArg);
|
|
172
|
+
const parsed = await this.run("release-promote", this.createPromotionRequest("tsdocker-release-promotion-request", request, contextArg.promotionId), requestDirectoryArg, requestOwnerIdArg);
|
|
173
|
+
return plugins.tsdockerReleaseProtocol.assertReleasePromotionResult(parsed, request, contextArg);
|
|
174
|
+
}
|
|
175
|
+
async cleanup(requestArg, requestDirectoryArg, requestOwnerIdArg) {
|
|
176
|
+
const request = this.assertRequestForProject(requestArg);
|
|
177
|
+
const parsed = await this.run("release-cleanup", {
|
|
178
|
+
candidateId: request.candidateId,
|
|
179
|
+
kind: "tsdocker-release-cleanup-request",
|
|
180
|
+
projectId: request.projectId,
|
|
181
|
+
protocolVersion: 1,
|
|
182
|
+
schemaVersion: 1,
|
|
183
|
+
}, requestDirectoryArg, requestOwnerIdArg);
|
|
184
|
+
return assertReleaseCleanupResult(parsed, request);
|
|
185
|
+
}
|
|
186
|
+
async reclaimRequestFiles(requestDirectoryArg, retiredOwnerIdsArg) {
|
|
187
|
+
if (retiredOwnerIdsArg.length === 0 ||
|
|
188
|
+
new Set(retiredOwnerIdsArg).size !== retiredOwnerIdsArg.length ||
|
|
189
|
+
retiredOwnerIdsArg.some((ownerIdArg) => !requestOwnerIdPattern.test(ownerIdArg))) {
|
|
190
|
+
throw new Error("tSDocker request reclamation requires unique exact retired owner IDs.");
|
|
191
|
+
}
|
|
192
|
+
const requestDirectory = await this.assertRequestDirectory(requestDirectoryArg);
|
|
193
|
+
const retiredOwnerIds = new Set(retiredOwnerIdsArg);
|
|
194
|
+
const callerUid = process.getuid?.();
|
|
195
|
+
const entries = await plugins.fs.readdir(requestDirectory, {
|
|
196
|
+
withFileTypes: true,
|
|
197
|
+
});
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
const match = entry.name.match(requestFilePattern);
|
|
200
|
+
if (!match || !retiredOwnerIds.has(match[1]))
|
|
201
|
+
continue;
|
|
202
|
+
const requestPath = plugins.path.join(requestDirectory, entry.name);
|
|
203
|
+
let requestStat;
|
|
204
|
+
try {
|
|
205
|
+
requestStat = await plugins.fs.lstat(requestPath);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
if (error.code === "ENOENT")
|
|
209
|
+
continue;
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
if (!entry.isFile() ||
|
|
213
|
+
!requestStat.isFile() ||
|
|
214
|
+
requestStat.isSymbolicLink() ||
|
|
215
|
+
(callerUid !== undefined && requestStat.uid !== callerUid) ||
|
|
216
|
+
(requestStat.mode & 0o077) !== 0 ||
|
|
217
|
+
requestStat.size > requestByteLimit) {
|
|
218
|
+
throw new Error(`Retired tSDocker request file is unsafe: ${requestPath}`);
|
|
219
|
+
}
|
|
220
|
+
await plugins.fs.rm(requestPath);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async readInstalledVersion() {
|
|
224
|
+
const packageHandle = await plugins.fs.open(this.packageJsonPath, plugins.fsConstants.O_RDONLY | plugins.fsConstants.O_NOFOLLOW);
|
|
225
|
+
let packageJson;
|
|
226
|
+
try {
|
|
227
|
+
const before = await packageHandle.stat();
|
|
228
|
+
if (!before.isFile() ||
|
|
229
|
+
before.size <= 0 ||
|
|
230
|
+
before.size > packageJsonByteLimit) {
|
|
231
|
+
throw new Error("Project-local @git.zone/tsdocker package metadata is unavailable or unsafe.");
|
|
232
|
+
}
|
|
233
|
+
const bytes = await packageHandle.readFile();
|
|
234
|
+
const after = await packageHandle.stat();
|
|
235
|
+
if (before.dev !== after.dev ||
|
|
236
|
+
before.ino !== after.ino ||
|
|
237
|
+
before.size !== after.size ||
|
|
238
|
+
before.mtimeMs !== after.mtimeMs ||
|
|
239
|
+
before.ctimeMs !== after.ctimeMs ||
|
|
240
|
+
bytes.byteLength !== before.size) {
|
|
241
|
+
throw new Error("Project-local @git.zone/tsdocker package metadata changed while being read.");
|
|
242
|
+
}
|
|
243
|
+
packageJson = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
throw new Error("Project-local @git.zone/tsdocker package metadata is invalid.", { cause: error });
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
await packageHandle.close();
|
|
250
|
+
}
|
|
251
|
+
if (!isPlainObject(packageJson) ||
|
|
252
|
+
packageJson.name !== "@git.zone/tsdocker" ||
|
|
253
|
+
typeof packageJson.version !== "string" ||
|
|
254
|
+
!supportsTsdockerMinimumVersion(packageJson.version, minimumReleaseVersion)) {
|
|
255
|
+
throw new Error("Docker release journal schema 2 requires project-local @git.zone/tsdocker >= 3.5.1.");
|
|
256
|
+
}
|
|
257
|
+
return packageJson.version;
|
|
258
|
+
}
|
|
259
|
+
assertRequestForProject(requestArg) {
|
|
260
|
+
return plugins.tsdockerReleaseProtocol.assertReleaseQualificationRequestForProject(requestArg, this.cwd);
|
|
261
|
+
}
|
|
262
|
+
assertPromotionInvocation(requestArg, contextArg) {
|
|
263
|
+
return plugins.tsdockerReleaseProtocol.assertReleasePromotionInvocation({
|
|
264
|
+
...contextArg,
|
|
265
|
+
request: requestArg,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
createPromotionRequest(kindArg, requestArg, promotionIdArg) {
|
|
269
|
+
return {
|
|
270
|
+
candidateId: requestArg.candidateId,
|
|
271
|
+
kind: kindArg,
|
|
272
|
+
projectId: requestArg.projectId,
|
|
273
|
+
promotionId: promotionIdArg,
|
|
274
|
+
protocolVersion: 1,
|
|
275
|
+
schemaVersion: 1,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
async assertRequestDirectory(requestDirectoryArg) {
|
|
279
|
+
const requestDirectory = plugins.path.resolve(requestDirectoryArg);
|
|
280
|
+
const directoryStat = await plugins.fs.lstat(requestDirectory);
|
|
281
|
+
const callerUid = process.getuid?.();
|
|
282
|
+
if (!directoryStat.isDirectory() ||
|
|
283
|
+
directoryStat.isSymbolicLink() ||
|
|
284
|
+
(callerUid !== undefined && directoryStat.uid !== callerUid) ||
|
|
285
|
+
(directoryStat.mode & 0o077) !== 0) {
|
|
286
|
+
throw new Error("tSDocker release request storage must be a private owned directory.");
|
|
287
|
+
}
|
|
288
|
+
return requestDirectory;
|
|
289
|
+
}
|
|
290
|
+
async runWithTemporaryRequestDirectory(commandArg, operationArg, assertResultArg) {
|
|
291
|
+
const temporaryRoot = await plugins.fs.realpath(plugins.os.tmpdir());
|
|
292
|
+
const temporaryDirectory = await plugins.fs.mkdtemp(plugins.path.join(temporaryRoot, `gitzone-tsdocker-${commandArg}-`));
|
|
293
|
+
let result;
|
|
294
|
+
let operationError;
|
|
295
|
+
try {
|
|
296
|
+
await plugins.fs.chmod(temporaryDirectory, 0o700);
|
|
297
|
+
result = await operationArg(temporaryDirectory, plugins.crypto.randomBytes(16).toString("hex"));
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
operationError = error;
|
|
301
|
+
}
|
|
302
|
+
let directoryCleanupError;
|
|
303
|
+
try {
|
|
304
|
+
await plugins.fs.rm(temporaryDirectory, {
|
|
305
|
+
recursive: true,
|
|
306
|
+
force: false,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
directoryCleanupError = error;
|
|
311
|
+
}
|
|
312
|
+
if (directoryCleanupError) {
|
|
313
|
+
if (operationError instanceof TsdockerReleaseRequestCleanupError) {
|
|
314
|
+
operationError.reclamationError = directoryCleanupError;
|
|
315
|
+
throw operationError;
|
|
316
|
+
}
|
|
317
|
+
throw new TsdockerReleaseRequestCleanupError(commandArg, temporaryDirectory, operationError, result, directoryCleanupError);
|
|
318
|
+
}
|
|
319
|
+
if (operationError instanceof TsdockerReleaseRequestCleanupError) {
|
|
320
|
+
if (operationError.result !== undefined) {
|
|
321
|
+
return assertResultArg(operationError.result);
|
|
322
|
+
}
|
|
323
|
+
if (operationError.commandError !== undefined) {
|
|
324
|
+
throw operationError.commandError;
|
|
325
|
+
}
|
|
326
|
+
throw operationError;
|
|
327
|
+
}
|
|
328
|
+
if (operationError)
|
|
329
|
+
throw operationError;
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
async run(commandArg, requestArg, requestDirectoryArg, requestOwnerIdArg, extraArgsArg = []) {
|
|
333
|
+
let requestPath = "";
|
|
334
|
+
let requestCreated = false;
|
|
335
|
+
let requestIdentity;
|
|
336
|
+
let commandError;
|
|
337
|
+
let result;
|
|
338
|
+
let hasResult = false;
|
|
339
|
+
try {
|
|
340
|
+
const args = [commandArg];
|
|
341
|
+
if (requestArg !== undefined) {
|
|
342
|
+
if (!requestDirectoryArg ||
|
|
343
|
+
!requestOwnerIdArg ||
|
|
344
|
+
!requestOwnerIdPattern.test(requestOwnerIdArg)) {
|
|
345
|
+
throw new Error("tSDocker release request storage and exact owner are required.");
|
|
346
|
+
}
|
|
347
|
+
const requestDirectory = await this.assertRequestDirectory(requestDirectoryArg);
|
|
348
|
+
requestPath = plugins.path.join(requestDirectory, `.tsdocker-request.${requestOwnerIdArg}.${commandArg}.${plugins.crypto
|
|
349
|
+
.randomBytes(12)
|
|
350
|
+
.toString("hex")}.json`);
|
|
351
|
+
const document = canonicalReleaseJsonDocument(requestArg);
|
|
352
|
+
if (Buffer.byteLength(document) > requestByteLimit) {
|
|
353
|
+
throw new Error("tSDocker release request exceeds 64 KiB.");
|
|
354
|
+
}
|
|
355
|
+
const callerUid = process.getuid?.();
|
|
356
|
+
const handle = await plugins.fs.open(requestPath, plugins.fsConstants.O_WRONLY |
|
|
357
|
+
plugins.fsConstants.O_CREAT |
|
|
358
|
+
plugins.fsConstants.O_EXCL |
|
|
359
|
+
plugins.fsConstants.O_NOFOLLOW, 0o600);
|
|
360
|
+
requestCreated = true;
|
|
361
|
+
try {
|
|
362
|
+
const openedStat = await handle.stat();
|
|
363
|
+
if (!openedStat.isFile() ||
|
|
364
|
+
(callerUid !== undefined && openedStat.uid !== callerUid) ||
|
|
365
|
+
(openedStat.mode & 0o077) !== 0) {
|
|
366
|
+
throw new Error("tSDocker release request file is unsafe.");
|
|
367
|
+
}
|
|
368
|
+
requestIdentity = {
|
|
369
|
+
dev: openedStat.dev,
|
|
370
|
+
ino: openedStat.ino,
|
|
371
|
+
mode: openedStat.mode,
|
|
372
|
+
uid: openedStat.uid,
|
|
373
|
+
};
|
|
374
|
+
await handle.writeFile(document, "utf8");
|
|
375
|
+
await handle.sync();
|
|
376
|
+
const requestStat = await handle.stat();
|
|
377
|
+
if (!requestStat.isFile() ||
|
|
378
|
+
(callerUid !== undefined && requestStat.uid !== callerUid) ||
|
|
379
|
+
(requestStat.mode & 0o077) !== 0 ||
|
|
380
|
+
requestStat.size !== Buffer.byteLength(document)) {
|
|
381
|
+
throw new Error("tSDocker release request file is unsafe.");
|
|
382
|
+
}
|
|
383
|
+
requestIdentity = {
|
|
384
|
+
dev: requestStat.dev,
|
|
385
|
+
ino: requestStat.ino,
|
|
386
|
+
mode: requestStat.mode,
|
|
387
|
+
uid: requestStat.uid,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
await handle.close();
|
|
392
|
+
}
|
|
393
|
+
args.push(`--request-file=${requestPath}`, ...extraArgsArg);
|
|
394
|
+
}
|
|
395
|
+
else if (extraArgsArg.length > 0) {
|
|
396
|
+
throw new Error("tSDocker request flags require a request payload.");
|
|
397
|
+
}
|
|
398
|
+
const commandResult = await this.smartshell.execSpawn(this.binaryPath, args, {
|
|
399
|
+
cwd: this.cwd,
|
|
400
|
+
maxBuffer: responseByteLimit + 1,
|
|
401
|
+
silent: true,
|
|
402
|
+
timeout: commandTimeouts[commandArg],
|
|
403
|
+
timeoutKillGraceMs: commandArg === "release-qualify" || commandArg === "release-promote"
|
|
404
|
+
? 3 * 60_000
|
|
405
|
+
: 30_000,
|
|
406
|
+
});
|
|
407
|
+
result = parseProtocolOutput(commandResult, commandArg);
|
|
408
|
+
hasResult = true;
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
commandError = error;
|
|
412
|
+
}
|
|
413
|
+
let cleanupError;
|
|
414
|
+
if (requestCreated) {
|
|
415
|
+
try {
|
|
416
|
+
if (!requestIdentity) {
|
|
417
|
+
throw new Error("tSDocker release request was created without a cleanup identity.");
|
|
418
|
+
}
|
|
419
|
+
const currentStat = await plugins.fs.lstat(requestPath);
|
|
420
|
+
if (!currentStat.isFile() ||
|
|
421
|
+
currentStat.isSymbolicLink() ||
|
|
422
|
+
currentStat.dev !== requestIdentity.dev ||
|
|
423
|
+
currentStat.ino !== requestIdentity.ino ||
|
|
424
|
+
currentStat.mode !== requestIdentity.mode ||
|
|
425
|
+
currentStat.uid !== requestIdentity.uid) {
|
|
426
|
+
throw new Error("tSDocker release request changed before caller cleanup.");
|
|
427
|
+
}
|
|
428
|
+
await plugins.fs.rm(requestPath);
|
|
429
|
+
}
|
|
430
|
+
catch (error) {
|
|
431
|
+
cleanupError = error;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (cleanupError) {
|
|
435
|
+
throw new TsdockerReleaseRequestCleanupError(commandArg, requestPath, commandError, hasResult ? result : undefined, cleanupError);
|
|
436
|
+
}
|
|
437
|
+
if (commandError)
|
|
438
|
+
throw commandError;
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy50c2RvY2tlcnByb3RvY29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvbW9kX3JlbGVhc2UvaGVscGVycy50c2RvY2tlcnByb3RvY29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbkUsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUE2QnhFLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUNyQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsMEJBQTBCLENBQUM7QUFDN0QsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQ3pDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyw4QkFBOEIsQ0FBQztBQUNqRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FDbkMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLHdCQUF3QixDQUFDO0FBQzNELE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUN2QyxPQUFPLENBQUMsdUJBQXVCLENBQUMsNEJBQTRCLENBQUM7QUFDL0QsTUFBTSxDQUFDLE1BQU0saUNBQWlDLEdBQzVDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxpQ0FBaUMsQ0FBQztBQUNwRSxNQUFNLENBQUMsTUFBTSxnQ0FBZ0MsR0FDM0MsT0FBTyxDQUFDLHVCQUF1QixDQUFDLGdDQUFnQyxDQUFDO0FBQ25FLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUMvQixPQUFPLENBQUMsdUJBQXVCLENBQUMsb0JBQW9CLENBQUM7QUFDdkQsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQ3ZDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyw0QkFBNEIsQ0FBQztBQUMvRCxNQUFNLENBQUMsTUFBTSxnQ0FBZ0MsR0FDM0MsT0FBTyxDQUFDLHVCQUF1QixDQUFDLGdDQUFnQyxDQUFDO0FBQ25F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
|
|
@@ -2,6 +2,6 @@ import type { ICliMode } from "../helpers.climode.js";
|
|
|
2
2
|
import { type IResolvedReleaseWorkflow } from "../helpers.workflow.js";
|
|
3
3
|
export { buildReleaseGitPushArgs } from "./helpers.releasepublication.js";
|
|
4
4
|
export declare const run: (argvArg: any) => Promise<void>;
|
|
5
|
-
type TDockerCommandWorkflow = Pick<IResolvedReleaseWorkflow, "dockerRegistry" | "dockerBuildRegistries" | "dockerTest" | "
|
|
5
|
+
type TDockerCommandWorkflow = Pick<IResolvedReleaseWorkflow, "dockerRegistry" | "dockerBuildRegistries" | "dockerTest" | "dockerCached" | "dockerParallel" | "dockerContext" | "dockerPatterns">;
|
|
6
6
|
export declare function buildTsdockerPushCommand(workflow: TDockerCommandWorkflow): string;
|
|
7
7
|
export declare function showHelp(mode?: ICliMode): void;
|