@git.zone/cli 6.8.0 → 6.10.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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/helpers.workflow.d.ts +23 -1
- package/dist_ts/helpers.workflow.js +93 -3
- package/dist_ts/mod_config/index.js +49 -7
- package/dist_ts/mod_release/classes.releasejournal.d.ts +20 -1
- package/dist_ts/mod_release/classes.releasejournal.js +191 -9
- package/dist_ts/mod_release/helpers.giteaassets.d.ts +36 -0
- package/dist_ts/mod_release/helpers.giteaassets.js +661 -0
- package/dist_ts/mod_release/helpers.npmartifact.d.ts +5 -4
- package/dist_ts/mod_release/helpers.npmartifact.js +36 -9
- package/dist_ts/mod_release/helpers.releasepublication.d.ts +4 -1
- package/dist_ts/mod_release/helpers.releasepublication.js +151 -8
- package/dist_ts/mod_release/index.d.ts +2 -0
- package/dist_ts/mod_release/index.js +98 -17
- package/dist_ts/mod_release/interfaces.giteaassets.d.ts +50 -0
- package/dist_ts/mod_release/interfaces.giteaassets.js +2 -0
- package/package.json +3 -3
- package/readme.md +107 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/helpers.workflow.ts +154 -3
- package/ts/mod_config/index.ts +61 -6
- package/ts/mod_release/classes.releasejournal.ts +298 -14
- package/ts/mod_release/helpers.giteaassets.ts +932 -0
- package/ts/mod_release/helpers.npmartifact.ts +58 -12
- package/ts/mod_release/helpers.releasepublication.ts +230 -4
- package/ts/mod_release/index.ts +129 -13
- package/ts/mod_release/interfaces.giteaassets.ts +67 -0
|
@@ -9,6 +9,7 @@ const supportedPnpmVersions = [
|
|
|
9
9
|
"11.25.0",
|
|
10
10
|
"12.1.0",
|
|
11
11
|
"12.2.1",
|
|
12
|
+
"12.3.0",
|
|
12
13
|
"12.3.4",
|
|
13
14
|
] as const;
|
|
14
15
|
const pnpmHelpRequirements = {
|
|
@@ -49,6 +50,19 @@ const pnpmHelpRequirements = {
|
|
|
49
50
|
"[possible values: public, restricted]",
|
|
50
51
|
],
|
|
51
52
|
},
|
|
53
|
+
"12.3.0": {
|
|
54
|
+
pack: ["Usage: pnpm pack [OPTIONS]", "--out <OUT>", "--json"],
|
|
55
|
+
publish: [
|
|
56
|
+
"Usage: pnpm publish [OPTIONS] [PACKAGE]",
|
|
57
|
+
"Tarball or directory to publish",
|
|
58
|
+
"--no-git-checks",
|
|
59
|
+
"--ignore-scripts",
|
|
60
|
+
"--json",
|
|
61
|
+
"--tag <TAG>",
|
|
62
|
+
"--access <ACCESS>",
|
|
63
|
+
"[possible values: public, restricted]",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
52
66
|
"12.3.4": {
|
|
53
67
|
pack: ["Usage: pnpm pack [OPTIONS]", "--out <OUT>", "--json"],
|
|
54
68
|
publish: [
|
|
@@ -77,9 +91,24 @@ export function assertNpmPackageName(value: unknown): asserts value is string {
|
|
|
77
91
|
}
|
|
78
92
|
|
|
79
93
|
export interface IPnpmReleaseCapability {
|
|
80
|
-
version: (typeof supportedPnpmVersions)[number];
|
|
94
|
+
readonly version: (typeof supportedPnpmVersions)[number];
|
|
81
95
|
}
|
|
82
96
|
|
|
97
|
+
export const buildQualifiedPnpmArgs = (
|
|
98
|
+
capabilityArg: IPnpmReleaseCapability | undefined,
|
|
99
|
+
argsArg: readonly string[],
|
|
100
|
+
): string[] => {
|
|
101
|
+
if (
|
|
102
|
+
!capabilityArg ||
|
|
103
|
+
!supportedPnpmVersions.includes(capabilityArg.version)
|
|
104
|
+
) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"npm release commands require a qualified pnpm invocation.",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return ["with", capabilityArg.version, ...argsArg];
|
|
110
|
+
};
|
|
111
|
+
|
|
83
112
|
export type TNpmArtifactProbeStatus =
|
|
84
113
|
"absent" | "exact" | "conflict" | "inconclusive";
|
|
85
114
|
|
|
@@ -169,21 +198,28 @@ export const assertPnpmReleaseCapability = async (
|
|
|
169
198
|
);
|
|
170
199
|
}
|
|
171
200
|
const requirements = pnpmHelpRequirements[supportedVersion];
|
|
201
|
+
const capability = Object.freeze({ version: supportedVersion });
|
|
172
202
|
|
|
173
|
-
const packHelp = await smartshellArg.execSpawn(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
203
|
+
const packHelp = await smartshellArg.execSpawn(
|
|
204
|
+
"pnpm",
|
|
205
|
+
buildQualifiedPnpmArgs(capability, ["pack", "--help"]),
|
|
206
|
+
{
|
|
207
|
+
cwd: cwdArg,
|
|
208
|
+
silent: true,
|
|
209
|
+
timeout: capabilityCommandTimeoutMs,
|
|
210
|
+
timeoutKillGraceMs: 5_000,
|
|
211
|
+
},
|
|
212
|
+
);
|
|
179
213
|
if (packHelp.exitCode !== 0) {
|
|
180
|
-
throw new Error(
|
|
214
|
+
throw new Error(
|
|
215
|
+
"Unable to inspect the selected pnpm pack capabilities. Exact release commands require standalone pnpm with support; Corepack launchers are unsupported.",
|
|
216
|
+
);
|
|
181
217
|
}
|
|
182
218
|
requireHelpFragments(packHelp.combinedOutput, requirements.pack, "pack");
|
|
183
219
|
|
|
184
220
|
const publishHelp = await smartshellArg.execSpawn(
|
|
185
221
|
"pnpm",
|
|
186
|
-
["publish", "--help"],
|
|
222
|
+
buildQualifiedPnpmArgs(capability, ["publish", "--help"]),
|
|
187
223
|
{
|
|
188
224
|
cwd: cwdArg,
|
|
189
225
|
silent: true,
|
|
@@ -199,7 +235,7 @@ export const assertPnpmReleaseCapability = async (
|
|
|
199
235
|
requirements.publish,
|
|
200
236
|
"publish",
|
|
201
237
|
);
|
|
202
|
-
return
|
|
238
|
+
return capability;
|
|
203
239
|
};
|
|
204
240
|
|
|
205
241
|
/**
|
|
@@ -358,6 +394,7 @@ export const packNpmArtifact = async (
|
|
|
358
394
|
cwdArg: string,
|
|
359
395
|
destinationDirectoryArg: string,
|
|
360
396
|
expectedVersionArg: string,
|
|
397
|
+
capabilityArg: IPnpmReleaseCapability | undefined,
|
|
361
398
|
fileArg: string = releaseArtifactFileName,
|
|
362
399
|
): Promise<IReleaseArtifact> => {
|
|
363
400
|
if (
|
|
@@ -375,7 +412,12 @@ export const packNpmArtifact = async (
|
|
|
375
412
|
const artifactPath = plugins.path.join(destinationDirectoryArg, fileArg);
|
|
376
413
|
const result = await smartshellArg.execSpawn(
|
|
377
414
|
"pnpm",
|
|
378
|
-
|
|
415
|
+
buildQualifiedPnpmArgs(capabilityArg, [
|
|
416
|
+
"pack",
|
|
417
|
+
"--out",
|
|
418
|
+
artifactPath,
|
|
419
|
+
"--json",
|
|
420
|
+
]),
|
|
379
421
|
{
|
|
380
422
|
cwd: cwdArg,
|
|
381
423
|
timeout: packCommandTimeoutMs,
|
|
@@ -470,10 +512,14 @@ export const publishNpmArtifact = async (
|
|
|
470
512
|
cwdArg: string,
|
|
471
513
|
artifactPathArg: string,
|
|
472
514
|
registryArg: string,
|
|
515
|
+
capabilityArg: IPnpmReleaseCapability | undefined,
|
|
473
516
|
): Promise<{ exitCode: number; output: string }> => {
|
|
474
517
|
const result = await smartshellArg.execSpawn(
|
|
475
518
|
"pnpm",
|
|
476
|
-
|
|
519
|
+
buildQualifiedPnpmArgs(
|
|
520
|
+
capabilityArg,
|
|
521
|
+
buildPnpmPublishArgs(artifactPathArg, registryArg),
|
|
522
|
+
),
|
|
477
523
|
{
|
|
478
524
|
cwd: cwdArg,
|
|
479
525
|
timeout: publishCommandTimeoutMs,
|
|
@@ -7,17 +7,27 @@ import {
|
|
|
7
7
|
getReleaseDockerPromotionContext,
|
|
8
8
|
getReleaseArtifacts,
|
|
9
9
|
getReleaseNpmArtifact,
|
|
10
|
+
hasReleasePackages,
|
|
10
11
|
type TReleaseJournal,
|
|
11
12
|
type IReleaseJournalV2,
|
|
13
|
+
type IReleaseJournalV4,
|
|
12
14
|
type IReleaseTargetStatus,
|
|
13
15
|
type TReleaseErrorCode,
|
|
14
16
|
type TReleaseTargetState,
|
|
15
17
|
} from "./classes.releasejournal.js";
|
|
18
|
+
import {
|
|
19
|
+
GiteaAssetsClient,
|
|
20
|
+
GiteaAssetConflictError,
|
|
21
|
+
validateGiteaAssets,
|
|
22
|
+
} from "./helpers.giteaassets.js";
|
|
23
|
+
import { assertGiteaAssetsGitDestination } from "../helpers.workflow.js";
|
|
16
24
|
import {
|
|
17
25
|
probeAnonymousNpmArtifact,
|
|
18
26
|
publishNpmArtifact,
|
|
19
27
|
verifyStoredNpmArtifact,
|
|
20
28
|
waitForAnonymousNpmArtifact,
|
|
29
|
+
buildQualifiedPnpmArgs,
|
|
30
|
+
type IPnpmReleaseCapability,
|
|
21
31
|
type INpmArtifactProbeOptions,
|
|
22
32
|
type INpmArtifactProbeResult,
|
|
23
33
|
} from "./helpers.npmartifact.js";
|
|
@@ -73,6 +83,8 @@ export function buildReleaseGitPushArgs(
|
|
|
73
83
|
|
|
74
84
|
type TReleaseTargetSelector =
|
|
75
85
|
| { kind: "git" }
|
|
86
|
+
| { kind: "gitea-release" }
|
|
87
|
+
| { kind: "gitea-asset"; name: string }
|
|
76
88
|
| { kind: "npm"; registry: string; packageName?: string }
|
|
77
89
|
| { kind: "docker-qualification" }
|
|
78
90
|
| { kind: "docker-promotion"; promotionId: string }
|
|
@@ -85,6 +97,7 @@ interface IGitProbeResult {
|
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
export interface IReleasePublicationOptions {
|
|
100
|
+
pnpmCapability?: IPnpmReleaseCapability;
|
|
88
101
|
smartshell: plugins.smartshell.Smartshell;
|
|
89
102
|
cwd: string;
|
|
90
103
|
store: ReleaseJournalStore;
|
|
@@ -93,6 +106,15 @@ export interface IReleasePublicationOptions {
|
|
|
93
106
|
recoveryAttemptId?: string;
|
|
94
107
|
npmProbeOptions?: INpmArtifactProbeOptions;
|
|
95
108
|
tsdocker?: ITsdockerReleaseClient;
|
|
109
|
+
giteaAssets?: Pick<
|
|
110
|
+
GiteaAssetsClient,
|
|
111
|
+
| "preflight"
|
|
112
|
+
| "inspectRelease"
|
|
113
|
+
| "createRelease"
|
|
114
|
+
| "inspectAssets"
|
|
115
|
+
| "uploadAsset"
|
|
116
|
+
| "verifyComplete"
|
|
117
|
+
>;
|
|
96
118
|
ensurePublicationState: (expectedRemoteMainOidArg?: string) => Promise<void>;
|
|
97
119
|
}
|
|
98
120
|
|
|
@@ -103,6 +125,20 @@ const getTargetStatus = (
|
|
|
103
125
|
if (selectorArg.kind === "git") {
|
|
104
126
|
return journalArg.git;
|
|
105
127
|
}
|
|
128
|
+
if (
|
|
129
|
+
selectorArg.kind === "gitea-release" ||
|
|
130
|
+
selectorArg.kind === "gitea-asset"
|
|
131
|
+
) {
|
|
132
|
+
if (journalArg.schemaVersion !== 4)
|
|
133
|
+
throw new Error("Release journal has no Gitea assets.");
|
|
134
|
+
if (selectorArg.kind === "gitea-release")
|
|
135
|
+
return journalArg.giteaAssets.release;
|
|
136
|
+
const entry = journalArg.giteaAssets.assets.find(
|
|
137
|
+
(entry) => entry.asset.name === selectorArg.name,
|
|
138
|
+
);
|
|
139
|
+
if (!entry) throw new Error("Release journal has no matching Gitea asset.");
|
|
140
|
+
return entry;
|
|
141
|
+
}
|
|
106
142
|
if (selectorArg.kind === "docker-qualification") {
|
|
107
143
|
if (journalArg.schemaVersion !== 2) {
|
|
108
144
|
throw new Error("Release journal does not contain Docker qualification.");
|
|
@@ -613,7 +649,7 @@ const executeNpmRegistry = async (
|
|
|
613
649
|
// the accepted artifact on resume. Older root/Docker journal behavior stays
|
|
614
650
|
// unchanged.
|
|
615
651
|
if (
|
|
616
|
-
journal
|
|
652
|
+
hasReleasePackages(journal) &&
|
|
617
653
|
status.state === "failed" &&
|
|
618
654
|
status.attempts > 0 &&
|
|
619
655
|
status.error === "verification-inconclusive" &&
|
|
@@ -689,7 +725,7 @@ const executeNpmRegistry = async (
|
|
|
689
725
|
}
|
|
690
726
|
if (probe.status !== "absent") {
|
|
691
727
|
if (
|
|
692
|
-
journal
|
|
728
|
+
hasReleasePackages(journal) &&
|
|
693
729
|
status.state === "failed" &&
|
|
694
730
|
probe.status === "inconclusive"
|
|
695
731
|
) {
|
|
@@ -713,12 +749,15 @@ const executeNpmRegistry = async (
|
|
|
713
749
|
artifact.file,
|
|
714
750
|
);
|
|
715
751
|
await verifyStoredNpmArtifact(artifactPath, artifact);
|
|
752
|
+
// Reject a missing invocation before claiming a potentially publishing target.
|
|
753
|
+
buildQualifiedPnpmArgs(optionsArg.pnpmCapability, []);
|
|
716
754
|
journal = await claimTarget(optionsArg.store, journal, selector);
|
|
717
755
|
const publishResult = await publishNpmArtifact(
|
|
718
756
|
optionsArg.smartshell,
|
|
719
757
|
optionsArg.cwd,
|
|
720
758
|
artifactPath,
|
|
721
759
|
registryArg,
|
|
760
|
+
optionsArg.pnpmCapability,
|
|
722
761
|
);
|
|
723
762
|
probe = await probeNpm(
|
|
724
763
|
journal,
|
|
@@ -1426,6 +1465,165 @@ const executeDockerPromotion = async (
|
|
|
1426
1465
|
);
|
|
1427
1466
|
};
|
|
1428
1467
|
|
|
1468
|
+
const executeGiteaTarget = async (
|
|
1469
|
+
options: IReleasePublicationOptions,
|
|
1470
|
+
journalArg: TReleaseJournal,
|
|
1471
|
+
selector: TReleaseTargetSelector,
|
|
1472
|
+
inspect: () => Promise<boolean>,
|
|
1473
|
+
publish: () => Promise<void>,
|
|
1474
|
+
onVerified?: (target: IReleaseTargetStatus) => void,
|
|
1475
|
+
): Promise<TReleaseJournal> => {
|
|
1476
|
+
let journal = journalArg;
|
|
1477
|
+
let status = getTargetStatus(journal, selector);
|
|
1478
|
+
if (status.state === "conflict")
|
|
1479
|
+
throw new Error("Gitea publication has a recorded destination conflict.");
|
|
1480
|
+
const mark = async (
|
|
1481
|
+
state: "verified" | "failed" | "conflict",
|
|
1482
|
+
error: TReleaseErrorCode | null,
|
|
1483
|
+
) => {
|
|
1484
|
+
status = getTargetStatus(journal, selector);
|
|
1485
|
+
journal = await updateTarget(
|
|
1486
|
+
options.store,
|
|
1487
|
+
journal,
|
|
1488
|
+
selector,
|
|
1489
|
+
status.state,
|
|
1490
|
+
status.attempt?.id || null,
|
|
1491
|
+
(target) => {
|
|
1492
|
+
target.state = state;
|
|
1493
|
+
target.error = error;
|
|
1494
|
+
target.attempt = null;
|
|
1495
|
+
if (state === "verified") onVerified?.(target);
|
|
1496
|
+
},
|
|
1497
|
+
);
|
|
1498
|
+
};
|
|
1499
|
+
let present: boolean;
|
|
1500
|
+
try {
|
|
1501
|
+
present = await inspect();
|
|
1502
|
+
} catch (error) {
|
|
1503
|
+
if (error instanceof GiteaAssetConflictError)
|
|
1504
|
+
await mark("conflict", "destination-conflict");
|
|
1505
|
+
throw error;
|
|
1506
|
+
}
|
|
1507
|
+
if (present) {
|
|
1508
|
+
if (status.state !== "verified") await mark("verified", null);
|
|
1509
|
+
return journal;
|
|
1510
|
+
}
|
|
1511
|
+
if (status.state === "verified") {
|
|
1512
|
+
await mark("conflict", "destination-conflict");
|
|
1513
|
+
throw new Error(
|
|
1514
|
+
"A previously verified Gitea release or attachment is missing.",
|
|
1515
|
+
);
|
|
1516
|
+
}
|
|
1517
|
+
if (status.state === "publishing") {
|
|
1518
|
+
journal = await recoverPublishingTarget(
|
|
1519
|
+
options.store,
|
|
1520
|
+
journal,
|
|
1521
|
+
selector,
|
|
1522
|
+
options.recoveryAttemptId,
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
await options.ensurePublicationState(journal.release.mainOid);
|
|
1526
|
+
journal = await claimTarget(options.store, journal, selector);
|
|
1527
|
+
// One mutation per claimed attempt. Reconcile an accepted request even when
|
|
1528
|
+
// its response was lost; never overwrite an attachment or recreate a tag.
|
|
1529
|
+
let publicationError: unknown;
|
|
1530
|
+
try {
|
|
1531
|
+
await publish();
|
|
1532
|
+
} catch (error) {
|
|
1533
|
+
publicationError = error;
|
|
1534
|
+
}
|
|
1535
|
+
try {
|
|
1536
|
+
present = await inspect();
|
|
1537
|
+
} catch (error) {
|
|
1538
|
+
await mark(
|
|
1539
|
+
error instanceof GiteaAssetConflictError ? "conflict" : "failed",
|
|
1540
|
+
error instanceof GiteaAssetConflictError
|
|
1541
|
+
? "destination-conflict"
|
|
1542
|
+
: "verification-inconclusive",
|
|
1543
|
+
);
|
|
1544
|
+
throw error;
|
|
1545
|
+
}
|
|
1546
|
+
if (present) {
|
|
1547
|
+
await mark("verified", null);
|
|
1548
|
+
return journal;
|
|
1549
|
+
}
|
|
1550
|
+
await mark(
|
|
1551
|
+
publicationError instanceof GiteaAssetConflictError ? "conflict" : "failed",
|
|
1552
|
+
publicationError instanceof GiteaAssetConflictError
|
|
1553
|
+
? "destination-conflict"
|
|
1554
|
+
: publicationError
|
|
1555
|
+
? "command-failed"
|
|
1556
|
+
: "verification-inconclusive",
|
|
1557
|
+
);
|
|
1558
|
+
throw new Error(
|
|
1559
|
+
"Gitea publication could not be verified; npm publication remains blocked. Inspect the retained journal before resuming.",
|
|
1560
|
+
);
|
|
1561
|
+
};
|
|
1562
|
+
|
|
1563
|
+
const executeGiteaAssets = async (
|
|
1564
|
+
options: IReleasePublicationOptions,
|
|
1565
|
+
journalArg: IReleaseJournalV4,
|
|
1566
|
+
client: NonNullable<IReleasePublicationOptions["giteaAssets"]>,
|
|
1567
|
+
): Promise<IReleaseJournalV4> => {
|
|
1568
|
+
let releaseId = journalArg.giteaAssets.release.id;
|
|
1569
|
+
let journal = (await executeGiteaTarget(
|
|
1570
|
+
options,
|
|
1571
|
+
journalArg,
|
|
1572
|
+
{ kind: "gitea-release" },
|
|
1573
|
+
async () => {
|
|
1574
|
+
const release = await client.inspectRelease();
|
|
1575
|
+
if (!release) return false;
|
|
1576
|
+
if (releaseId !== null && release.id !== releaseId)
|
|
1577
|
+
throw new GiteaAssetConflictError("Gitea release identity changed.");
|
|
1578
|
+
releaseId = release.id;
|
|
1579
|
+
return true;
|
|
1580
|
+
},
|
|
1581
|
+
async () => {
|
|
1582
|
+
await client.createRelease();
|
|
1583
|
+
},
|
|
1584
|
+
(target) => {
|
|
1585
|
+
(target as IReleaseJournalV4["giteaAssets"]["release"]).id = releaseId;
|
|
1586
|
+
},
|
|
1587
|
+
)) as IReleaseJournalV4;
|
|
1588
|
+
if (releaseId === null)
|
|
1589
|
+
throw new Error("Gitea release has no verified identity.");
|
|
1590
|
+
const expected = journal.giteaAssets.assets.map((entry) => entry.asset);
|
|
1591
|
+
const directory = options.store.getReleaseDirectory(journal.release.version);
|
|
1592
|
+
for (const { asset } of journal.giteaAssets.assets) {
|
|
1593
|
+
journal = (await executeGiteaTarget(
|
|
1594
|
+
options,
|
|
1595
|
+
journal,
|
|
1596
|
+
{ kind: "gitea-asset", name: asset.name },
|
|
1597
|
+
async () => {
|
|
1598
|
+
const inspection = await client.inspectAssets(releaseId!, expected);
|
|
1599
|
+
return inspection.present.some((entry) => entry.name === asset.name);
|
|
1600
|
+
},
|
|
1601
|
+
async () => {
|
|
1602
|
+
await validateGiteaAssets(directory, expected);
|
|
1603
|
+
await client.uploadAsset(releaseId!, asset, directory);
|
|
1604
|
+
},
|
|
1605
|
+
)) as IReleaseJournalV4;
|
|
1606
|
+
}
|
|
1607
|
+
// One full anonymous verification immediately before entering the npm phase.
|
|
1608
|
+
// Resume always repeats it, including an otherwise completed journal.
|
|
1609
|
+
try {
|
|
1610
|
+
await client.verifyComplete(releaseId, expected);
|
|
1611
|
+
} catch (error) {
|
|
1612
|
+
if (error instanceof GiteaAssetConflictError) {
|
|
1613
|
+
await markUnclaimedTarget(
|
|
1614
|
+
options.store,
|
|
1615
|
+
journal,
|
|
1616
|
+
{ kind: "gitea-release" },
|
|
1617
|
+
["verified"],
|
|
1618
|
+
"conflict",
|
|
1619
|
+
"destination-conflict",
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
throw error;
|
|
1623
|
+
}
|
|
1624
|
+
return journal;
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1429
1627
|
export const executeReleasePublication = async (
|
|
1430
1628
|
optionsArg: IReleasePublicationOptions,
|
|
1431
1629
|
): Promise<TReleaseJournal> => {
|
|
@@ -1437,6 +1635,32 @@ export const executeReleasePublication = async (
|
|
|
1437
1635
|
artifact,
|
|
1438
1636
|
);
|
|
1439
1637
|
}
|
|
1638
|
+
let giteaClient = optionsArg.giteaAssets;
|
|
1639
|
+
if (journal.schemaVersion === 4) {
|
|
1640
|
+
const { destination, tokenEnv, manifestPath, assets } = journal.giteaAssets;
|
|
1641
|
+
assertGiteaAssetsGitDestination(
|
|
1642
|
+
{ ...destination, tokenEnv, manifestPath },
|
|
1643
|
+
optionsArg.pushUrl || "",
|
|
1644
|
+
);
|
|
1645
|
+
await validateGiteaAssets(
|
|
1646
|
+
optionsArg.store.getReleaseDirectory(journal.release.version),
|
|
1647
|
+
assets.map((entry) => entry.asset),
|
|
1648
|
+
);
|
|
1649
|
+
if (!giteaClient) {
|
|
1650
|
+
const token = process.env[tokenEnv];
|
|
1651
|
+
if (!token)
|
|
1652
|
+
throw new Error(
|
|
1653
|
+
`Gitea assets require the configured credential in ${tokenEnv}.`,
|
|
1654
|
+
);
|
|
1655
|
+
giteaClient = new GiteaAssetsClient({
|
|
1656
|
+
destination,
|
|
1657
|
+
token,
|
|
1658
|
+
tag: journal.release.tag,
|
|
1659
|
+
commit: journal.release.mainOid,
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
await giteaClient.preflight();
|
|
1663
|
+
}
|
|
1440
1664
|
if (journal.schemaVersion === 2) {
|
|
1441
1665
|
journal = await executeDockerQualification(optionsArg, journal);
|
|
1442
1666
|
if (
|
|
@@ -1447,6 +1671,8 @@ export const executeReleasePublication = async (
|
|
|
1447
1671
|
}
|
|
1448
1672
|
}
|
|
1449
1673
|
journal = await executeGitTarget(optionsArg, journal);
|
|
1674
|
+
if (journal.schemaVersion === 4)
|
|
1675
|
+
journal = await executeGiteaAssets(optionsArg, journal, giteaClient!);
|
|
1450
1676
|
const expectedRemoteMainOid =
|
|
1451
1677
|
journal.git.state === "verified"
|
|
1452
1678
|
? journal.release.mainOid
|
|
@@ -1458,12 +1684,12 @@ export const executeReleasePublication = async (
|
|
|
1458
1684
|
journal,
|
|
1459
1685
|
registry.registry,
|
|
1460
1686
|
registry.packageName,
|
|
1461
|
-
journal
|
|
1687
|
+
hasReleasePackages(journal),
|
|
1462
1688
|
);
|
|
1463
1689
|
}
|
|
1464
1690
|
// Submit in dependency order before waiting for npm's publish-time scans.
|
|
1465
1691
|
// Success still requires every package/registry cell to verify exactly.
|
|
1466
|
-
if (journal
|
|
1692
|
+
if (hasReleasePackages(journal)) {
|
|
1467
1693
|
for (const registry of journal.npm.registries) {
|
|
1468
1694
|
if (
|
|
1469
1695
|
registry.state !== "failed" ||
|