// BuildFlow buildflow-portal CI/CD
// ①拉取代码 -> ②编译打包 -> 推送Harbor -> ③部署
// 飞书卡片通知(成功绿/失败红), 内联闭包用 JsonOutput 无插件依赖

def feishuNotify = { String result, String failedStageName = "" ->
    def dur = currentBuild.durationString.replace(" and counting", "")
    def commit = ""
    try { commit = sh(script: "git log -1 --pretty=format:%s__%an 2>/dev/null | head -1", returnStdout: true).trim() } catch(ignored) {}
    def isOk = (result == "SUCCESS")
    def emoji = isOk ? "✅" : "❌"
    def color = isOk ? "green" : "red"
    def title = emoji + " CI/CD " + (isOk ? "成功" : "失败") + " · " + env.JOB_NAME + " #" + env.BUILD_NUMBER
    def stMsg = isOk ? "成功" : "失败"
    def fields = [
        [is_short: true, text: [tag: "lark_md", content: "**项目**\n" + env.JOB_NAME]],
        [is_short: true, text: [tag: "lark_md", content: "**耗时**\n" + dur]],
        [is_short: true, text: [tag: "lark_md", content: "**提交**\n" + commit.take(50)]],
        [is_short: true, text: [tag: "lark_md", content: "**状态**\n" + stMsg]]
    ]
    def elements = [[tag: "div", fields: fields], [tag: "hr"]]
    if (isOk) {
        elements.add([tag: "div", text: [tag: "lark_md", content: "镜像地址\n" + env.IMAGE + ":" + env.TAG]])
    } else if (failedStageName) {
        elements.add([tag: "div", text: [tag: "lark_md", content: "失败阶段\n" + failedStageName]])
    }
    def burl = env.BUILD_URL
    if (burl == null) { burl = "http://115.191.51.246:8080/job/" + env.JOB_NAME.replace("/", "/job/") + "/" }
    elements.add([tag: "action", actions: [[tag: "button", text: [tag: "plain_text", content: "查看构建"], url: burl, type: isOk ? "primary" : "danger"]]])
    def card = [msg_type: "interactive", card: [header: [title: [tag: "plain_text", content: title], template: color], elements: elements]]
    def jsonStr = groovy.json.JsonOutput.toJson(card)
    writeFile file: "/tmp/feishu_msg.json", text: jsonStr
    sh "curl -sS -X POST https://open.feishu.cn/open-apis/bot/v2/hook/d215e8ed-edea-4f07-a77c-2a0e5b52d9b9 -H \x27Content-Type: application/json\x27 -d @/tmp/feishu_msg.json || true"
    sh "rm -f /tmp/feishu_msg.json"
}

pipeline {
    agent any
    environment {
        HARBOR = "43.134.235.58:58080"
        IMAGE  = "${HARBOR}/buildflow/buildflow-portal"
        TAG    = "${env.BUILD_NUMBER}"
    }
    options {
        timeout(time: 30, unit: "MINUTES")
        buildDiscarder(logRotator(numToKeepStr: "10"))
    }
    stages {
        stage("① 拉取代码") {
            steps {
                checkout scm
                sh "git log --oneline -3"
            }
        }
        stage("② 编译打包") {
            steps {
                sh "docker build -t ${IMAGE}:${TAG} -t ${IMAGE}:latest ."
                sh "docker images | grep ${IMAGE} | head -2"
            }
        }
        stage("推送 Harbor") {
            steps {
                withCredentials([usernamePassword(credentialsId: "harbor-credentials", usernameVariable: "HUSER", passwordVariable: "HPASS")]) {
                    sh """
                        echo \$HPASS | docker login ${HARBOR} -u \$HUSER --password-stdin
                        docker push ${IMAGE}:${TAG}
                        docker push ${IMAGE}:latest
                        docker logout ${HARBOR}
                    """
                }
            }
        }
        stage("③ 部署") {
            steps {
                script {
                    try {
                        node("deploy-agent") {
                            sh """
                                docker pull ${IMAGE}:latest
                                docker rm -f buildflow-portal 2>/dev/null || true
                                docker run -d --name buildflow-portal --restart unless-stopped -p 5174:5173 ${IMAGE}:latest
                            """
                        }
                        echo "部署完成"
                    } catch (e) {
                        echo "部署节点(deploy-agent)暂不可用,跳过自动部署。镜像已推送 Harbor。"
                    }
                }
            }
        }
    }
    post {
        success {
            script { feishuNotify("SUCCESS") }
        }
        failure {
            script { feishuNotify("FAILURE", "构建过程中失败,请查看日志") }
        }
        always {
            sh "docker rmi ${IMAGE}:${TAG} ${IMAGE}:latest 2>/dev/null || true"
            deleteDir()
        }
    }
}
