diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 20d0749fc..af3fff0e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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/)) - 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 - `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 -1. Create `patch-{name}.sql` in `./db/` -2. Add your patch filename in the `patchList` list in `./server/database.js` +See: https://github.com/louislam/uptime-kuma/tree/master/db/knex_migrations ## Unit Test diff --git a/db/knex_init_db.js b/db/knex_init_db.js index c97cbf8e1..a2b3b15e5 100644 --- a/db/knex_init_db.js +++ b/db/knex_init_db.js @@ -273,10 +273,10 @@ async function createTables(dbType) { await knex.schema.createTable("notification", (table) => { table.increments("id"); table.string("name", 255); - table.string("config", 255); // TODO: should use TEXT! table.boolean("active").notNullable().defaultTo(true); table.integer("user_id").unsigned(); table.boolean("is_default").notNullable().defaultTo(false); + table.text("config"); }); // monitor_notification diff --git a/extra/rebase-pr.js b/extra/rebase-pr.js new file mode 100644 index 000000000..4921d2e7c --- /dev/null +++ b/extra/rebase-pr.js @@ -0,0 +1,40 @@ +const { execSync } = require("child_process"); + +/** + * Rebase a PR onto such as 1.23.X or master + * @returns {Promise} + */ +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(); diff --git a/package.json b/package.json index 9b972fae1..57f96f5db 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,8 @@ "deploy-demo-server": "node extra/deploy-demo-server.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", - "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": { "@grpc/grpc-js": "~1.7.3", diff --git a/server/database.js b/server/database.js index 8842fbe99..74b5469ce 100644 --- a/server/database.js +++ b/server/database.js @@ -404,8 +404,14 @@ class Database { directory: Database.knexMigrationsPath, }); } catch (e) { - log.error("db", "Database migration failed"); - throw 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"); + throw e; + } } } diff --git a/server/model/monitor.js b/server/model/monitor.js index adeeab83a..284a5ccc9 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -948,7 +948,15 @@ class Monitor extends BeanModel { if (! this.isStop) { 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 { log.info("monitor", `[${this.name}] isStop = true, no next check.`); } diff --git a/server/notification-providers/bark.js b/server/notification-providers/bark.js index 8746761e4..7fe9a7a9f 100644 --- a/server/notification-providers/bark.js +++ b/server/notification-providers/bark.js @@ -46,8 +46,7 @@ class Bark extends NotificationProvider { } /** - * Add additional parameter for better on device styles (iOS 15 - * optimized) + * Add additional parameter for Bark v1 endpoints * @param {BeanModel} notification Notification to send * @param {string} postUrl URL to append parameters to * @returns {string} Additional URL parameters @@ -96,12 +95,23 @@ class Bark extends NotificationProvider { * @returns {string} Success message */ async postNotification(notification, title, subtitle, endpoint) { - // url encode title and subtitle - title = encodeURIComponent(title); - subtitle = encodeURIComponent(subtitle); - let postUrl = endpoint + "/" + title + "/" + subtitle; - postUrl = this.appendAdditionalParameters(notification, postUrl); - let result = await axios.get(postUrl); + let result; + if (notification.apiVersion === "v1" || notification.apiVersion == null) { + // url encode title and subtitle + title = encodeURIComponent(title); + subtitle = encodeURIComponent(subtitle); + let postUrl = endpoint + "/" + title + "/" + subtitle; + postUrl = this.appendAdditionalParameters(notification, 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); if (result.statusText != null) { return "Bark notification succeed: " + result.statusText; diff --git a/src/components/notifications/Bark.vue b/src/components/notifications/Bark.vue index 6cac73d36..b38a7dc62 100644 --- a/src/components/notifications/Bark.vue +++ b/src/components/notifications/Bark.vue @@ -1,4 +1,11 @@