Build and archive the tested frontend, upload it through dedicated FTPS credentials, and atomically activate it through cPanel after CI succeeds.
48 lines
1.6 KiB
JavaScript
48 lines
1.6 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
import { DeploymentError } from "./cpanel-deploy-lib.mjs";
|
|
import { auditRoot, readRootConfig, restoreRoot } from "./cpanel-root-lib.mjs";
|
|
|
|
async function writeReport(report) {
|
|
const reportPath = process.env.CPANEL_ROOT_REPORT_PATH;
|
|
if (!reportPath) return;
|
|
await fs.mkdir(path.dirname(reportPath), { recursive: true });
|
|
await fs.writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`);
|
|
}
|
|
|
|
async function main() {
|
|
const mode = process.argv[2] || "audit";
|
|
if (!new Set(["audit", "restore"]).has(mode) || process.argv.length > 3) {
|
|
throw new DeploymentError("Usage: cpanel-root.mjs [audit|restore]");
|
|
}
|
|
const config = readRootConfig(process.env);
|
|
if (mode === "audit") {
|
|
const report = await auditRoot(config);
|
|
await writeReport(report);
|
|
console.log(JSON.stringify(report, null, 2));
|
|
if (process.env.GITHUB_OUTPUT) {
|
|
await fs.appendFile(
|
|
process.env.GITHUB_OUTPUT,
|
|
`healthy=${report.healthy}\nstate_token=${report.stateToken}\nrecovery_count=${report.recoveryCandidates.length}\n`
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
const result = await restoreRoot(
|
|
config,
|
|
process.env.CPANEL_ROOT_RECOVERY || "",
|
|
process.env.CPANEL_ROOT_STATE_TOKEN || "",
|
|
process.env.CPANEL_ROOT_CONFIRMATION || ""
|
|
);
|
|
await writeReport(result);
|
|
console.log(`Restored ${result.restored}; retained displaced state as ${result.displaced}.`);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error instanceof Error ? error.message : "Unknown cPanel root failure.");
|
|
process.exit(1);
|
|
});
|