Files
api/plugin/builder/cli/setup-plugin-environment.ts
Eli Bosley 5958d33fce chore: cleanup the cleanup scripts (#1266)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Updated the plugin installation endpoint to use a new port for
improved connectivity.
- Streamlined installation and removal processes for a more reliable
setup and clearer cleanup feedback.
- Introduced a new script to manage cleanup operations, enhancing system
maintenance during removals.
- **Chores**
- Expanded file monitoring to support additional file types, ensuring
timely updates.
- Optimized background operations that configure essential components
for enhanced overall performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-03-24 12:35:25 -04:00

123 lines
4.0 KiB
TypeScript

import { z } from "zod";
import { access, constants, readFile } from "node:fs/promises";
import { Command } from "commander";
import { getStagingChangelogFromGit } from "../utils/changelog";
import { createHash } from "node:crypto";
import { getTxzPath } from "../utils/paths";
const safeParseEnvSchema = z.object({
ci: z.boolean().optional(),
baseUrl: z.string().url(),
tag: z.string().optional().default(''),
txzPath: z.string().refine((val) => val.endsWith(".txz"), {
message: "TXZ Path must end with .txz",
}),
pluginVersion: z.string().regex(/^\d{4}\.\d{2}\.\d{2}\.\d{4}$/, {
message: "Plugin version must be in the format YYYY.MM.DD.HHMM",
}),
releaseNotesPath: z.string().optional(),
});
const pluginEnvSchema = safeParseEnvSchema.extend({
releaseNotes: z.string().nonempty("Release notes are required"),
txzSha256: z.string().refine((val) => val.length === 64, {
message: "TXZ SHA256 must be 64 characters long",
}),
});
export type PluginEnv = z.infer<typeof pluginEnvSchema>;
export const validatePluginEnv = async (
envArgs: Record<string, any>
): Promise<PluginEnv> => {
const safeEnv = safeParseEnvSchema.parse(envArgs);
if (safeEnv.releaseNotesPath) {
await access(safeEnv.releaseNotesPath, constants.F_OK);
const releaseNotes = await readFile(safeEnv.releaseNotesPath, "utf8");
if (!releaseNotes || releaseNotes.length === 0) {
throw new Error(
`Release notes file is empty: ${safeEnv.releaseNotesPath}`
);
}
envArgs.releaseNotes = releaseNotes;
} else {
envArgs.releaseNotes =
process.env.TEST === "true"
? "FAST_TEST_CHANGELOG"
: await getStagingChangelogFromGit(safeEnv);
}
if (safeEnv.txzPath) {
await access(safeEnv.txzPath, constants.F_OK);
console.log("Reading txz file from:", safeEnv.txzPath);
const txzFile = await readFile(safeEnv.txzPath);
if (!txzFile || txzFile.length === 0) {
throw new Error(`TXZ Path is empty: ${safeEnv.txzPath}`);
}
envArgs.txzSha256 = getSha256(txzFile);
}
const validatedEnv = pluginEnvSchema.parse(envArgs);
if (validatedEnv.tag) {
console.warn("Tag is set, will generate a TAGGED build");
}
return validatedEnv;
};
export const getPluginVersion = () => {
const now = new Date();
const formatUtcComponent = (component: number) => String(component).padStart(2, '0');
const year = now.getUTCFullYear();
const month = formatUtcComponent(now.getUTCMonth() + 1);
const day = formatUtcComponent(now.getUTCDate());
const hour = formatUtcComponent(now.getUTCHours());
const minute = formatUtcComponent(now.getUTCMinutes());
const version = `${year}.${month}.${day}.${hour}${minute}`;
console.log("Plugin version:", version);
return version;
};
export const setupPluginEnv = async (argv: string[]): Promise<PluginEnv> => {
// CLI setup for plugin environment
const program = new Command();
program
.requiredOption(
"--base-url <url>",
"Base URL - will be used to determine the bucket, and combined with the tag (if set) to form the final URL",
process.env.CI === "true"
? "This is a CI build, please set the base URL manually"
: `http://${process.env.HOST_LAN_IP}:5858`
)
.option(
"--txz-path <path>",
"Path to built package, will be used to generate the SHA256 and renamed with the plugin version",
getTxzPath({ startingDir: process.cwd() })
)
.option(
"--plugin-version <version>",
"Plugin Version in the format YYYY.MM.DD.HHMM",
getPluginVersion()
)
.option("--tag <tag>", "Tag (used for PR and staging builds)", process.env.TAG)
.option("--release-notes-path <path>", "Path to release notes file")
.option("--ci", "CI mode", process.env.CI === "true")
.parse(argv);
const options = program.opts();
console.log("Options:", options);
const env = await validatePluginEnv(options);
console.log("Plugin environment setup successfully:", env);
return env;
};
function getSha256(txzBlob: Buffer): string {
return createHash("sha256").update(txzBlob).digest("hex");
}