@kb-labs/release-manager-core 2.118.2 → 2.119.0-canary.0b4b21a55
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/index.d.ts +87 -4
- package/dist/index.js +160 -25
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -357,6 +357,14 @@ interface ChangelogGenerator {
|
|
|
357
357
|
repoRoot: string;
|
|
358
358
|
gitCwd: string;
|
|
359
359
|
config: ReleaseConfig;
|
|
360
|
+
/** Named flow whose release tag pattern bounds the changelog. */
|
|
361
|
+
flow?: string;
|
|
362
|
+
/** Explicit git boundaries; these take precedence over the flow baseline. */
|
|
363
|
+
range?: {
|
|
364
|
+
from?: string;
|
|
365
|
+
to?: string;
|
|
366
|
+
sinceTag?: string;
|
|
367
|
+
};
|
|
360
368
|
}): Promise<string>;
|
|
361
369
|
}
|
|
362
370
|
interface PipelineOptions {
|
|
@@ -656,6 +664,60 @@ declare function resolveFlowFromTag(config: ReleaseConfig, tag: string): {
|
|
|
656
664
|
channel: ReleaseChannel;
|
|
657
665
|
} | null;
|
|
658
666
|
|
|
667
|
+
/**
|
|
668
|
+
* Release status — a read-only "what is actually true right now" view for a
|
|
669
|
+
* flow, cross-checking the surfaces that the 2026-08-13 release-system audit
|
|
670
|
+
* found drifting apart independently: the latest stable git tag, and the
|
|
671
|
+
* real npm dist-tags packages currently resolve to.
|
|
672
|
+
*
|
|
673
|
+
* This does not replace the receipt/state-machine model from the breaking
|
|
674
|
+
* control-plane cutover plan — it is the cheap, non-breaking piece of that
|
|
675
|
+
* diagnosis that can ship today: make "a tag/npm entry exists" and "this was
|
|
676
|
+
* actually verified and promoted" visibly different without any new storage.
|
|
677
|
+
*/
|
|
678
|
+
|
|
679
|
+
interface NpmDistTagInfo {
|
|
680
|
+
name: string;
|
|
681
|
+
stableVersion: string | null;
|
|
682
|
+
canaryVersion: string | null;
|
|
683
|
+
error?: string;
|
|
684
|
+
}
|
|
685
|
+
interface StableTagInfo {
|
|
686
|
+
tag: string | null;
|
|
687
|
+
version: string | null;
|
|
688
|
+
commit: string | null;
|
|
689
|
+
committedAt: string | null;
|
|
690
|
+
}
|
|
691
|
+
interface FlowReleaseStatus {
|
|
692
|
+
flow: string;
|
|
693
|
+
packages: string[];
|
|
694
|
+
git: StableTagInfo;
|
|
695
|
+
npm: {
|
|
696
|
+
registry: string;
|
|
697
|
+
stableDistTag: string;
|
|
698
|
+
canaryDistTag: string;
|
|
699
|
+
perPackage: NpmDistTagInfo[];
|
|
700
|
+
/** Agreed version across all sampled packages, or null if they disagree or none resolved. */
|
|
701
|
+
stableVersion: string | null;
|
|
702
|
+
canaryVersion: string | null;
|
|
703
|
+
stableDrift: boolean;
|
|
704
|
+
canaryDrift: boolean;
|
|
705
|
+
};
|
|
706
|
+
verdict: {
|
|
707
|
+
ok: boolean;
|
|
708
|
+
warnings: string[];
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
interface ComputeFlowReleaseStatusOptions {
|
|
712
|
+
cwd: string;
|
|
713
|
+
config: ReleaseConfig;
|
|
714
|
+
flow: string;
|
|
715
|
+
shell: ShellAPI;
|
|
716
|
+
/** How many of the flow's packages to sample against npm. Lockstep flows only need enough to detect drift. Default 3. */
|
|
717
|
+
maxPackagesToCheck?: number;
|
|
718
|
+
}
|
|
719
|
+
declare function computeFlowReleaseStatus(opts: ComputeFlowReleaseStatusOptions): Promise<FlowReleaseStatus>;
|
|
720
|
+
|
|
659
721
|
/**
|
|
660
722
|
* Unified release pipeline — single orchestrator for CLI and REST.
|
|
661
723
|
*
|
|
@@ -744,12 +806,26 @@ declare function runReleaseChecks(checks: CustomCheckConfig[], options: CheckRun
|
|
|
744
806
|
declare function verifyPackages(packages: PackageVersion[], options?: {
|
|
745
807
|
logger?: Pick<PluginLogger, 'info'>;
|
|
746
808
|
onProgress?: (pkg: string, result: VerifyResult) => void;
|
|
809
|
+
packageManager?: 'pnpm' | 'npm' | 'yarn';
|
|
747
810
|
}): Promise<VerifyResult[]>;
|
|
748
811
|
/**
|
|
749
812
|
* Verify a single package is publishable.
|
|
750
|
-
*
|
|
751
|
-
|
|
752
|
-
|
|
813
|
+
* pack → extract → check exports, directory imports, test leaks, syntax.
|
|
814
|
+
*
|
|
815
|
+
* Packing tool must match what the real publish step will actually use:
|
|
816
|
+
* `pnpm pack` resolves `workspace:`/`link:` protocol refs to real version
|
|
817
|
+
* ranges natively (confirmed: `pnpm pack` on a package with
|
|
818
|
+
* `peerDependencies: { "@kb-labs/sdk": "workspace:^" }` produces a tarball
|
|
819
|
+
* with `"@kb-labs/sdk": "^2.115.4"`). `npm pack` does not — it packs the
|
|
820
|
+
* manifest byte-for-byte, so an unrewritten `workspace:*`/`link:` ref
|
|
821
|
+
* survives into the tarball and gets correctly flagged by
|
|
822
|
+
* findForbiddenDependencyProtocols() below. Defaulting to 'npm' here when
|
|
823
|
+
* the caller doesn't say otherwise is deliberately the strict reading (catch
|
|
824
|
+
* it even if we don't know yet what will actually publish); passing 'pnpm'
|
|
825
|
+
* for a pipeline that really does pack with pnpm avoids false positives on
|
|
826
|
+
* refs pnpm already resolves for free.
|
|
827
|
+
*/
|
|
828
|
+
declare function verifyPackage(packagePath: string, packageName?: string, packageManager?: 'pnpm' | 'npm' | 'yarn'): VerifyResult;
|
|
753
829
|
/**
|
|
754
830
|
* Run the static artifact checks (test-file leaks, exports existence,
|
|
755
831
|
* directory-import detection, syntax validation) against an already
|
|
@@ -798,6 +874,13 @@ interface VerifyAgainstRegistryOptions {
|
|
|
798
874
|
* Default: 0 (single attempt, matches pre-existing Verdaccio behavior).
|
|
799
875
|
*/
|
|
800
876
|
retries?: number;
|
|
877
|
+
/**
|
|
878
|
+
* Total time to wait for npm metadata and tarballs to propagate after a
|
|
879
|
+
* publish. When provided this supersedes the legacy fixed retry count, so
|
|
880
|
+
* an idempotent re-run resumes verification of already-published tarballs
|
|
881
|
+
* instead of requiring a new publish or a workflow-owned sleep.
|
|
882
|
+
*/
|
|
883
|
+
visibilityDeadlineMs?: number;
|
|
801
884
|
retryDelaysMs?: readonly number[];
|
|
802
885
|
logger?: Pick<PluginLogger, 'info' | 'warn'>;
|
|
803
886
|
}
|
|
@@ -858,4 +941,4 @@ declare function verifyCleanInstall(tarballPath: string, packageName: string, ad
|
|
|
858
941
|
*/
|
|
859
942
|
declare function resolveScopePath(repoRoot: string, scope: string): Promise<string>;
|
|
860
943
|
|
|
861
|
-
export { type AuditSummary, type BuildConfig, type BuildResult, CHECKS_CONCURRENCY, type ChangelogGenerator, type CheckId, type CheckResult, type CheckResultDetails, type CleanInstallResult, type CustomCheckConfig, DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, type FlowConfig, type PackagePublisher, type PackageVersion, type PackagesFilter, type PipelineOptions, type PipelineResult, type PlannerOptions, type PluginLogger, type PublishResult, type PublishablePackage, type ReleaseChannel, type ReleaseConfig, type ReleaseContext, type ReleasePlan, type ReleaseReport, type ReleaseResult, type ReleaseShell, type ReleaseStage, type RollbackSnapshot, type StrategyOptions, type VerifyResult, type VersionBump, type VersionStrategy, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, findForbiddenDependencyProtocols, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyCleanInstall, verifyExtractedTarball, verifyPackage, verifyPackages };
|
|
944
|
+
export { type AuditSummary, type BuildConfig, type BuildResult, CHECKS_CONCURRENCY, type ChangelogGenerator, type CheckId, type CheckResult, type CheckResultDetails, type CleanInstallResult, type ComputeFlowReleaseStatusOptions, type CustomCheckConfig, DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, type FlowConfig, type FlowReleaseStatus, type NpmDistTagInfo, type PackagePublisher, type PackageVersion, type PackagesFilter, type PipelineOptions, type PipelineResult, type PlannerOptions, type PluginLogger, type PublishResult, type PublishablePackage, type ReleaseChannel, type ReleaseConfig, type ReleaseContext, type ReleasePlan, type ReleaseReport, type ReleaseResult, type ReleaseShell, type ReleaseStage, type RollbackSnapshot, type StableTagInfo, type StrategyOptions, type VerifyResult, type VersionBump, type VersionStrategy, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, computeFlowReleaseStatus, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, findForbiddenDependencyProtocols, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyCleanInstall, verifyExtractedTarball, verifyPackage, verifyPackages };
|
package/dist/index.js
CHANGED
|
@@ -1050,6 +1050,133 @@ function resolvePublishRegistry(config, channel) {
|
|
|
1050
1050
|
}
|
|
1051
1051
|
return config.registry ?? DEFAULT_NPM_REGISTRY;
|
|
1052
1052
|
}
|
|
1053
|
+
|
|
1054
|
+
// src/status.ts
|
|
1055
|
+
var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)/;
|
|
1056
|
+
function compareSemver(a, b) {
|
|
1057
|
+
const ma = a.match(SEMVER_RE);
|
|
1058
|
+
const mb = b.match(SEMVER_RE);
|
|
1059
|
+
if (!ma || !mb) {
|
|
1060
|
+
return 0;
|
|
1061
|
+
}
|
|
1062
|
+
for (let i = 1; i <= 3; i++) {
|
|
1063
|
+
const diff = Number(ma[i]) - Number(mb[i]);
|
|
1064
|
+
if (diff !== 0) {
|
|
1065
|
+
return diff;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
return 0;
|
|
1069
|
+
}
|
|
1070
|
+
function escapeRegex2(str) {
|
|
1071
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1072
|
+
}
|
|
1073
|
+
async function fetchDistTags(name, registry) {
|
|
1074
|
+
try {
|
|
1075
|
+
const encoded = name.startsWith("@") ? `@${encodeURIComponent(name.slice(1))}` : name;
|
|
1076
|
+
const url = `${registry.replace(/\/$/, "")}/${encoded}`;
|
|
1077
|
+
const res = await fetch(url, {
|
|
1078
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" },
|
|
1079
|
+
signal: AbortSignal.timeout(8e3)
|
|
1080
|
+
});
|
|
1081
|
+
if (!res.ok) {
|
|
1082
|
+
return { error: `HTTP ${res.status}` };
|
|
1083
|
+
}
|
|
1084
|
+
const body = await res.json();
|
|
1085
|
+
return body["dist-tags"] ?? {};
|
|
1086
|
+
} catch (err) {
|
|
1087
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
async function findLatestStableTag(shell, cwd, flowName, tagPattern) {
|
|
1091
|
+
const empty = { tag: null, version: null, commit: null, committedAt: null };
|
|
1092
|
+
const prefix = tagPattern.split("{version}")[0]?.replace("{flow}", flowName) ?? `${flowName}-v`;
|
|
1093
|
+
const listRes = await shell.exec("git", ["tag", "-l", `${prefix}*`], { cwd });
|
|
1094
|
+
const tags = listRes.stdout.split("\n").map((t) => t.trim()).filter(Boolean);
|
|
1095
|
+
if (tags.length === 0) {
|
|
1096
|
+
return empty;
|
|
1097
|
+
}
|
|
1098
|
+
const versionRe = new RegExp(`^${escapeRegex2(prefix)}(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$`);
|
|
1099
|
+
const parsed = tags.map((t) => ({ tag: t, version: t.match(versionRe)?.[1] })).filter((t) => Boolean(t.version));
|
|
1100
|
+
if (parsed.length === 0) {
|
|
1101
|
+
return empty;
|
|
1102
|
+
}
|
|
1103
|
+
parsed.sort((a, b) => compareSemver(a.version, b.version));
|
|
1104
|
+
const latest = parsed[parsed.length - 1];
|
|
1105
|
+
const [shaRes, dateRes] = await Promise.all([
|
|
1106
|
+
shell.exec("git", ["rev-list", "-n", "1", latest.tag], { cwd }),
|
|
1107
|
+
shell.exec("git", ["log", "-1", "--format=%cI", latest.tag], { cwd })
|
|
1108
|
+
]);
|
|
1109
|
+
return {
|
|
1110
|
+
tag: latest.tag,
|
|
1111
|
+
version: latest.version,
|
|
1112
|
+
commit: shaRes.stdout.trim() || null,
|
|
1113
|
+
committedAt: dateRes.stdout.trim() || null
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
async function computeFlowReleaseStatus(opts) {
|
|
1117
|
+
const { cwd, config, flow, shell, maxPackagesToCheck = 3 } = opts;
|
|
1118
|
+
const flowConfig = mergeConfigWithFlow(config, flow);
|
|
1119
|
+
const tagPattern = config.flows?.[flow]?.tagPattern ?? DEFAULT_TAG_PATTERN;
|
|
1120
|
+
const packages = await discoverCurrentPackages(cwd, void 0, flowConfig);
|
|
1121
|
+
const registry = resolvePublishRegistry(config, "canary");
|
|
1122
|
+
const stableDistTag = resolvePublishTag(config, "stable");
|
|
1123
|
+
const canaryDistTag = resolvePublishTag(config, "canary");
|
|
1124
|
+
const sampled = packages.slice(0, maxPackagesToCheck);
|
|
1125
|
+
const perPackage = [];
|
|
1126
|
+
for (const pkg of sampled) {
|
|
1127
|
+
const result = await fetchDistTags(pkg.name, registry);
|
|
1128
|
+
if ("error" in result) {
|
|
1129
|
+
perPackage.push({ name: pkg.name, stableVersion: null, canaryVersion: null, error: result.error });
|
|
1130
|
+
} else {
|
|
1131
|
+
perPackage.push({
|
|
1132
|
+
name: pkg.name,
|
|
1133
|
+
stableVersion: result[stableDistTag] ?? null,
|
|
1134
|
+
canaryVersion: result[canaryDistTag] ?? null
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
const stableVersions = new Set(perPackage.map((p) => p.stableVersion).filter((v) => Boolean(v)));
|
|
1139
|
+
const canaryVersions = new Set(perPackage.map((p) => p.canaryVersion).filter((v) => Boolean(v)));
|
|
1140
|
+
const git = await findLatestStableTag(shell, cwd, flow, tagPattern);
|
|
1141
|
+
const warnings = [];
|
|
1142
|
+
if (stableVersions.size > 1) {
|
|
1143
|
+
warnings.push(`Packages disagree on npm "${stableDistTag}" version: ${[...stableVersions].join(", ")}`);
|
|
1144
|
+
}
|
|
1145
|
+
if (canaryVersions.size > 1) {
|
|
1146
|
+
warnings.push(`Packages disagree on npm "${canaryDistTag}" version: ${[...canaryVersions].join(", ")}`);
|
|
1147
|
+
}
|
|
1148
|
+
const stableVersion = stableVersions.size === 1 ? [...stableVersions][0] : null;
|
|
1149
|
+
const canaryVersion = canaryVersions.size === 1 ? [...canaryVersions][0] : null;
|
|
1150
|
+
if (git.version && stableVersion && git.version !== stableVersion) {
|
|
1151
|
+
warnings.push(
|
|
1152
|
+
`Latest git tag ${git.tag} (${git.version}) does not match npm "${stableDistTag}" (${stableVersion})`
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
if (stableVersion && canaryVersion && compareSemver(canaryVersion, stableVersion) > 0) {
|
|
1156
|
+
warnings.push(
|
|
1157
|
+
`npm "${canaryDistTag}" (${canaryVersion}) is ahead of "${stableDistTag}" (${stableVersion}) \u2014 treat as an unverified candidate, not a release, until it has a green delivery + smoke run and has been explicitly promoted`
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
return {
|
|
1161
|
+
flow,
|
|
1162
|
+
packages: packages.map((p) => p.name),
|
|
1163
|
+
git,
|
|
1164
|
+
npm: {
|
|
1165
|
+
registry,
|
|
1166
|
+
stableDistTag,
|
|
1167
|
+
canaryDistTag,
|
|
1168
|
+
perPackage,
|
|
1169
|
+
stableVersion,
|
|
1170
|
+
canaryVersion,
|
|
1171
|
+
stableDrift: stableVersions.size > 1,
|
|
1172
|
+
canaryDrift: canaryVersions.size > 1
|
|
1173
|
+
},
|
|
1174
|
+
verdict: {
|
|
1175
|
+
ok: warnings.length === 0,
|
|
1176
|
+
warnings
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1053
1180
|
function buildIntraDeps(packages, nameSet) {
|
|
1054
1181
|
const deps = /* @__PURE__ */ new Map();
|
|
1055
1182
|
for (const pkg of packages) {
|
|
@@ -1287,13 +1414,13 @@ function evaluateParser(check, stdout, stderr, exitCode) {
|
|
|
1287
1414
|
async function verifyPackages(packages, options) {
|
|
1288
1415
|
const results = [];
|
|
1289
1416
|
for (const pkg of packages) {
|
|
1290
|
-
const result = verifyPackage(pkg.path, pkg.name);
|
|
1417
|
+
const result = verifyPackage(pkg.path, pkg.name, options?.packageManager);
|
|
1291
1418
|
results.push(result);
|
|
1292
1419
|
options?.onProgress?.(pkg.name, result);
|
|
1293
1420
|
}
|
|
1294
1421
|
return results;
|
|
1295
1422
|
}
|
|
1296
|
-
function verifyPackage(packagePath, packageName) {
|
|
1423
|
+
function verifyPackage(packagePath, packageName, packageManager = "npm") {
|
|
1297
1424
|
const pkgJsonPath = join(packagePath, "package.json");
|
|
1298
1425
|
if (!existsSync(pkgJsonPath)) {
|
|
1299
1426
|
return { name: packageName ?? packagePath, success: true, issues: [] };
|
|
@@ -1310,23 +1437,26 @@ function verifyPackage(packagePath, packageName) {
|
|
|
1310
1437
|
const tmpDir = join(tmpdir(), `kb-verify-${randomBytes(6).toString("hex")}`);
|
|
1311
1438
|
try {
|
|
1312
1439
|
mkdirSync(tmpDir, { recursive: true });
|
|
1440
|
+
const isPnpm = packageManager === "pnpm";
|
|
1313
1441
|
const origPkg = readFileSync(pkgJsonPath, "utf-8");
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1442
|
+
if (!isPnpm) {
|
|
1443
|
+
const modPkg = JSON.parse(origPkg);
|
|
1444
|
+
for (const section of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
1445
|
+
const deps = modPkg[section];
|
|
1446
|
+
if (!deps) {
|
|
1447
|
+
continue;
|
|
1448
|
+
}
|
|
1449
|
+
for (const [k, v] of Object.entries(deps)) {
|
|
1450
|
+
if (typeof v === "string" && v.startsWith("link:")) {
|
|
1451
|
+
deps[k] = "*";
|
|
1452
|
+
}
|
|
1323
1453
|
}
|
|
1324
1454
|
}
|
|
1455
|
+
writeFileSync(pkgJsonPath, JSON.stringify(modPkg, null, 2) + "\n");
|
|
1325
1456
|
}
|
|
1326
|
-
writeFileSync(pkgJsonPath, JSON.stringify(modPkg, null, 2) + "\n");
|
|
1327
1457
|
let tgzFile;
|
|
1328
1458
|
try {
|
|
1329
|
-
spawnSync("npm", ["pack", "--pack-destination", tmpDir], { cwd: packagePath, stdio: "pipe", timeout: 3e4 });
|
|
1459
|
+
spawnSync(isPnpm ? "pnpm" : "npm", ["pack", "--pack-destination", tmpDir], { cwd: packagePath, stdio: "pipe", timeout: 3e4 });
|
|
1330
1460
|
const files = readdirSync(tmpDir).filter((f) => f.endsWith(".tgz"));
|
|
1331
1461
|
tgzFile = files[0] ? join(tmpDir, files[0]) : void 0;
|
|
1332
1462
|
} finally {
|
|
@@ -1483,31 +1613,35 @@ async function verifyAgainstRegistry(packages, options) {
|
|
|
1483
1613
|
const { registry, timeout = DEFAULT_TIMEOUT_MS, retries = 0, retryDelaysMs = DEFAULT_POLL_RETRY_DELAYS_MS, logger } = options;
|
|
1484
1614
|
const results = [];
|
|
1485
1615
|
for (const pkg of packages) {
|
|
1486
|
-
results.push(await verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, logger));
|
|
1616
|
+
results.push(await verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, options.visibilityDeadlineMs, logger));
|
|
1487
1617
|
}
|
|
1488
1618
|
return results;
|
|
1489
1619
|
}
|
|
1490
|
-
async function waitUntilPublished(pkg, registry, retries, retryDelaysMs, logger) {
|
|
1491
|
-
|
|
1620
|
+
async function waitUntilPublished(pkg, registry, retries, retryDelaysMs, visibilityDeadlineMs, logger) {
|
|
1621
|
+
const deadline = visibilityDeadlineMs === void 0 ? void 0 : Date.now() + visibilityDeadlineMs;
|
|
1622
|
+
for (let attempt = 0; deadline === void 0 ? attempt <= retries : Date.now() <= deadline; attempt++) {
|
|
1492
1623
|
if (await isVersionPublished(pkg.name, pkg.version, registry)) {
|
|
1493
1624
|
return true;
|
|
1494
1625
|
}
|
|
1495
|
-
if (attempt < retries) {
|
|
1626
|
+
if (deadline === void 0 ? attempt < retries : Date.now() < deadline) {
|
|
1496
1627
|
const delay = retryDelaysMs[Math.min(attempt, retryDelaysMs.length - 1)];
|
|
1628
|
+
const remaining = deadline === void 0 ? void 0 : deadline - Date.now();
|
|
1629
|
+
const waitMs = remaining === void 0 ? delay : Math.min(delay, Math.max(0, remaining));
|
|
1497
1630
|
logger?.warn?.(
|
|
1498
|
-
`${pkg.name}@${pkg.version} not yet visible on ${registry} (attempt ${attempt + 1}
|
|
1631
|
+
`${pkg.name}@${pkg.version} not yet visible on ${registry} (attempt ${attempt + 1}${deadline === void 0 ? `/${retries + 1}` : ""}), retrying in ${(waitMs / 1e3).toFixed(0)}s${remaining === void 0 ? "" : `; ${(Math.max(0, remaining) / 1e3).toFixed(0)}s remain`} \u2014 likely registry propagation lag`
|
|
1499
1632
|
);
|
|
1500
1633
|
await new Promise((r) => {
|
|
1501
|
-
setTimeout(r,
|
|
1634
|
+
setTimeout(r, waitMs);
|
|
1502
1635
|
});
|
|
1503
1636
|
}
|
|
1504
1637
|
}
|
|
1505
1638
|
return false;
|
|
1506
1639
|
}
|
|
1507
|
-
async function verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, logger) {
|
|
1508
|
-
const published = await waitUntilPublished(pkg, registry, retries, retryDelaysMs, logger);
|
|
1640
|
+
async function verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, visibilityDeadlineMs, logger) {
|
|
1641
|
+
const published = await waitUntilPublished(pkg, registry, retries, retryDelaysMs, visibilityDeadlineMs, logger);
|
|
1509
1642
|
if (!published) {
|
|
1510
|
-
|
|
1643
|
+
const waited = visibilityDeadlineMs === void 0 ? `waited through ${retries} retr${retries === 1 ? "y" : "ies"}` : `visibility deadline of ${(visibilityDeadlineMs / 1e3).toFixed(0)}s elapsed`;
|
|
1644
|
+
return { name: pkg.name, success: false, issues: [`${pkg.name}@${pkg.version} was not found on ${registry} after publish (${waited})`] };
|
|
1511
1645
|
}
|
|
1512
1646
|
logger?.info?.(`${pkg.name}@${pkg.version} confirmed on ${registry}`);
|
|
1513
1647
|
const tmpDir = join(tmpdir(), `kb-verdaccio-verify-${randomBytes(6).toString("hex")}`);
|
|
@@ -1809,7 +1943,8 @@ async function _runPipeline(ctx) {
|
|
|
1809
1943
|
}
|
|
1810
1944
|
if (!skipVerify && !dryRun) {
|
|
1811
1945
|
progress("verifying", "Verifying package artifacts...");
|
|
1812
|
-
const
|
|
1946
|
+
const packageManager = config.workspace?.type ?? config.publish?.packageManager ?? "pnpm";
|
|
1947
|
+
const verifyResults = await verifyPackages(plan.packages, { logger, packageManager });
|
|
1813
1948
|
const verifyFailed = verifyResults.filter((r) => !r.success);
|
|
1814
1949
|
if (verifyFailed.length > 0) {
|
|
1815
1950
|
await restoreSnapshot(repoRoot);
|
|
@@ -1851,7 +1986,7 @@ async function _runPipeline(ctx) {
|
|
|
1851
1986
|
if (changelogGen && channel === "stable") {
|
|
1852
1987
|
progress("versioning", "Generating changelog...");
|
|
1853
1988
|
try {
|
|
1854
|
-
changelogMd = await changelogGen.generate(plan, { repoRoot, gitCwd: scopeCwd, config });
|
|
1989
|
+
changelogMd = await changelogGen.generate(plan, { repoRoot, gitCwd: scopeCwd, config, flow });
|
|
1855
1990
|
} catch (err) {
|
|
1856
1991
|
logger?.warn?.(`Changelog generation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1857
1992
|
}
|
|
@@ -2093,6 +2228,6 @@ async function resolveScopePath(repoRoot, scope) {
|
|
|
2093
2228
|
return join(repoRoot, scope);
|
|
2094
2229
|
}
|
|
2095
2230
|
|
|
2096
|
-
export { CHECKS_CONCURRENCY, DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, findForbiddenDependencyProtocols, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyCleanInstall, verifyExtractedTarball, verifyPackage, verifyPackages };
|
|
2231
|
+
export { CHECKS_CONCURRENCY, DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, computeFlowReleaseStatus, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, findForbiddenDependencyProtocols, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyCleanInstall, verifyExtractedTarball, verifyPackage, verifyPackages };
|
|
2097
2232
|
//# sourceMappingURL=index.js.map
|
|
2098
2233
|
//# sourceMappingURL=index.js.map
|