fix(deploy): déléguer le redéploiement du dashboard à l hôte
This commit is contained in:
2483
src/backend/package-lock.json
generated
Normal file
2483
src/backend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"start": "node src/index.js",
|
||||
"dev": "nodemon src/index.js",
|
||||
"test": "node test/app-registry.test.js && node test/healthcheck.test.js"
|
||||
"test": "node test/app-registry.test.js && node test/healthcheck.test.js && node test/webhook.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.21.0",
|
||||
|
||||
@@ -17,10 +17,33 @@ const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || '';
|
||||
const APPS_BASE_PATH = process.env.APPS_BASE_PATH || '/opt/manus-deploy/apps';
|
||||
const DEPLOY_SCRIPT = '/opt/manus-deploy/scripts/deploy-app.sh';
|
||||
const LOG_DIR = '/var/log/manus-deploy';
|
||||
const DASHBOARD_APP_ID = 'manus-dashboard';
|
||||
const DASHBOARD_DEPLOY_REQUEST = path.join(APPS_BASE_PATH, DASHBOARD_APP_ID, '.deployment-request');
|
||||
|
||||
// Déploiements en cours (évite les doubles déclenchements)
|
||||
const deployingApps = new Set();
|
||||
|
||||
/**
|
||||
* Le conteneur ne peut pas se recréer lui-même : Docker interrompt son client
|
||||
* `docker compose` au moment où le conteneur courant est arrêté. Ce cas est
|
||||
* donc délégué au service systemd hôte manus-dashboard-self-deploy.path.
|
||||
*/
|
||||
function isHostManagedDeployment(appName) {
|
||||
return appName === DASHBOARD_APP_ID;
|
||||
}
|
||||
|
||||
function requestDashboardHostDeployment({ branch, commitHash, committer }) {
|
||||
const temporaryRequest = `${DASHBOARD_DEPLOY_REQUEST}.${process.pid}.tmp`;
|
||||
const request = {
|
||||
branch,
|
||||
commitHash,
|
||||
committer,
|
||||
requestedAt: new Date().toISOString(),
|
||||
};
|
||||
fs.writeFileSync(temporaryRequest, JSON.stringify(request, null, 2), { mode: 0o600 });
|
||||
fs.renameSync(temporaryRequest, DASHBOARD_DEPLOY_REQUEST);
|
||||
}
|
||||
|
||||
function verifyGiteaSignature(req) {
|
||||
if (!WEBHOOK_SECRET) {
|
||||
console.warn('[Webhook] AVERTISSEMENT: WEBHOOK_SECRET non défini. Validation désactivée.');
|
||||
@@ -103,6 +126,15 @@ router.post('/gitea', (req, res) => {
|
||||
if (!appName) return res.status(200).json({ message: `Dépôt ${repoName} non déployé ou sans manifeste valide` });
|
||||
if (branch !== 'main') return res.status(200).json({ message: `Branch ${branch} ignorée` });
|
||||
|
||||
if (isHostManagedDeployment(appName)) {
|
||||
requestDashboardHostDeployment({ branch, commitHash, committer });
|
||||
return res.status(202).json({
|
||||
message: 'Redéploiement du dashboard confié au service hôte',
|
||||
commit: commitHash,
|
||||
branch,
|
||||
});
|
||||
}
|
||||
|
||||
res.status(202).json({ message: `Déploiement de ${appName} déclenché`, commit: commitHash, branch, committer });
|
||||
|
||||
// Récupérer la fonction broadcast si disponible globalement
|
||||
@@ -135,3 +167,4 @@ router.get('/status', (req, res) => {
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
module.exports.isHostManagedDeployment = isHostManagedDeployment;
|
||||
|
||||
11
src/backend/test/webhook.test.js
Normal file
11
src/backend/test/webhook.test.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Un conteneur ne peut pas recréer fiablement son propre conteneur Docker :
|
||||
* le client `docker compose` est arrêté en même temps que lui. Le webhook doit
|
||||
* donc déléguer ce cas précis à un service systemd hôte.
|
||||
*/
|
||||
const assert = require('node:assert/strict');
|
||||
const { isHostManagedDeployment } = require('../src/webhook');
|
||||
|
||||
assert.equal(isHostManagedDeployment('manus-dashboard'), true);
|
||||
assert.equal(isHostManagedDeployment('itinova-contacts'), false);
|
||||
console.log('OK webhook');
|
||||
Reference in New Issue
Block a user