Merge branch 'master' into postgres-support

This commit is contained in:
Chongyi Zheng 2023-09-22 11:41:48 -04:00 committed by GitHub
commit f05d5c81b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 93 additions and 15 deletions

View file

@ -112,6 +112,12 @@ I personally do not like something that requires so many configurations before y
- IDE that supports [`ESLint`](https://eslint.org/) and EditorConfig (I am using [`IntelliJ IDEA`](https://www.jetbrains.com/idea/)) - IDE that supports [`ESLint`](https://eslint.org/) and EditorConfig (I am using [`IntelliJ IDEA`](https://www.jetbrains.com/idea/))
- A SQLite GUI tool (f.ex. [`SQLite Expert Personal`](https://www.sqliteexpert.com/download.html) or [`DBeaver Community`](https://dbeaver.io/download/)) - A SQLite GUI tool (f.ex. [`SQLite Expert Personal`](https://www.sqliteexpert.com/download.html) or [`DBeaver Community`](https://dbeaver.io/download/))
### GitHub Codespace
If you don't want to setup an local environment, you can now develop on GitHub Codespace, read more:
https://github.com/louislam/uptime-kuma/tree/master/.devcontainer
## Git Branches ## Git Branches
- `master`: 2.X.X development. If you want to add a new feature, your pull request should base on this. - `master`: 2.X.X development. If you want to add a new feature, your pull request should base on this.
@ -193,8 +199,7 @@ The data and socket logic are in `src/mixins/socket.js`.
## Database Migration ## Database Migration
1. Create `patch-{name}.sql` in `./db/` See: https://github.com/louislam/uptime-kuma/tree/master/db/knex_migrations
2. Add your patch filename in the `patchList` list in `./server/database.js`
## Unit Test ## Unit Test

View file

@ -273,10 +273,10 @@ async function createTables(dbType) {
await knex.schema.createTable("notification", (table) => { await knex.schema.createTable("notification", (table) => {
table.increments("id"); table.increments("id");
table.string("name", 255); table.string("name", 255);
table.string("config", 255); // TODO: should use TEXT!
table.boolean("active").notNullable().defaultTo(true); table.boolean("active").notNullable().defaultTo(true);
table.integer("user_id").unsigned(); table.integer("user_id").unsigned();
table.boolean("is_default").notNullable().defaultTo(false); table.boolean("is_default").notNullable().defaultTo(false);
table.text("config");
}); });
// monitor_notification // monitor_notification

40
extra/rebase-pr.js Normal file
View file

@ -0,0 +1,40 @@
const { execSync } = require("child_process");
/**
* Rebase a PR onto such as 1.23.X or master
* @returns {Promise<void>}
*/
async function main() {
const branch = process.argv[2];
// Use gh to get current branch's pr id
let currentBranchPRID = execSync("gh pr view --json number --jq \".number\"").toString().trim();
console.log("Pr ID: ", currentBranchPRID);
// Use gh commend to get pr commits
const prCommits = JSON.parse(execSync(`gh pr view ${currentBranchPRID} --json commits`).toString().trim()).commits;
console.log("Found commits: ", prCommits.length);
// Sort the commits by authoredDate
prCommits.sort((a, b) => {
return new Date(a.authoredDate) - new Date(b.authoredDate);
});
// Get the oldest commit id
const oldestCommitID = prCommits[0].oid;
console.log("Oldest commit id of this pr:", oldestCommitID);
// Get the latest commit id of the target branch
const latestCommitID = execSync(`git rev-parse origin/${branch}`).toString().trim();
console.log("Latest commit id of " + branch + ":", latestCommitID);
// Get the original parent commit id of the oldest commit
const originalParentCommitID = execSync(`git log --pretty=%P -n 1 "${oldestCommitID}"`).toString().trim();
console.log("Original parent commit id of the oldest commit:", originalParentCommitID);
// Rebase the pr onto the target branch
execSync(`git rebase --onto ${latestCommitID} ${originalParentCommitID}`);
}
main();

View file

@ -72,7 +72,8 @@
"deploy-demo-server": "node extra/deploy-demo-server.js", "deploy-demo-server": "node extra/deploy-demo-server.js",
"sort-contributors": "node extra/sort-contributors.js", "sort-contributors": "node extra/sort-contributors.js",
"quick-run-nightly": "docker run --rm --env NODE_ENV=development -p 3001:3001 louislam/uptime-kuma:nightly2", "quick-run-nightly": "docker run --rm --env NODE_ENV=development -p 3001:3001 louislam/uptime-kuma:nightly2",
"start-dev-container": "cd docker && docker-compose -f docker-compose-dev.yml up --force-recreate" "start-dev-container": "cd docker && docker-compose -f docker-compose-dev.yml up --force-recreate",
"rebase-pr-to-1.23.X": "node extra/rebase-pr.js 1.23.X"
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "~1.7.3", "@grpc/grpc-js": "~1.7.3",

View file

@ -404,10 +404,16 @@ class Database {
directory: Database.knexMigrationsPath, directory: Database.knexMigrationsPath,
}); });
} catch (e) { } catch (e) {
// Allow missing patch files for downgrade or testing pr.
if (e.message.includes("the following files are missing:")) {
log.warn("db", e.message);
log.warn("db", "Database migration failed, you may be downgrading Uptime Kuma.");
} else {
log.error("db", "Database migration failed"); log.error("db", "Database migration failed");
throw e; throw e;
} }
} }
}
/** /**
* TODO * TODO

View file

@ -948,7 +948,15 @@ class Monitor extends BeanModel {
if (! this.isStop) { if (! this.isStop) {
log.debug("monitor", `[${this.name}] SetTimeout for next check.`); log.debug("monitor", `[${this.name}] SetTimeout for next check.`);
this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000);
let intervalRemainingMs = Math.max(
1,
beatInterval * 1000 - dayjs().diff(dayjs.utc(bean.time))
);
log.debug("monitor", `[${this.name}] Next heartbeat in: ${intervalRemainingMs}ms`);
this.heartbeatInterval = setTimeout(safeBeat, intervalRemainingMs);
} else { } else {
log.info("monitor", `[${this.name}] isStop = true, no next check.`); log.info("monitor", `[${this.name}] isStop = true, no next check.`);
} }

View file

@ -46,8 +46,7 @@ class Bark extends NotificationProvider {
} }
/** /**
* Add additional parameter for better on device styles (iOS 15 * Add additional parameter for Bark v1 endpoints
* optimized)
* @param {BeanModel} notification Notification to send * @param {BeanModel} notification Notification to send
* @param {string} postUrl URL to append parameters to * @param {string} postUrl URL to append parameters to
* @returns {string} Additional URL parameters * @returns {string} Additional URL parameters
@ -96,12 +95,23 @@ class Bark extends NotificationProvider {
* @returns {string} Success message * @returns {string} Success message
*/ */
async postNotification(notification, title, subtitle, endpoint) { async postNotification(notification, title, subtitle, endpoint) {
let result;
if (notification.apiVersion === "v1" || notification.apiVersion == null) {
// url encode title and subtitle // url encode title and subtitle
title = encodeURIComponent(title); title = encodeURIComponent(title);
subtitle = encodeURIComponent(subtitle); subtitle = encodeURIComponent(subtitle);
let postUrl = endpoint + "/" + title + "/" + subtitle; let postUrl = endpoint + "/" + title + "/" + subtitle;
postUrl = this.appendAdditionalParameters(notification, postUrl); postUrl = this.appendAdditionalParameters(notification, postUrl);
let result = await axios.get(postUrl); result = await axios.get(postUrl);
} else {
result = await axios.post(`${endpoint}/push`, {
title,
body: subtitle,
icon: barkNotificationAvatar,
sound: notification.barkSound || "telegraph", // default sound is telegraph
group: notification.barkGroup || "UptimeKuma", // default group is UptimeKuma
});
}
this.checkResult(result); this.checkResult(result);
if (result.statusText != null) { if (result.statusText != null) {
return "Bark notification succeed: " + result.statusText; return "Bark notification succeed: " + result.statusText;

View file

@ -1,4 +1,11 @@
<template> <template>
<div class="mb-3">
<label for="Bark API Version" class="form-label">{{ $t("Bark API Version") }}</label>
<select id="Bark API Version" v-model="$parent.notification.apiVersion" class="form-select" required>
<option value="v1">v1</option>
<option value="v2">v2</option>
</select>
</div>
<div class="mb-3"> <div class="mb-3">
<label for="Bark Endpoint" class="form-label">{{ $t("Bark Endpoint") }}<span style="color: red;"><sup>*</sup></span></label> <label for="Bark Endpoint" class="form-label">{{ $t("Bark Endpoint") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="Bark Endpoint" v-model="$parent.notification.barkEndpoint" type="text" class="form-control" required> <input id="Bark Endpoint" v-model="$parent.notification.barkEndpoint" type="text" class="form-control" required>

View file

@ -626,6 +626,7 @@
"TemplateCode": "TemplateCode", "TemplateCode": "TemplateCode",
"SignName": "SignName", "SignName": "SignName",
"Sms template must contain parameters: ": "Sms template must contain parameters: ", "Sms template must contain parameters: ": "Sms template must contain parameters: ",
"Bark API Version": "Bark API Version",
"Bark Endpoint": "Bark Endpoint", "Bark Endpoint": "Bark Endpoint",
"Bark Group": "Bark Group", "Bark Group": "Bark Group",
"Bark Sound": "Bark Sound", "Bark Sound": "Bark Sound",