From 59d10062ca5957459e0cda53c0468c1514ace590 Mon Sep 17 00:00:00 2001
From: Frank Elsinga
Date: Sun, 22 Jun 2025 14:49:24 +0200
Subject: [PATCH 01/43] chore: remove fluff from PR-template (#5941)
---
.github/ISSUE_TEMPLATE/ask_for_help.yml | 2 +-
.github/ISSUE_TEMPLATE/bug_report.yml | 2 +-
.github/ISSUE_TEMPLATE/feature_request.yml | 2 +-
.github/ISSUE_TEMPLATE/security_issue.yml | 2 +-
.github/PULL_REQUEST_TEMPLATE.md | 55 +++++-----------------
5 files changed, 17 insertions(+), 46 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/ask_for_help.yml b/.github/ISSUE_TEMPLATE/ask_for_help.yml
index 45bd046e5..2156c5be0 100644
--- a/.github/ISSUE_TEMPLATE/ask_for_help.yml
+++ b/.github/ISSUE_TEMPLATE/ask_for_help.yml
@@ -3,7 +3,7 @@ name: ❓ Ask for help
description: |
Submit any question related to Uptime Kuma
#title: "[Help]"
-labels: ["help", "P3-low"]
+labels: ["help"]
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 31cd6faf6..d0330c70a 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -3,7 +3,7 @@ name: 🐛 Bug Report
description: |
Submit a bug report to help us improve
#title: "[Bug]"
-labels: ["bug", "P2-medium"]
+labels: ["bug"]
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index c9ec4d093..4e1be15e1 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -3,7 +3,7 @@ name: 🚀 Feature Request
description: |
Submit a proposal for a new feature
# title: "[Feature]"
-labels: ["feature-request", "P3-low"]
+labels: ["feature-request"]
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/security_issue.yml b/.github/ISSUE_TEMPLATE/security_issue.yml
index d49c0aaf5..247073102 100644
--- a/.github/ISSUE_TEMPLATE/security_issue.yml
+++ b/.github/ISSUE_TEMPLATE/security_issue.yml
@@ -3,7 +3,7 @@ name: 🛡️ Security Issue
description: |
Notify Louis Lam about a security concern. Please do NOT include any sensitive details in this issue.
# title: "Security Issue"
-labels: ["security", "P1-high"]
+labels: ["security"]
assignees: [louislam]
body:
- type: markdown
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index f639c395e..dade3e76f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,10 +1,10 @@
-**⚠️ Please Note: We do not accept all types of pull requests, and we want to ensure we don’t waste your time. Before submitting, make sure you have read our pull request guidelines: [Pull Request Rules](https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma)**
-
## ❗ Important Announcement
Click here for more details:
+**⚠️ Please Note: We do not accept all types of pull requests, and we want to ensure we don’t waste your time. Before submitting, make sure you have read our pull request guidelines: [Pull Request Rules](https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma)**
+
### 🚧 Temporary Delay in Feature Requests and Pull Request Reviews
**At this time, we may be slower to respond to new feature requests and review pull requests. Existing requests and PRs will remain in the backlog but may not be prioritized immediately.**
@@ -26,16 +26,22 @@ We appreciate your patience and understanding as we continue to improve Uptime K
## 📋 Overview
-Provide a clear summary of the purpose and scope of this pull request:
+
- **What problem does this pull request address?**
-
- Please provide a detailed explanation here.
-
- **What features or functionality does this pull request introduce or enhance?**
-
- Please provide a detailed explanation here.
+## 🔗 Related Issues
+
+
+
+- Relates to #issue-number
+- Resolves #issue-number
+
## 🔄 Changes
### 🛠️ Type of change
@@ -52,19 +58,7 @@ Provide a clear summary of the purpose and scope of this pull request:
- [ ] 🔧 Other (please specify):
- Provide additional details here.
-## 🔗 Related Issues
-
-
-
-- Relates to #issue-number
-- Resolves #issue-number
-- Fixes #issue-number
-
-## 📄 Checklist *
+## 📄 Checklist
@@ -97,26 +91,3 @@ If not, remove this section.
| `DOWN` |  |  |
| Certificate-expiry |  |  |
| Testing |  |  |
-
-## ℹ️ Additional Context
-
-Provide any relevant details to assist reviewers in understanding the changes.
-
-Click here for more details:
-
-
-**Key Considerations**:
-
-- **Design decisions** – Key choices or trade-offs made during development.
-- **Alternative solutions** – Approaches considered but not implemented, along with reasons.
-- **Relevant links** – Specifications, discussions, or resources that provide context.
-- **Dependencies** – Related pull requests or issues that must be resolved before merging.
-- **Additional context** – Any other details that may help reviewers understand the changes.
-
-Provide details here
-
-## 💬 Requested Feedback
-
-
-
-- `Mention documents needing feedback here`
From b55d6e8911ea6ee5a7bdddc9f3106b6f5bade698 Mon Sep 17 00:00:00 2001
From: Louis Lam
Date: Mon, 23 Jun 2025 15:24:49 +0800
Subject: [PATCH 02/43] 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",
From 92f2484a8d9dbce171efad6eafe922e95bb2e83d Mon Sep 17 00:00:00 2001
From: Louis Lam
Date: Mon, 23 Jun 2025 17:56:39 +0800
Subject: [PATCH 03/43] Auto reply to PRs (#5943)
Co-authored-by: Frank Elsinga
---
.github/workflows/pr-reply.yml | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 .github/workflows/pr-reply.yml
diff --git a/.github/workflows/pr-reply.yml b/.github/workflows/pr-reply.yml
new file mode 100644
index 000000000..553774bf3
--- /dev/null
+++ b/.github/workflows/pr-reply.yml
@@ -0,0 +1,30 @@
+# Replys a message to all new PRs
+# The message:
+# - Say hello and thanks to the contributor
+# - Mention maintainers will review the PR soon
+# - To other people, show the testing pr command: npx kuma-pr
+# - Also show the advanced usage link: https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests
+name: Reply to PRs
+on:
+ pull_request:
+ types: [opened, reopened]
+jobs:
+ reply:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Reply to PR
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const pr = context.payload.pull_request;
+ const message = `Hello @${pr.user.login}, thank you for your contribution! :tada:\n` +
+ `The maintainers will review your PR soon.\n\n` +
+ `If anyone would like to help test this PR, you can use the command:\n` +
+ `\`\`\`bash\nnpx kuma-pr ${pr.user.login}:${pr.head.ref}\n\`\`\`\n\n` +
+ ` For advanced usage, please refer to our [wiki](https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests) `;
+ await github.rest.issues.createComment({
+ issue_number: pr.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: message
+ });
From 9e7ea4913aa6302da7ea36175f9318913291f12f Mon Sep 17 00:00:00 2001
From: Louis Lam
Date: Mon, 23 Jun 2025 21:12:18 +0800
Subject: [PATCH 04/43] Fix auto pr reply (#5945)
---
.github/workflows/pr-reply.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.github/workflows/pr-reply.yml b/.github/workflows/pr-reply.yml
index 553774bf3..48752e641 100644
--- a/.github/workflows/pr-reply.yml
+++ b/.github/workflows/pr-reply.yml
@@ -8,6 +8,12 @@ name: Reply to PRs
on:
pull_request:
types: [opened, reopened]
+
+permissions:
+ issues: write
+ pull-requests: write
+ contents: read
+
jobs:
reply:
runs-on: ubuntu-latest
From 9976ef94af050f68945e1fc94620216ef3728756 Mon Sep 17 00:00:00 2001
From: mindsolo
Date: Mon, 23 Jun 2025 16:38:01 +0300
Subject: [PATCH 05/43] feat: Add proxy clone functionality to settings (#5944)
Co-authored-by: Frank Elsinga
---
src/components/ProxyDialog.vue | 32 +++++++++++++++++++++++++++++
src/components/settings/Proxies.vue | 3 ++-
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index 2f7ed7b61..aae635469 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -174,6 +174,38 @@ export default {
this.modal.show();
},
+ /**
+ * Show dialog to clone a proxy
+ * @param {number} proxyID ID of proxy to clone
+ * @returns {void}
+ */
+ showClone(proxyID) {
+ if (proxyID) {
+ for (let proxy of this.$root.proxyList) {
+ if (proxy.id === proxyID) {
+ // Create a clone of the proxy data
+ this.proxy = {
+ protocol: proxy.protocol,
+ host: proxy.host,
+ port: proxy.port,
+ auth: proxy.auth,
+ username: proxy.username,
+ password: proxy.password,
+ active: proxy.active,
+ default: false, // Cloned proxy should not be default
+ applyExisting: false,
+ };
+ break;
+ }
+ }
+ }
+
+ // Set id to null to indicate this is a new proxy (clone)
+ this.id = null;
+
+ this.modal.show();
+ },
+
/**
* Submit form data for saving
* @returns {void}
diff --git a/src/components/settings/Proxies.vue b/src/components/settings/Proxies.vue
index 4608f3aa4..de5b8d5a0 100644
--- a/src/components/settings/Proxies.vue
+++ b/src/components/settings/Proxies.vue
@@ -13,7 +13,8 @@
{{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }})
{{ $t("Default") }}
- {{ $t("Edit") }}
+ {{ $t("Edit") }} |
+ {{ $t("Clone") }}
From 10fd6ede1e016befd3fd2656553b362a2c74fb2a Mon Sep 17 00:00:00 2001
From: Louis Lam
Date: Wed, 25 Jun 2025 13:39:00 +0800
Subject: [PATCH 06/43] [Eliminate Blocking] Docker monitor (#5927)
---
server/docker.js | 18 +++++++++---------
server/model/monitor.js | 2 +-
server/util-server.js | 15 +++++++++++++++
3 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/server/docker.js b/server/docker.js
index ee6051dfa..7ca5da562 100644
--- a/server/docker.js
+++ b/server/docker.js
@@ -1,10 +1,10 @@
const axios = require("axios");
const { R } = require("redbean-node");
const https = require("https");
-const fs = require("fs");
+const fsAsync = require("fs").promises;
const path = require("path");
const Database = require("./database");
-const { axiosAbortSignal } = require("./util-server");
+const { axiosAbortSignal, fsExists } = require("./util-server");
class DockerHost {
@@ -81,7 +81,7 @@ class DockerHost {
options.socketPath = dockerHost.dockerDaemon;
} else if (dockerHost.dockerType === "tcp") {
options.baseURL = DockerHost.patchDockerURL(dockerHost.dockerDaemon);
- options.httpsAgent = new https.Agent(DockerHost.getHttpsAgentOptions(dockerHost.dockerType, options.baseURL));
+ options.httpsAgent = new https.Agent(await DockerHost.getHttpsAgentOptions(dockerHost.dockerType, options.baseURL));
}
try {
@@ -141,9 +141,9 @@ class DockerHost {
* File names can also be overridden via 'DOCKER_TLS_FILE_NAME_(CA|KEY|CERT)'.
* @param {string} dockerType i.e. "tcp" or "socket"
* @param {string} url The docker host URL rewritten to https://
- * @returns {object} HTTP agent options
+ * @returns {Promise