Files
Crystal/scripts/image-publication.mjs
kawaandClaude Sonnet 5.5 91d3b9c9f2
Private ROM checks / private-rom (push) Failing after 25m51s
Checks / web (push) Failing after 20s
Publish container image / publish (push) Successful in 54s
Keep the dev tag check strict and default the tag in the workflow
The earlier script default broke the tests that reject empty tags.
The workflow now falls back to dev-<full commit SHA> for manual runs.

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

70 lines
2.2 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 ?? "";
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}`,
);
}