mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(release): accept complete core tarball manifests (#112813)
* fix(release): consume complete core tarball manifest * fix(release): declare core tarball selector
This commit is contained in:
committed by
GitHub
parent
8ef067a216
commit
79d4e4a3ad
@@ -456,6 +456,14 @@ jobs:
|
|||||||
const path = require("node:path");
|
const path = require("node:path");
|
||||||
const [manifestPath, packageDir] = process.argv.slice(2);
|
const [manifestPath, packageDir] = process.argv.slice(2);
|
||||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
||||||
|
const dependencyTarballs = Array.isArray(manifest.corePackageTarballs)
|
||||||
|
? manifest.corePackageTarballs
|
||||||
|
: manifest.corePackageTarballs === undefined && Array.isArray(manifest.dependencyTarballs)
|
||||||
|
? manifest.dependencyTarballs
|
||||||
|
: null;
|
||||||
|
if (!dependencyTarballs) {
|
||||||
|
throw new Error("package artifact manifest is missing dependency tarball metadata");
|
||||||
|
}
|
||||||
const entries = [
|
const entries = [
|
||||||
{
|
{
|
||||||
packageName: "openclaw",
|
packageName: "openclaw",
|
||||||
@@ -463,7 +471,7 @@ jobs:
|
|||||||
tarballName: manifest.tarballName,
|
tarballName: manifest.tarballName,
|
||||||
tarballSha256: manifest.tarballSha256,
|
tarballSha256: manifest.tarballSha256,
|
||||||
},
|
},
|
||||||
...(Array.isArray(manifest.dependencyTarballs) ? manifest.dependencyTarballs : []),
|
...dependencyTarballs,
|
||||||
];
|
];
|
||||||
const packageNames = new Set();
|
const packageNames = new Set();
|
||||||
const tarballNames = new Set();
|
const tarballNames = new Set();
|
||||||
|
|||||||
@@ -185,6 +185,15 @@ export function requireRunIdFromDispatchOutput(output: unknown, workflowFile: un
|
|||||||
*/
|
*/
|
||||||
export function buildPublishCommand(options: unknown): string;
|
export function buildPublishCommand(options: unknown): string;
|
||||||
export function validatePreflightManifest(manifest: unknown, params: unknown): void;
|
export function validatePreflightManifest(manifest: unknown, params: unknown): void;
|
||||||
|
export function preflightCorePackageTarballs(manifest: {
|
||||||
|
corePackageTarballs?: unknown;
|
||||||
|
dependencyTarballs?: unknown;
|
||||||
|
}): Array<{
|
||||||
|
packageName: string;
|
||||||
|
packageVersion: string;
|
||||||
|
tarballName: string;
|
||||||
|
tarballSha256: string;
|
||||||
|
}>;
|
||||||
export function validateFullManifest(manifest: unknown, params: unknown): void;
|
export function validateFullManifest(manifest: unknown, params: unknown): void;
|
||||||
export function validateTrustedToolingPin({
|
export function validateTrustedToolingPin({
|
||||||
toolingSha,
|
toolingSha,
|
||||||
|
|||||||
@@ -1200,10 +1200,7 @@ export function validatePreflightManifest(manifest, params) {
|
|||||||
if (!manifest.tarballName || !manifest.tarballSha256) {
|
if (!manifest.tarballName || !manifest.tarballSha256) {
|
||||||
throw new Error("npm preflight manifest missing tarball metadata");
|
throw new Error("npm preflight manifest missing tarball metadata");
|
||||||
}
|
}
|
||||||
if (!Array.isArray(manifest.dependencyTarballs)) {
|
for (const dependency of preflightCorePackageTarballs(manifest)) {
|
||||||
throw new Error("npm preflight manifest missing dependency tarball metadata");
|
|
||||||
}
|
|
||||||
for (const dependency of manifest.dependencyTarballs) {
|
|
||||||
if (
|
if (
|
||||||
!dependency?.packageName ||
|
!dependency?.packageName ||
|
||||||
!dependency.packageVersion ||
|
!dependency.packageVersion ||
|
||||||
@@ -1216,6 +1213,17 @@ export function validatePreflightManifest(manifest, params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function preflightCorePackageTarballs(manifest) {
|
||||||
|
const hasCorePackageTarballs = Object.hasOwn(manifest, "corePackageTarballs");
|
||||||
|
const tarballs = hasCorePackageTarballs
|
||||||
|
? manifest.corePackageTarballs
|
||||||
|
: manifest.dependencyTarballs;
|
||||||
|
if (!Array.isArray(tarballs)) {
|
||||||
|
throw new Error("npm preflight manifest missing dependency tarball metadata");
|
||||||
|
}
|
||||||
|
return tarballs;
|
||||||
|
}
|
||||||
|
|
||||||
export function validateFullManifest(manifest, params) {
|
export function validateFullManifest(manifest, params) {
|
||||||
if (manifest.workflowName !== "Full Release Validation") {
|
if (manifest.workflowName !== "Full Release Validation") {
|
||||||
throw new Error(`full validation workflow mismatch: ${manifest.workflowName}`);
|
throw new Error(`full validation workflow mismatch: ${manifest.workflowName}`);
|
||||||
@@ -1534,7 +1542,7 @@ async function main() {
|
|||||||
`prepared tarball digest mismatch: expected ${npmManifest.tarballSha256}, got ${actualTarballSha}`,
|
`prepared tarball digest mismatch: expected ${npmManifest.tarballSha256}, got ${actualTarballSha}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const dependencyTarballPaths = npmManifest.dependencyTarballs.map((dependency) => {
|
const dependencyTarballPaths = preflightCorePackageTarballs(npmManifest).map((dependency) => {
|
||||||
const dependencyPath = join(npmDir, dependency.tarballName);
|
const dependencyPath = join(npmDir, dependency.tarballName);
|
||||||
if (!existsSync(dependencyPath)) {
|
if (!existsSync(dependencyPath)) {
|
||||||
throw new Error(`prepared dependency tarball missing: ${dependencyPath}`);
|
throw new Error(`prepared dependency tarball missing: ${dependencyPath}`);
|
||||||
|
|||||||
@@ -3187,6 +3187,8 @@ describe("package artifact reuse", () => {
|
|||||||
'candidate_manifest="${package_dir}/package-candidate.json"',
|
'candidate_manifest="${package_dir}/package-candidate.json"',
|
||||||
'find "${package_dir}" -type f -name "*.tgz"',
|
'find "${package_dir}" -type f -name "*.tgz"',
|
||||||
"package artifact manifest contains duplicate package metadata",
|
"package artifact manifest contains duplicate package metadata",
|
||||||
|
"Array.isArray(manifest.corePackageTarballs)",
|
||||||
|
"manifest.corePackageTarballs === undefined",
|
||||||
"package artifact tarball set does not match preflight manifest",
|
"package artifact tarball set does not match preflight manifest",
|
||||||
"package candidate manifest does not match the OpenClaw tarball",
|
"package candidate manifest does not match the OpenClaw tarball",
|
||||||
"Package Telegram artifact SHA-256 differs from package_sha256.",
|
"Package Telegram artifact SHA-256 differs from package_sha256.",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
isDirectReleaseCandidateExecution,
|
isDirectReleaseCandidateExecution,
|
||||||
parseArgs,
|
parseArgs,
|
||||||
parseRunIdFromDispatchOutput,
|
parseRunIdFromDispatchOutput,
|
||||||
|
preflightCorePackageTarballs,
|
||||||
reconcileReleaseCandidateState,
|
reconcileReleaseCandidateState,
|
||||||
releaseBranchForTag,
|
releaseBranchForTag,
|
||||||
resolveArtifactName,
|
resolveArtifactName,
|
||||||
@@ -589,6 +590,37 @@ describe("release candidate checklist", () => {
|
|||||||
).toThrow("invalid dependency tarball metadata");
|
).toThrow("invalid dependency tarball metadata");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("prefers the complete core package tarball set with legacy manifest fallback", () => {
|
||||||
|
const legacyTarball = {
|
||||||
|
packageName: "@openclaw/ai",
|
||||||
|
packageVersion: "2026.7.1-beta.3",
|
||||||
|
tarballName: "openclaw-ai-2026.7.1-beta.3.tgz",
|
||||||
|
tarballSha256: "ai-sha",
|
||||||
|
};
|
||||||
|
const gatewayProtocolTarball = {
|
||||||
|
packageName: "@openclaw/gateway-protocol",
|
||||||
|
packageVersion: "2026.7.1-beta.3",
|
||||||
|
tarballName: "openclaw-gateway-protocol-2026.7.1-beta.3.tgz",
|
||||||
|
tarballSha256: "protocol-sha",
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
preflightCorePackageTarballs({
|
||||||
|
corePackageTarballs: [legacyTarball, gatewayProtocolTarball],
|
||||||
|
dependencyTarballs: [legacyTarball],
|
||||||
|
}),
|
||||||
|
).toEqual([legacyTarball, gatewayProtocolTarball]);
|
||||||
|
expect(preflightCorePackageTarballs({ dependencyTarballs: [legacyTarball] })).toEqual([
|
||||||
|
legacyTarball,
|
||||||
|
]);
|
||||||
|
expect(() =>
|
||||||
|
preflightCorePackageTarballs({
|
||||||
|
corePackageTarballs: null,
|
||||||
|
dependencyTarballs: [legacyTarball],
|
||||||
|
}),
|
||||||
|
).toThrow("missing dependency tarball metadata");
|
||||||
|
});
|
||||||
|
|
||||||
it("trusts the npm workflow SHA while binding the candidate through its manifest", () => {
|
it("trusts the npm workflow SHA while binding the candidate through its manifest", () => {
|
||||||
const workflowSha = "a".repeat(40);
|
const workflowSha = "a".repeat(40);
|
||||||
const isTrustedWorkflowAncestor = vi.fn(() => true);
|
const isTrustedWorkflowAncestor = vi.fn(() => true);
|
||||||
|
|||||||
Reference in New Issue
Block a user