A static nginx image (unprivileged, read-only) of the production build, published to Gitea's registry for amd64 and arm64: version tags go to prod, manual dev-<commit> builds to dev, each smoke-tested first and optionally announced to Dockhand. The README describes running it with Docker Compose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
import { createHmac } from "node:crypto";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
export async function notifyDockhand({ url, secret }, send = fetch) {
|
|
if (!url && !secret) return false;
|
|
if (!url || !secret)
|
|
throw new Error(
|
|
"Configure both Dockhand webhook URL and secret for this channel.",
|
|
);
|
|
const target = new URL(url);
|
|
if (!["http:", "https:"].includes(target.protocol))
|
|
throw new Error("Dockhand webhook requires an HTTP(S) URL.");
|
|
const body = "{}";
|
|
const signature = createHmac("sha256", secret).update(body).digest("hex");
|
|
const response = await send(target, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-Hub-Signature-256": `sha256=${signature}`,
|
|
},
|
|
body,
|
|
redirect: "error",
|
|
signal: AbortSignal.timeout(60_000),
|
|
});
|
|
if (!response.ok)
|
|
throw new Error(
|
|
`Dockhand rejected the deployment request (HTTP ${response.status}).`,
|
|
);
|
|
return true;
|
|
}
|
|
|
|
if (
|
|
process.argv[1] &&
|
|
import.meta.url === pathToFileURL(process.argv[1]).href
|
|
) {
|
|
try {
|
|
const sent = await notifyDockhand({
|
|
url: process.env.DOCKHAND_WEBHOOK_URL,
|
|
secret: process.env.DOCKHAND_WEBHOOK_SECRET,
|
|
});
|
|
console.log(
|
|
sent
|
|
? "Dockhand deployment requested. Check the stack's deployment status in Dockhand."
|
|
: "Dockhand webhook not configured for this channel; image publication is complete.",
|
|
);
|
|
} catch {
|
|
// Do not print the URL, secret or server response into the job log.
|
|
console.error(
|
|
"Dockhand deployment request failed. The image was already published; check this channel's webhook configuration and connectivity.",
|
|
);
|
|
process.exitCode = 1;
|
|
}
|
|
}
|