8e49d2b300
Adds POST /api/updates/apply (pull, rebuild, restart) plus an "Update now" button and hourly auto-check in the UI, for checkouts that are safely fast-forwardable. Reintroduces self-restart (previously removed in edc25ca for cross-environment reliability concerns) per explicit user request.
77 lines
2.3 KiB
JavaScript
77 lines
2.3 KiB
JavaScript
/**
|
|
* @file HTTP routes for dashboard upstream-update detection, plus the one
|
|
* self-applying path: POST /apply fast-forwards, rebuilds, and restarts the
|
|
* process on the user's explicit click (see `server/lib/update-check.js`'s
|
|
* `applyUpdate` and `server/lib/self-restart.js`). Everywhere else, the
|
|
* dashboard only ever prints a command for the user to run themselves.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
const { Router } = require("express");
|
|
const { getUpdatesStatus, applyUpdate } = require("../lib/update-check");
|
|
const { scheduleRestart } = require("../lib/self-restart");
|
|
|
|
const router = Router();
|
|
|
|
router.get("/status", async (_req, res) => {
|
|
try {
|
|
const status = await getUpdatesStatus();
|
|
res.json(status);
|
|
} catch (err) {
|
|
res.status(500).json({
|
|
error: { code: "UPDATE_STATUS_FAILED", message: err.message || String(err) },
|
|
});
|
|
}
|
|
});
|
|
|
|
router.post("/check", async (_req, res) => {
|
|
try {
|
|
const status = await getUpdatesStatus();
|
|
try {
|
|
const { broadcast } = require("../websocket");
|
|
broadcast("update_status", status);
|
|
} catch {
|
|
// WS not initialized (e.g. in isolated tests) — safe to ignore.
|
|
}
|
|
res.json(status);
|
|
} catch (err) {
|
|
res.status(500).json({
|
|
error: { code: "UPDATE_CHECK_FAILED", message: err.message || String(err) },
|
|
});
|
|
}
|
|
});
|
|
|
|
router.post("/apply", async (_req, res) => {
|
|
try {
|
|
const result = await applyUpdate();
|
|
if (!result.applied) {
|
|
res.status(409).json({
|
|
...result,
|
|
error: {
|
|
code: "UPDATE_NOT_APPLICABLE",
|
|
message:
|
|
result.reason === "up_to_date"
|
|
? "Already up to date."
|
|
: "Current branch can't be fast-forwarded automatically.",
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
res.json(result);
|
|
try {
|
|
const { broadcast } = require("../websocket");
|
|
broadcast("update_status", { ...result, update_available: false });
|
|
} catch {
|
|
// WS not initialized (e.g. in isolated tests) — safe to ignore.
|
|
}
|
|
// After the response above, restart onto the freshly-built code.
|
|
setImmediate(() => scheduleRestart());
|
|
} catch (err) {
|
|
res.status(500).json({
|
|
error: { code: "UPDATE_APPLY_FAILED", message: err.message || String(err) },
|
|
});
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|