Merge branch 'master' into feat/pre-fill-schedule-maintenance

This commit is contained in:
Frank Elsinga 2026-01-14 09:07:07 +01:00 committed by GitHub
commit 9caae0e1be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 69 additions and 59 deletions

View File

@ -50,7 +50,8 @@ jobs:
git push origin --delete "release-${VERSION}" || true
# Delete local branch if it exists
git branch -D "release-${VERSION}" || true
# Create new branch from master
# For testing purpose
# git checkout beta-workflow
git checkout -b "release-${VERSION}"
- name: Install dependencies

View File

@ -1,3 +1,6 @@
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const pkg = require("../../package.json");
const fs = require("fs");
const childProcess = require("child_process");
@ -58,8 +61,13 @@ function commit(version) {
throw new Error("commit error");
}
// Note: Push is handled by gh pr create in the release script
// No need to push here as we're on a release branch, not master
// Get the current branch name
res = childProcess.spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"]);
let branchName = res.stdout.toString().trim();
console.log("Current branch:", branchName);
// Git push the branch
childProcess.spawnSync("git", ["push", "origin", branchName, "--force"], { stdio: "inherit" });
}
/**

View File

@ -4,7 +4,7 @@
import * as childProcess from "child_process";
const ignoreList = ["louislam", "CommanderStorm", "UptimeKumaBot", "weblate", "Copilot"];
const ignoreList = ["louislam", "CommanderStorm", "UptimeKumaBot", "weblate", "Copilot", "@autofix-ci[bot]"];
const mergeList = ["Translations Update from Weblate", "Update dependencies"];

View File

@ -48,7 +48,7 @@ checkDocker();
await checkTagExists(repoNames, version);
// node extra/beta/update-version.js
execSync("node ./extra/beta/update-version.js");
await import("../beta/update-version.mjs");
// Create Pull Request (gh pr create will handle pushing the branch)
await createReleasePR(version, previousVersion, dryRun, branchName, githubRunId);

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "uptime-kuma",
"version": "2.1.0-beta.1",
"version": "2.1.0-beta.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "uptime-kuma",
"version": "2.1.0-beta.1",
"version": "2.1.0-beta.2",
"license": "MIT",
"dependencies": {
"@grpc/grpc-js": "~1.8.22",

View File

@ -1,6 +1,6 @@
{
"name": "uptime-kuma",
"version": "2.1.0-beta.1",
"version": "2.1.0-beta.2",
"license": "MIT",
"repository": {
"type": "git",

View File

@ -176,14 +176,6 @@ class DomainExpiry extends BeanModel {
const rdap = await getRdapServer(tld.publicSuffix);
if (!rdap) {
// Only warn when the monitor actually has domain expiry notifications enabled.
// The edit monitor page calls this method frequently while the user is typing.
if (Boolean(monitor.domainExpiryNotification)) {
log.warn(
"domain_expiry",
`Domain expiry unsupported for '.${tld.publicSuffix}' because its RDAP endpoint is not listed in the IANA database.`
);
}
throw new TranslatableError("domain_expiry_unsupported_unsupported_tld_no_rdap_endpoint", {
publicSuffix: tld.publicSuffix,
});

View File

@ -1059,7 +1059,15 @@ class Monitor extends BeanModel {
log.debug("monitor", `Failed getting expiration date for domain ${supportInfo.domain}`);
}
} catch (error) {
// purposely not logged due to noise. Is accessible via checkMointor
if (
error.message === "domain_expiry_unsupported_unsupported_tld_no_rdap_endpoint" &&
Boolean(this.domainExpiryNotification)
) {
log.warn(
"domain_expiry",
`Domain expiry unsupported for '.${error.meta.publicSuffix}' because its RDAP endpoint is not listed in the IANA database.`
);
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<div>
<h4>{{ $t("Certificate Info") }}</h4>
{{ $t("Certificate Chain") }}:
{{ $t("Certificate Chain:") }}
<div v-if="valid" class="rounded d-inline-flex ms-2 text-white tag-valid">
{{ $t("Valid") }}
</div>

View File

@ -40,14 +40,13 @@
required
/>
<div class="form-text">
{{ $t("Examples") }}:
<i18n-t tag="div" keypath="Examples:" class="form-text">
<ul>
<li>/var/run/docker.sock</li>
<li>http://localhost:2375</li>
<li>https://localhost:2376 (TLS)</li>
<li><code>/var/run/docker.sock</code></li>
<li><code>http://localhost:2375</code></li>
<li><code>https://localhost:2376 (TLS)</code></li>
</ul>
</div>
</i18n-t>
</div>
</div>

View File

@ -31,12 +31,9 @@
required
/>
<div class="form-text mt-3">
{{ $t("Examples") }}:
<ul>
<li>ws://chrome.browserless.io/playwright?token=YOUR-API-TOKEN</li>
</ul>
</div>
<i18n-t tag="div" keypath="Example:" class="form-text mt-3">
<code>ws://chrome.browserless.io/playwright?token=YOUR-API-TOKEN</code>
</i18n-t>
</div>
</div>

View File

@ -2,8 +2,8 @@
<div class="mb-3">
<label for="octopush-version" class="form-label">{{ $t("Octopush API Version") }}</label>
<select id="octopush-version" v-model="$parent.notification.octopushVersion" class="form-select">
<option value="2">{{ "octopush" }} ({{ $t("endpoint") }}: api.octopush.com)</option>
<option value="1">{{ $t("Legacy Octopush-DM") }} ({{ $t("endpoint") }}: www.octopush-dm.com)</option>
<option value="2">{{ $t("octopushEndpoint", { url: "api.octopush.com" }) }}</option>
<option value="1">{{ $t("legacyOctopushEndpoint", { url: "www.octopush-dm.com" }) }}</option>
</select>
<div class="form-text">
{{ $t("octopushLegacyHint") }}

View File

@ -27,7 +27,7 @@
<div class="status">
{{ $t("apiKey-" + item.status) }}
</div>
<div class="date">{{ $t("Created") }}: {{ item.createdDate }}</div>
<div class="date">{{ $t("createdAt", { date: item.createdDate }) }}</div>
<div class="date">
{{ $t("Expires") }}:
{{ item.expires || $t("Never") }}

View File

@ -3,8 +3,8 @@
<div class="logo d-flex flex-column justify-content-center align-items-center">
<object class="my-4" width="200" height="200" data="/icon.svg" />
<div class="fs-4 fw-bold">Uptime Kuma</div>
<div>{{ $t("Version") }}: {{ $root.info.version }}</div>
<div class="frontend-version">{{ $t("Frontend Version") }}: {{ $root.frontendVersion }}</div>
<div>{{ $t("versionIs", { version: $root.info.version }) }}</div>
<div class="frontend-version">{{ $t("frontendVersionIs", { version: $root.frontendVersion }) }}</div>
<div v-if="!$root.isFrontendBackendVersionMatched" class="alert alert-warning mt-4" role="alert">
{{ $t("Frontend Version do not match backend version!") }}

View File

@ -4,15 +4,13 @@
<!-- Change Password -->
<template v-if="!settings.disableAuth">
<p>
{{ $t("Current User") }}:
<strong>{{ $root.username }}</strong>
<button
v-if="!settings.disableAuth"
id="logout-btn"
class="btn btn-danger ms-4 me-2 mb-2"
@click="$root.logout"
>
{{ $t("Logout") }}
{{ $t("logoutCurrentUser", { username: $root.username }) }}
</button>
</p>

View File

@ -20,7 +20,7 @@
"General": "General",
"Game": "Game",
"Primary Base URL": "Primary Base URL",
"Version": "Version",
"versionIs": "Version: {version}",
"Check Update On GitHub": "Check Update On GitHub",
"List": "List",
"Home": "Home",
@ -145,6 +145,7 @@
"where you intend to implement third-party authentication": "where you intend to implement third-party authentication",
"Please use this option carefully!": "Please use this option carefully!",
"Logout": "Log out",
"logoutCurrentUser": "Log out {username}",
"Leave": "Leave",
"I understand, please disable": "I understand, please disable",
"Confirm": "Confirm",
@ -280,7 +281,6 @@
"records": "records",
"One record": "One record",
"steamApiKeyDescriptionAt": "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key at {url}",
"Current User": "Current User",
"topic": "Topic",
"topicExplanation": "MQTT topic to monitor",
"mqttWebSocketPath": "MQTT WebSocket Path",
@ -320,8 +320,9 @@
"dark": "dark",
"Post": "Post",
"Please input title and content": "Please input title and content",
"Created": "Created",
"Last Updated": "Last Updated",
"createdAt": "Created: {date}",
"lastUpdatedAt": "Last Updated: {date}",
"lastUpdatedAtFromNow": "Last Updated: {date} ({fromNow})",
"Switch to Light Theme": "Switch to Light Theme",
"Switch to Dark Theme": "Switch to Dark Theme",
"Show Tags": "Show Tags",
@ -356,7 +357,7 @@
"proxyDescription": "Proxies must be assigned to a monitor to function.",
"enableProxyDescription": "This proxy will not effect on monitor requests until it is activated. You can control temporarily disable the proxy from all monitors by activation status.",
"setAsDefaultProxyDescription": "This proxy will be enabled by default for new monitors. You can still disable the proxy separately for each monitor.",
"Certificate Chain": "Certificate Chain",
"Certificate Chain:": "Certificate Chain:",
"Valid": "Valid",
"Invalid": "Invalid",
"User": "User",
@ -403,7 +404,7 @@
"Add a new expiry notification day": "Add a new expiry notification day",
"Remove the expiry notification": "Remove the expiry notification day",
"Proxy": "Proxy",
"Date Created": "Date Created",
"dateCreatedAtFromNow": "Date Created: {date} ({fromNow})",
"Footer Text": "Footer Text",
"RSS Title": "RSS Title",
"Leave blank to use status page title": "Leave blank to use status page title",
@ -477,7 +478,7 @@
"disableCloudflaredNoAuthMsg": "You are in No Auth mode, a password is not required.",
"trustProxyDescription": "Trust 'X-Forwarded-*' headers. If you want to get the correct client IP and your Uptime Kuma is behind a proxy such as Nginx or Apache, you should enable this.",
"wayToGetLineNotifyToken": "You can get an access token from {0}",
"Examples": "Examples",
"Examples:": "Examples: {0}",
"supportBaleChatID": "Support Direct Chat / Group / Channel's Chat ID",
"wayToGetBaleChatID": "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
"wayToGetBaleToken": "You can get a token from {0}.",
@ -492,7 +493,7 @@
"Event type:": "Event type:",
"Event data:": "Event data:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Then choose an action, for example switch the scene to where an RGB light is red.",
"Frontend Version": "Frontend Version",
"frontendVersionIs": "Frontend Version: {version}",
"Frontend Version do not match backend version!": "Frontend Version do not match backend version!",
"backupOutdatedWarning": "Deprecated: Since a lot of features were added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.",
"backupRecommend": "Please backup the volume or the data folder (./data/) directly instead.",
@ -503,7 +504,7 @@
"startDateTime": "Start Date/Time",
"endDateTime": "End Date/Time",
"cronExpression": "Cron Expression",
"cronSchedule": "Schedule: ",
"cronScheduleDescription": "Schedule: {description}",
"Duration (Minutes)": "Duration (Minutes)",
"invalidCronExpression": "Invalid Cron Expression: {0}",
"recurringInterval": "Interval",
@ -682,7 +683,6 @@
"backupDescription": "You can backup all monitors and notifications into a JSON file.",
"backupDescription2": "Note: history and event data is not included.",
"backupDescription3": "Sensitive data such as notification tokens are included in the export file; please store export securely.",
"endpoint": "endpoint",
"octopushAPIKey": "\"API key\" from HTTP API credentials in control panel",
"octopushLogin": "\"Login\" from HTTP API credentials in control panel",
"promosmsLogin": "API Login Name",
@ -884,7 +884,8 @@
"From Name/Number": "From Name/Number",
"Leave blank to use a shared sender number.": "Leave blank to use a shared sender number.",
"Octopush API Version": "Octopush API Version",
"Legacy Octopush-DM": "Legacy Octopush-DM",
"octopushEndpoint": "octopush (endpoint: {url})",
"legacyOctopushEndpoint": "Legacy Octopush-DM (endpoint: {url})",
"ntfy Topic": "ntfy Topic",
"Server URL should not contain the nfty topic": "Server URL should not contain the nfty topic",
"onebotHttpAddress": "OneBot HTTP Address",

View File

@ -129,7 +129,7 @@
<label for="cron" class="form-label">
{{ $t("cronExpression") }}
</label>
<p>{{ $t("cronSchedule") }}{{ cronDescription }}</p>
<p>{{ $t("cronScheduleDescription", { description: cronDescription }) }}</p>
<input
id="cron"
v-model="maintenance.cron"

View File

@ -342,14 +342,20 @@
<!-- Incident Date -->
<div class="date mt-3">
{{ $t("Date Created") }}: {{ $root.datetime(incident.createdDate) }} ({{
dateFromNow(incident.createdDate)
}})
{{
$t("dateCreatedAtFromNow", {
date: $root.datetime(incident.createdDate),
fromNow: dateFromNow(incident.createdDate),
})
}}
<br />
<span v-if="incident.lastUpdatedDate">
{{ $t("Last Updated") }}: {{ $root.datetime(incident.lastUpdatedDate) }} ({{
dateFromNow(incident.lastUpdatedDate)
}})
{{
$t("lastUpdatedAtFromNow", {
date: $root.datetime(incident.lastUpdatedDate),
fromNow: dateFromNow(incident.lastUpdatedDate),
})
}}
</span>
</div>
@ -572,7 +578,7 @@
</p>
<div class="refresh-info mb-2">
<div>{{ $t("Last Updated") }}: {{ lastUpdateTimeDisplay }}</div>
<div>{{ $t("lastUpdatedAt", { date: lastUpdateTimeDisplay }) }}</div>
<div data-testid="update-countdown-text">
{{ $tc("statusPageRefreshIn", [updateCountdownText]) }}
</div>