From c979a7fe7be1a8c5f8d66c17f7d432837423402d Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Mon, 2 Feb 2026 21:39:08 -0500 Subject: [PATCH] feat(update): notify user when container is already up to date Previously the "no update needed" branch was empty, leaving users with no feedback after the update check completed. Added Format No Update and Send No Update nodes to display " is already up to date" message. Co-Authored-By: Claude Opus 4.5 --- n8n-workflow.json | 59 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/n8n-workflow.json b/n8n-workflow.json index c40daa3..e3c16e9 100644 --- a/n8n-workflow.json +++ b/n8n-workflow.json @@ -1690,7 +1690,7 @@ }, { "parameters": { - "jsCode": "// Compare old and new image IDs to detect if update is needed\nconst stdout = $input.item.json.stdout;\nconst prevData = $('Build Image Inspect').item.json;\nconst currentImageId = prevData.currentImageId;\nconst chatId = prevData.chatId;\n\nlet newImage;\ntry {\n newImage = JSON.parse(stdout);\n} catch (e) {\n return {\n json: {\n error: true,\n chatId,\n text: `Failed to inspect new image: ${e.message}`\n }\n };\n}\n\nconst newImageId = newImage.Id;\n\nif (currentImageId === newImageId) {\n // No update needed - stay silent per CONTEXT.md\n return { json: { needsUpdate: false, chatId } };\n}\n\n// Extract new version from labels\nconst labels = newImage.Config?.Labels || {};\nconst newVersion = labels['org.opencontainers.image.version']\n || labels['version']\n || newImageId.substring(7, 19);\n\nreturn {\n json: {\n needsUpdate: true,\n currentImageId,\n newImageId,\n currentVersion: prevData.currentVersion,\n newVersion,\n containerConfig: prevData.containerConfig,\n hostConfig: prevData.hostConfig,\n networkSettings: prevData.networkSettings,\n containerName: prevData.containerName,\n containerId: prevData.containerId,\n chatId\n }\n};" + "jsCode": "// Compare old and new image IDs to detect if update is needed\nconst stdout = $input.item.json.stdout;\nconst prevData = $('Build Image Inspect').item.json;\nconst currentImageId = prevData.currentImageId;\nconst chatId = prevData.chatId;\n\nlet newImage;\ntry {\n newImage = JSON.parse(stdout);\n} catch (e) {\n return {\n json: {\n error: true,\n chatId,\n text: `Failed to inspect new image: ${e.message}`\n }\n };\n}\n\nconst newImageId = newImage.Id;\n\nif (currentImageId === newImageId) {\n // No update needed - notify user\n return { json: { needsUpdate: false, chatId, containerName: prevData.containerName } };\n}\n\n// Extract new version from labels\nconst labels = newImage.Config?.Labels || {};\nconst newVersion = labels['org.opencontainers.image.version']\n || labels['version']\n || newImageId.substring(7, 19);\n\nreturn {\n json: {\n needsUpdate: true,\n currentImageId,\n newImageId,\n currentVersion: prevData.currentVersion,\n newVersion,\n containerConfig: prevData.containerConfig,\n hostConfig: prevData.hostConfig,\n networkSettings: prevData.networkSettings,\n containerName: prevData.containerName,\n containerId: prevData.containerId,\n chatId\n }\n};" }, "id": "code-compare-digests", "name": "Compare Digests", @@ -1733,6 +1733,44 @@ 1200 ] }, + { + "parameters": { + "jsCode": "// Format 'already up to date' message\nconst containerName = $json.containerName;\nconst chatId = $json.chatId;\n\nreturn {\n json: {\n chatId,\n text: `${containerName} is already up to date`\n }\n};" + }, + "id": "code-format-no-update", + "name": "Format No Update", + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 3540, + 1400 + ] + }, + { + "parameters": { + "resource": "message", + "operation": "sendMessage", + "chatId": "={{ $json.chatId }}", + "text": "={{ $json.text }}", + "additionalFields": { + "parse_mode": "HTML" + } + }, + "id": "telegram-send-no-update", + "name": "Send No Update", + "type": "n8n-nodes-base.telegram", + "typeVersion": 1.2, + "position": [ + 3760, + 1400 + ], + "credentials": { + "telegramApi": { + "id": "telegram-credential", + "name": "Telegram API" + } + } + }, { "parameters": { "jsCode": "// Build stop container command\nconst containerId = $json.containerId;\n\nreturn {\n json: {\n cmd: `curl -s -o /dev/null -w \"%{http_code}\" --unix-socket /var/run/docker.sock -X POST 'http://localhost/v1.47/containers/${containerId}/stop?t=10'`,\n containerId,\n containerName: $json.containerName,\n currentVersion: $json.currentVersion,\n newVersion: $json.newVersion,\n currentImageId: $json.currentImageId,\n containerConfig: $json.containerConfig,\n hostConfig: $json.hostConfig,\n networkSettings: $json.networkSettings,\n chatId: $json.chatId\n }\n};" @@ -2878,7 +2916,24 @@ "index": 0 } ], - [] + [ + { + "node": "Format No Update", + "type": "main", + "index": 0 + } + ] + ] + }, + "Format No Update": { + "main": [ + [ + { + "node": "Send No Update", + "type": "main", + "index": 0 + } + ] ] }, "Build Stop Command": {