luhaowen 1 тиждень тому
батько
коміт
f0ff590f08

+ 36 - 0
src/org/feishu/FeishuNotifier.groovy

@@ -0,0 +1,36 @@
+package org.feishu
+import groovy.json.JsonOutput
+def send(String webhook,
+         String secret,
+         String title,
+         String text,
+         String btnTitle = '查看构建',
+         String btnUrl   = env.BUILD_URL) {
+
+    def signObj = secret ? new SignUtil().genSign(secret) : [:]
+    def card = [
+        msg_type: "interactive",
+        card: [
+            header: [
+                title: [tag: "plain_text", content: title]
+            ],
+            elements: [
+                [tag: "div", text: [tag: "lark_md", content: text]],
+                [tag: "hr"],
+                [tag: "action", actions: [
+                    [tag: "button", type: "primary", text: [tag: "plain_text", content: btnTitle],
+                     url: btnUrl]
+                ]]
+            ]
+        ]
+    ]
+    if (signObj) {
+        card += [timestamp: signObj.timestamp as String, sign: signObj.sign]
+    }
+    httpRequest consoleLogResponseBody: true,
+                contentType: 'APPLICATION_JSON',
+                httpMode: 'POST',
+                requestBody: JsonOutput.toJson(card),
+                url: webhook,
+                timeout: 30
+}

+ 9 - 10
src/org/feishu/SignUtil.groovy

@@ -1,15 +1,14 @@
 package org.feishu
-
+@Grab('commons-codec:commons-codec:1.15')
+import org.apache.commons.codec.binary.Base64
 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))
-    }
+def genSign(String secret) {
+    def ts = System.currentTimeMillis() / 1000 as int
+    def stringToSign = "$ts\n$secret"
+    def mac = Mac.getInstance("HmacSHA256")
+    mac.init(new SecretKeySpec(stringToSign.bytes, "HmacSHA256"))
+    def sign = Base64.encodeBase64String(mac.doFinal())
+    return [timestamp: ts, sign: sign]
 }

+ 0 - 13
vars/feishu.groovy

@@ -1,13 +0,0 @@
-#!/usr/bin/env groovy
-import groovy.json.JsonOutput
-
-def send(String webhook, Map card) {
-    httpRequest(
-        httpMode: 'POST',
-        url: webhook,
-        contentType: 'APPLICATION_JSON',
-        requestBody: JsonOutput.toJson([msg_type: 'interactive', card: card]),
-        validResponseCodes: '200',
-        consoleLogResponseBody: true
-    )
-}

+ 16 - 0
vars/feishuEnd.groovy

@@ -0,0 +1,16 @@
+#!/usr/bin/env groovy
+def call(String secret = '') {
+    def notifier = new org.feishu.FeishuNotifier()
+    def status = currentBuild.currentResult  // SUCCESS/FAILED/ABORTED
+    def emoji  = status == 'SUCCESS' ? '✅' : '❌'
+    def msg = """**构建结束**  
+项目:${env.JOB_NAME} #${env.BUILD_NUMBER}  
+结果:**${status}**  
+耗时:${currentBuild.durationString.replace(' and counting', '')}"""
+    notifier.send(
+        webhook: env.FEISHU_WEBHOOK,
+        secret : secret,
+        title  : "$emoji Jenkins 构建$status",
+        text   : msg
+    )
+}

+ 14 - 0
vars/feishuStart.groovy

@@ -0,0 +1,14 @@
+#!/usr/bin/env groovy
+def call(String secret = '') {
+    def notifier = new org.feishu.FeishuNotifier()
+    def msg = """**开始构建**  
+项目:${env.JOB_NAME}  
+构建编号:#${env.BUILD_NUMBER}  
+启动人:${currentBuild.getBuildCauses()[0].userId}"""
+    notifier.send(
+        webhook: env.FEISHU_WEBHOOK,
+        secret : secret,
+        title  : "🔔 Jenkins 构建开始",
+        text   : msg
+    )
+}

+ 0 - 42
vars/onBuildEvent.groovy

@@ -1,42 +0,0 @@
-#!/usr/bin/env groovy
-def call(String phase) {
-    // ===== 日志:确认加载的是新代码 =====
-    println "[feishu-card] onBuildEvent phase=${phase} , loaded from ${getClass().protectionDomain.codeSource.location}"
-    // =====================================
-    // 1. 先把凭据解析成真正的 URL 字符串
-    String webhook = credentials('feishu-webhook')
-    println "[feishu-card] resolved webhook=${webhook}"
-    // 2. 取环境变量
-    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')
-
-    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})"
-                ]
-            ]
-        ]
-    ]
-
-    // 3. 发送
-    feishu.send(webhook, card)
-}