Files
ewoooc/n8n-workflows/03-cicd-pipeline-notify.json
OoO d6d8777e41
All checks were successful
CD Pipeline / deploy (push) Successful in 1m12s
V10.601 收斂 Gemini 與密鑰治理
2026-06-06 14:52:46 +08:00

126 lines
4.7 KiB
JSON

{
"name": "CI/CD Pipeline 通知",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "gitlab-webhook",
"options": {}
},
"id": "webhook-trigger",
"name": "GitLab Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [0, 0],
"webhookId": "gitlab-pipeline-webhook"
},
{
"parameters": {
"jsCode": "// 解析 GitLab Pipeline Webhook\nconst data = $input.first().json;\nconst body = data.body || data;\n\n// 確認是 Pipeline 事件\nif (body.object_kind !== 'pipeline') {\n return [{ json: { skip: true, reason: 'Not a pipeline event' } }];\n}\n\nconst pipeline = body.object_attributes || {};\nconst project = body.project || {};\nconst user = body.user || {};\nconst commit = body.commit || {};\n\nconst status = pipeline.status || 'unknown';\n\n// 只處理最終狀態\nif (!['success', 'failed', 'canceled'].includes(status)) {\n return [{ json: { skip: true, reason: 'Skipping status: ' + status } }];\n}\n\nconst statusEmoji = {\n 'success': '✅',\n 'failed': '❌',\n 'canceled': '🚫'\n};\n\nconst duration = pipeline.duration || 0;\nconst minutes = Math.floor(duration / 60);\nconst seconds = duration % 60;\n\nconst emoji = statusEmoji[status] || '❓';\nconst projectName = project.name || project.path_with_namespace || 'Unknown';\nconst branch = pipeline.ref || 'N/A';\nconst pipelineId = pipeline.id || 'N/A';\nconst pipelineUrl = project.web_url ? project.web_url + '/-/pipelines/' + pipeline.id : 'N/A';\nconst commitMsg = commit.message ? commit.message.split('\\n')[0].substring(0, 50) : (pipeline.sha ? pipeline.sha.substring(0, 8) : 'N/A');\nconst author = (commit.author && commit.author.name) || user.name || user.username || 'Unknown';\nconst durationStr = minutes + 'm ' + seconds + 's';\n\n// 組合訊息文字\nconst text = emoji + ' *CI/CD Pipeline ' + status.toUpperCase() + '*\\n\\n' +\n '📦 專案: ' + projectName + '\\n' +\n '🌿 分支: ' + branch + '\\n' +\n '🆔 Pipeline: #' + pipelineId + '\\n' +\n '💬 Commit: ' + commitMsg + '\\n' +\n '👤 作者: ' + author + '\\n' +\n '⏱️ 耗時: ' + durationStr + '\\n\\n' +\n '🔗 [查看詳情](' + pipelineUrl + ')';\n\nreturn [{\n json: {\n skip: false,\n telegramBody: {\n chat_id: '5619078117',\n text: text,\n parse_mode: 'Markdown',\n disable_web_page_preview: true\n }\n }\n}];"
},
"id": "code-parse",
"name": "解析 Pipeline 事件",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [220, 0]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-1",
"leftValue": "={{ $json.skip }}",
"rightValue": false,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-pipeline",
"name": "是 Pipeline 事件?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [440, 0]
},
{
"parameters": {
"method": "POST",
"url": "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.telegramBody) }}",
"options": {}
},
"id": "telegram-notify",
"name": "發送 Telegram 通知",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [660, -100]
},
{
"parameters": {},
"id": "no-op",
"name": "忽略非 Pipeline 事件",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [660, 100]
}
],
"connections": {
"GitLab Webhook": {
"main": [
[
{
"node": "解析 Pipeline 事件",
"type": "main",
"index": 0
}
]
]
},
"解析 Pipeline 事件": {
"main": [
[
{
"node": "是 Pipeline 事件?",
"type": "main",
"index": 0
}
]
]
},
"是 Pipeline 事件?": {
"main": [
[
{
"node": "發送 Telegram 通知",
"type": "main",
"index": 0
}
],
[
{
"node": "忽略非 Pipeline 事件",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}