diff options
Diffstat (limited to 'extra/release/lib.mjs')
-rw-r--r-- | extra/release/lib.mjs | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/extra/release/lib.mjs b/extra/release/lib.mjs new file mode 100644 index 0000000..d6c294c --- /dev/null +++ b/extra/release/lib.mjs @@ -0,0 +1,191 @@ +import "dotenv/config"; +import * as childProcess from "child_process"; +import semver from "semver"; + +export const dryRun = process.env.RELEASE_DRY_RUN === "1"; + +if (dryRun) { + console.info("Dry run enabled."); +} + +/** + * Check if docker is running + * @returns {void} + */ +export function checkDocker() { + try { + childProcess.execSync("docker ps"); + } catch (error) { + console.error("Docker is not running. Please start docker and try again."); + process.exit(1); + } +} + +/** + * Get Docker Hub repository name + */ +export function getRepoName() { + return process.env.RELEASE_REPO_NAME || "louislam/uptime-kuma"; +} + +/** + * Build frontend dist + * @returns {void} + */ +export function buildDist() { + if (!dryRun) { + childProcess.execSync("npm run build", { stdio: "inherit" }); + } else { + console.info("[DRY RUN] npm run build"); + } +} + +/** + * Build docker image and push to Docker Hub + * @param {string} repoName Docker Hub repository name + * @param {string[]} tags Docker image tags + * @param {string} target Dockerfile's target name + * @param {string} buildArgs Docker build args + * @param {string} dockerfile Path to Dockerfile + * @param {string} platform Build platform + * @returns {void} + */ +export function buildImage(repoName, tags, target, buildArgs = "", dockerfile = "docker/dockerfile", platform = "linux/amd64,linux/arm64,linux/arm/v7") { + let args = [ + "buildx", + "build", + "-f", + dockerfile, + "--platform", + platform, + ]; + + // Add tags + for (let tag of tags) { + args.push("-t", `${repoName}:${tag}`); + } + + args = [ + ...args, + "--target", + target, + ]; + + // Add build args + if (buildArgs) { + args.push("--build-arg", buildArgs); + } + + args = [ + ...args, + ".", + "--push", + ]; + + if (!dryRun) { + childProcess.spawnSync("docker", args, { stdio: "inherit" }); + } else { + console.log(`[DRY RUN] docker ${args.join(" ")}`); + } +} + +/** + * Check if the version already exists on Docker Hub + * TODO: use semver to compare versions if it is greater than the previous? + * @param {string} repoName Docker Hub repository name + * @param {string} version Version to check + * @returns {void} + */ +export async function checkTagExists(repoName, version) { + console.log(`Checking if version ${version} exists on Docker Hub`); + + // Get a list of tags from the Docker Hub repository + let tags = []; + + // It is mainly to check my careless mistake that I forgot to update the release version in .env, so `page_size` is set to 100 is enough, I think. + const response = await fetch(`https://hub.docker.com/v2/repositories/${repoName}/tags/?page_size=100`); + if (response.ok) { + const data = await response.json(); + tags = data.results.map((tag) => tag.name); + } else { + console.error("Failed to get tags from Docker Hub"); + process.exit(1); + } + + // Check if the version already exists + if (tags.includes(version)) { + console.error(`Version ${version} already exists`); + process.exit(1); + } +} + +/** + * Check the version format + * @param {string} version Version to check + * @returns {void} + */ +export function checkVersionFormat(version) { + if (!version) { + console.error("VERSION is required"); + process.exit(1); + } + + // Check the version format, it should be a semver and must be like this: "2.0.0-beta.0" + if (!semver.valid(version)) { + console.error("VERSION is not a valid semver version"); + process.exit(1); + } +} + +/** + * Press any key to continue + * @returns {Promise<void>} + */ +export function pressAnyKey() { + console.log("Git Push and Publish the release note on github, then press any key to continue"); + process.stdin.setRawMode(true); + process.stdin.resume(); + return new Promise(resolve => process.stdin.once("data", data => { + process.stdin.setRawMode(false); + process.stdin.pause(); + resolve(); + })); +} + +/** + * Append version identifier + * @param {string} version Version + * @param {string} identifier Identifier + * @returns {string} Version with identifier + */ +export function ver(version, identifier) { + const obj = semver.parse(version); + + if (obj.prerelease.length === 0) { + obj.prerelease = [ identifier ]; + } else { + obj.prerelease[0] = [ obj.prerelease[0], identifier ].join("-"); + } + return obj.format(); +} + +/** + * Upload artifacts to GitHub + * @returns {void} + */ +export function uploadArtifacts() { + execSync("npm run upload-artifacts"); +} + +/** + * Execute a command + * @param {string} cmd Command to execute + * @returns {void} + */ +export function execSync(cmd) { + if (!dryRun) { + childProcess.execSync(cmd, { stdio: "inherit" }); + } else { + console.info(`[DRY RUN] ${cmd}`); + } +} |