luhaowen пре 1 недеља
комит
7ace3d7e7f
3 измењених фајлова са 88 додато и 0 уклоњено
  1. 15 0
      src/org/feishu/SignUtil.groovy
  2. 22 0
      vars/feishu.groovy
  3. 51 0
      vars/onBuildEvent.groovy

+ 15 - 0
src/org/feishu/SignUtil.groovy

@@ -0,0 +1,15 @@
+package org.feishu
+
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+import java.nio.charset.StandardCharsets
+
+class SignUtil {
+    static String genSign(String secret, Long timestamp) {
+        String stringToSign = timestamp + "\n" + secret
+        Mac mac = Mac.getInstance("HmacSHA256")
+        mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"))
+        byte[] signData = mac.doFinal(new byte[0])
+        return new String(Base64.getEncoder().encode(signData))
+    }
+}

+ 22 - 0
vars/feishu.groovy

@@ -0,0 +1,22 @@
+#!/usr/bin/env groovy
+import groovy.json.JsonOutput
+import org.feishu.SignUtil
+
+def send(String webhook, String secret, Map card) {
+    Long ts = System.currentTimeMillis() / 1000
+    String sign = SignUtil.genSign(secret, ts)
+    def body = [
+        timestamp: ts,
+        sign     : sign,
+        msg_type : "interactive",
+        card     : card
+    ]
+    httpRequest(
+        httpMode: 'POST',
+        requestBody: JsonOutput.toJson(body),
+        contentType: 'APPLICATION_JSON',
+        url: webhook,
+        consoleLogResponseBody: true,
+        validResponseCodes: '200'
+    )
+}

+ 51 - 0
vars/onBuildEvent.groovy

@@ -0,0 +1,51 @@
+#!/usr/bin/env groovy
+/**
+ * 在 pipeline 的开始 & 结束各调用一次即可:
+ * onBuildEvent('start')
+ * onBuildEvent('end')
+ */
+def call(String phase) {
+    // 从 Jenkins 环境变量里取值
+    String jobName = env.JOB_NAME
+    String buildNum = env.BUILD_NUMBER
+    String branch = env.GIT_BRANCH ?: 'unknown'
+    String result = currentBuild.currentResult ?: 'UNKNOWN'
+    String buildUrl = env.BUILD_URL
+    String duration = phase == 'end' ? "${currentBuild.durationString}" : '-'
+
+    // 颜色 & 图标随结果变化
+    String headerColor = phase == 'start' ? 'blue' : (result == 'SUCCESS' ? 'green' : 'red')
+    String headerIcon  = phase == 'start' ? 'rocket' : (result == 'SUCCESS' ? 'check_circle' : 'error')
+
+    def card = [
+        header: [
+            title: [
+                tag: "plain_text",
+                content: "Jenkins ${phase == 'start' ? '开始' : '结束'}通知"
+            ],
+            template: headerColor
+        ],
+        elements: [
+            [
+                tag: "div",
+                text: [
+                    tag: "lark_md",
+                    content: "**项目:** ${jobName}\n" +
+                             "**分支:** ${branch}\n" +
+                             "**构建:** #${buildNum}\n" +
+                             "**结果:** ${result}\n" +
+                             "**耗时:** ${duration}\n" +
+                             "**链接:** [查看详情](${buildUrl})"
+                ]
+            ]
+        ]
+    ]
+
+    // 从 Jenkins 凭据里取机器人配置,避免硬编码
+    def robot = [
+        webhook: credentials('feishu-webhook'),
+        secret : credentials('feishu-secret')
+    ]
+
+    feishu.send(robot.webhook, robot.secret, card)
+}