From b55d6e8911ea6ee5a7bdddc9f3106b6f5bade698 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Mon, 23 Jun 2025 15:24:49 +0800 Subject: [PATCH] Improve the experience of testing pull requests (#5942) --- docker/dockerfile | 4 ++++ extra/checkout-pr.js | 33 -------------------------------- extra/checkout-pr.mjs | 34 +++++++++++++++++++++++++++++++++ extra/kuma-pr/index.mjs | 26 +++++++++++++++++++++++++ extra/kuma-pr/package.json | 8 ++++++++ extra/kuma-pr/pr-lib.mjs | 39 ++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 112 insertions(+), 34 deletions(-) delete mode 100644 extra/checkout-pr.js create mode 100644 extra/checkout-pr.mjs create mode 100644 extra/kuma-pr/index.mjs create mode 100644 extra/kuma-pr/package.json create mode 100644 extra/kuma-pr/pr-lib.mjs diff --git a/docker/dockerfile b/docker/dockerfile index d55f94f61..e2a301e7b 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -79,6 +79,10 @@ USER node RUN git config --global user.email "no-reply@no-reply.com" RUN git config --global user.name "PR Tester" RUN git clone https://github.com/louislam/uptime-kuma.git . + +# Hide the warning when running in detached head state +RUN git config --global advice.detachedHead false + RUN npm ci EXPOSE 3000 3001 diff --git a/extra/checkout-pr.js b/extra/checkout-pr.js deleted file mode 100644 index 0328770b1..000000000 --- a/extra/checkout-pr.js +++ /dev/null @@ -1,33 +0,0 @@ -const childProcess = require("child_process"); - -if (!process.env.UPTIME_KUMA_GH_REPO) { - console.error("Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"); - process.exit(1); -} - -let inputArray = process.env.UPTIME_KUMA_GH_REPO.split(":"); - -if (inputArray.length !== 2) { - console.error("Invalid format. Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"); -} - -let name = inputArray[0]; -let branch = inputArray[1]; - -console.log("Checkout pr"); - -// Checkout the pr -let result = childProcess.spawnSync("git", [ "remote", "add", name, `https://github.com/${name}/uptime-kuma` ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); - -result = childProcess.spawnSync("git", [ "fetch", name, branch ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); - -result = childProcess.spawnSync("git", [ "checkout", `${name}/${branch}`, "--force" ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); diff --git a/extra/checkout-pr.mjs b/extra/checkout-pr.mjs new file mode 100644 index 000000000..653664477 --- /dev/null +++ b/extra/checkout-pr.mjs @@ -0,0 +1,34 @@ +import childProcess from "child_process"; +import { parsePrName } from "./kuma-pr/pr-lib.mjs"; + +let { name, branch } = parsePrName(process.env.UPTIME_KUMA_GH_REPO); + +console.log(`Checking out PR from ${name}:${branch}`); + +// Checkout the pr +let result = childProcess.spawnSync("git", [ "remote", "add", name, `https://github.com/${name}/uptime-kuma` ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to add remote repository."); + process.exit(1); +} + +result = childProcess.spawnSync("git", [ "fetch", name, branch ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to fetch the branch."); + process.exit(1); +} + +result = childProcess.spawnSync("git", [ "checkout", `${name}/${branch}`, "--force" ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to checkout the branch."); + process.exit(1); +} diff --git a/extra/kuma-pr/index.mjs b/extra/kuma-pr/index.mjs new file mode 100644 index 000000000..bcda9d335 --- /dev/null +++ b/extra/kuma-pr/index.mjs @@ -0,0 +1,26 @@ +#!/usr/bin/env node +import { spawn } from "child_process"; +import { parsePrName } from "./pr-lib.mjs"; + +const prName = process.argv[2]; + +// Pre-check the prName here, so testers don't need to wait until the Docker image is pulled to see the error. +try { + parsePrName(prName); +} catch (error) { + console.error(error.message); + process.exit(1); +} + +spawn("docker", [ + "run", + "--rm", + "-it", + "-p", "3000:3000", + "-p", "3001:3001", + "--pull", "always", + "-e", `UPTIME_KUMA_GH_REPO=${prName}`, + "louislam/uptime-kuma:pr-test2" +], { + stdio: "inherit", +}); diff --git a/extra/kuma-pr/package.json b/extra/kuma-pr/package.json new file mode 100644 index 000000000..16f30b160 --- /dev/null +++ b/extra/kuma-pr/package.json @@ -0,0 +1,8 @@ +{ + "name": "kuma-pr", + "version": "1.0.0", + "type": "module", + "bin": { + "kuma-pr": "./index.mjs" + } +} diff --git a/extra/kuma-pr/pr-lib.mjs b/extra/kuma-pr/pr-lib.mjs new file mode 100644 index 000000000..1cb5050bf --- /dev/null +++ b/extra/kuma-pr/pr-lib.mjs @@ -0,0 +1,39 @@ +/** + * Parse : to an object. + * @param {string} prName : + * @returns {object} An object with name and branch properties. + */ +export function parsePrName(prName) { + let name = "louislam"; + let branch; + + const errorMessage = "Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"; + + if (!prName) { + throw new Error(errorMessage); + } + + prName = prName.trim(); + if (prName === "") { + throw new Error(errorMessage); + } + + let inputArray = prName.split(":"); + + // Just realized that owner's prs are not prefixed with "louislam:" + if (inputArray.length === 1) { + branch = inputArray[0]; + + } else if (inputArray.length === 2) { + name = inputArray[0]; + branch = inputArray[1]; + + } else { + throw new Error("Invalid format. The format is like this: mhkarimi1383:goalert-notification"); + } + + return { + name, + branch + }; +} diff --git a/package.json b/package.json index 16837fa8a..97b7bc339 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "release-nightly": "node ./extra/release/nightly.mjs", "git-remove-tag": "git tag -d", "build-dist-and-restart": "npm run build && npm run start-server-dev", - "start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev", + "start-pr-test": "node extra/checkout-pr.mjs && npm install && npm run dev", "build-healthcheck-armv7": "cross-env GOOS=linux GOARCH=arm GOARM=7 go build -x -o ./extra/healthcheck-armv7 ./extra/healthcheck.go", "deploy-demo-server": "node extra/deploy-demo-server.js", "sort-contributors": "node extra/sort-contributors.js",