Files
Crystal/scripts/image-publication.mjs
T
kawaandClaude Sonnet 5.5 727f5b0261
Checks / web (push) Failing after 19s
Private ROM checks / private-rom (push) Failing after 1m39s
Default manual image builds to dev-<commit> when no tag is given
A manual run with an empty tag input failed validation. It now uses the
checked-out commit's short SHA, and the workflow input is optional.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 01:15:14 +02:00

70 lines
2.3 KiB
JavaScript

import { appendFileSync } from "node:fs";
import { execFileSync } from "node:child_process";
import { pathToFileURL } from "node:url";
/** Keep manual test builds out of the production channel. */
export function imagePublication({ event, ref, inputTag, revision }) {
if (!/^[0-9a-f]{40}$/.test(revision))
throw new Error("Expected the full SHA-1 of the checked-out commit.");
let tag, channel;
if (event === "workflow_dispatch") {
tag = inputTag || `dev-${revision.slice(0, 7)}`;
const commit = /^dev-([0-9a-f]{7,40})$/.exec(tag)?.[1];
if (!commit || tag !== tag.trim())
throw new Error(
"Manual image tags must be dev-<commit SHA> (7-40 lowercase hex characters).",
);
if (!revision.startsWith(commit))
throw new Error(
"The dev tag does not match the checked-out commit. Select the matching source branch or Git tag.",
);
channel = "dev";
} else if (event === "push" && ref?.startsWith("refs/tags/")) {
tag = ref.slice("refs/tags/".length);
if (
!/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(tag) ||
tag.length > 128 ||
tag !== tag.trim()
)
throw new Error(
"Production requires a stable Git version tag: vMAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH.",
);
channel = "prod";
} else {
throw new Error(
"Image publication requires a version tag push or a manual dev build.",
);
}
return { tag, channel, revision };
}
if (
process.argv[1] &&
import.meta.url === pathToFileURL(process.argv[1]).href
) {
const env = process.env;
const revision = execFileSync("git", ["rev-parse", "HEAD"], {
encoding: "utf8",
}).trim();
const publication = imagePublication({
event: env.EVENT_NAME,
ref: env.GIT_REF,
inputTag: env.INPUT_TAG,
revision,
});
const registry = new URL(env.SERVER_URL).host;
const image = `${registry}/${env.REPOSITORY.toLowerCase()}`;
const source = `${env.SERVER_URL.replace(/\/$/, "")}/${env.REPOSITORY}`;
const outputs = { registry, image, source, ...publication };
appendFileSync(
env.GITHUB_OUTPUT,
Object.entries(outputs)
.map(([key, value]) => `${key}=${value}\n`)
.join(""),
);
console.log(
`Publishing ${image}:${publication.tag} and :${publication.channel} from ${revision}`,
);
}