sandbox-agent/scripts/release/docker.ts

49 lines
1.9 KiB
TypeScript

import { $ } from "execa";
import type { ReleaseOpts } from "./main";
import { fetchGitRef, versionOrCommitToRef } from "./utils";
const IMAGE = "rivetdev/sandbox-agent";
export async function tagDocker(opts: ReleaseOpts) {
// Determine which commit to use for source images
let sourceCommit = opts.commit;
if (opts.reuseEngineVersion) {
console.log(`==> Reusing Docker images from ${opts.reuseEngineVersion}`);
const ref = versionOrCommitToRef(opts.reuseEngineVersion);
await fetchGitRef(ref);
const result = await $`git rev-parse ${ref}`;
sourceCommit = result.stdout.trim().slice(0, 7);
console.log(`==> Source commit: ${sourceCommit}`);
}
// Check both architecture images exist using manifest inspect
console.log(`==> Checking images exist: ${IMAGE}:${sourceCommit}-{amd64,arm64}`);
try {
console.log(`==> Inspecting ${IMAGE}:${sourceCommit}-amd64`);
await $({ stdio: "inherit" })`docker manifest inspect ${IMAGE}:${sourceCommit}-amd64`;
console.log(`==> Inspecting ${IMAGE}:${sourceCommit}-arm64`);
await $({ stdio: "inherit" })`docker manifest inspect ${IMAGE}:${sourceCommit}-arm64`;
console.log(`==> Both images exist`);
} catch (error) {
console.error(`==> Error inspecting images:`, error);
throw new Error(
`Images ${IMAGE}:${sourceCommit}-{amd64,arm64} do not exist on Docker Hub. Error: ${error}`,
);
}
// Create and push manifest with version
await createManifest(sourceCommit, opts.version);
// Create and push manifest with latest
if (opts.latest) {
await createManifest(sourceCommit, "latest");
}
}
async function createManifest(from: string, to: string) {
console.log(`==> Creating manifest: ${IMAGE}:${to} from ${IMAGE}:${from}-{amd64,arm64}`);
// Use buildx imagetools to create and push multi-arch manifest
// This works with manifest lists as inputs (unlike docker manifest create)
await $({ stdio: "inherit" })`docker buildx imagetools create --tag ${IMAGE}:${to} ${IMAGE}:${from}-amd64 ${IMAGE}:${from}-arm64`;
}