126 lines
4.7 KiB
JSON
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"
|
|
}
|
|
}
|