Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/coolify-deploy.mjs
T

94 lines
3.0 KiB
JavaScript
Executable File

#!/usr/bin/env node
const [, , command, ...args] = process.argv;
const apiUrl = (process.env.SELECTED_COOLIFY_API_URL || process.env.COOLIFY_STAGING_API_URL || process.env.COOLIFY_API_URL || "").replace(/\/+$/, "");
const token = process.env.SELECTED_COOLIFY_TOKEN || process.env.COOLIFY_STAGING_TOKEN || process.env.COOLIFY_TOKEN || "";
const delayMs = Number(process.env.COOLIFY_DEPLOYMENT_POLL_MS || "5000");
const attempts = Number(process.env.COOLIFY_DEPLOYMENT_WAIT_ATTEMPTS || "90");
function fail(message) {
process.stderr.write(`${message}\n`);
process.exit(1);
}
async function coolify(path, options = {}) {
if (!apiUrl || !token) {
fail("Coolify API URL and token are required");
}
const response = await fetch(`${apiUrl}${path}`, {
...options,
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
...(options.body ? { "Content-Type": "application/json" } : {}),
...options.headers,
},
});
const text = await response.text();
let payload = {};
if (text.trim()) {
try {
payload = JSON.parse(text);
} catch {
payload = { message: text.trim() };
}
}
if (!response.ok) {
fail(`Coolify API request failed with HTTP ${response.status}`);
}
return payload;
}
function deploymentStatus(payload) {
return String(payload.status || payload.deployment?.status || payload.data?.status || "unknown").toLowerCase();
}
function deploymentUuid(payload) {
const value = payload.deployment_uuid || payload.uuid || payload.deployment?.uuid || payload.data?.deployment_uuid || payload.data?.uuid || "";
return typeof value === "string" ? value : "";
}
async function trigger(resourceUuid) {
if (!resourceUuid) {
fail("Coolify resource UUID is required");
}
const payload = await coolify(`/applications/${encodeURIComponent(resourceUuid)}/start?force=true&instant_deploy=true`, {
method: "POST",
});
const uuid = deploymentUuid(payload);
if (!uuid) {
fail("Coolify deployment UUID was not returned by the start request");
}
process.stdout.write(uuid);
}
async function waitForDeployment(uuid, label) {
if (!uuid) {
fail("Coolify deployment UUID is required");
}
for (let attempt = 1; attempt <= attempts; attempt += 1) {
const payload = await coolify(`/deployments/${encodeURIComponent(uuid)}`);
const status = deploymentStatus(payload);
process.stdout.write(`${label} deployment status: ${status}\n`);
if (["finished", "success", "succeeded", "completed", "done"].includes(status)) {
return;
}
if (["failed", "error", "cancelled", "canceled"].includes(status)) {
fail(`${label} deployment failed`);
}
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
fail(`${label} deployment did not finish in time`);
}
if (command === "trigger") {
await trigger(args[0] || "");
} else if (command === "wait") {
await waitForDeployment(args[0] || "", args[1] || "Coolify");
} else {
fail("Usage: coolify-deploy.mjs trigger <resource-uuid> | wait <deployment-uuid> <label>");
}