最近有一个jenkins发版需求,画一个草图说明下:
流水线作业直接开干:
pipeline {
agent any
environment {
DINGTALK_SECRET = 'SEC*******************' // 替换为您的钉钉机器人密钥
DINGTALK_ACCESS_TOKEN = '' // 替换为您的钉钉机器人 access token
DINGTALK_USER = '' // 钉钉用户的登录账号
GIT_REPO = '' //仓库地址
MAVEN_CMD = '' //打包命令
TARGET_DIR = '' //打包目录
TARGET_FILE = '' //jar包
REMOTE_DIR = '' //远程部署目录
BACKUP_DIR = "${REMOTE_DIR}/bak" //jar包备份目录
DEPLOY_SCRIPT = '' //shell脚本执行命令
PROJECT_NAME = '' //项目名称
}
stages {
stage('准备脚本') {
steps {
script {
writeFile file: 'generate_signature.py', text: '''\
import hmac
import hashlib
import base64
import time
import urllib.parse
import sys
def generate_dingtalk_signature(secret):
timestamp = str(round(time.time() * 1000))
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
signature = urllib.parse.quote(base64.b64encode(hmac_code))
return timestamp, signature
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python generate_signature.py <secret>")
sys.exit(1)
secret = sys.argv[1]
timestamp, signature = generate_dingtalk_signature(secret)
print(timestamp)
print(signature)
'''
}
}
}
stage('生成签名') {
steps {
script {
def result = sh(script: "python3 generate_signature.py ${env.DINGTALK_SECRET}", returnStdout: true).trim().split('\n')
env.TIMESTAMP = result[0]
env.SIGNATURE = result[1]
}
}
}
stage('选择Tag') {
steps {
script {
// 使用凭证获取tags
withCredentials([usernamePassword(credentialsId: '替换成你的服务器凭证ID(jenkins)', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
def tags = sh(script: "git ls-remote --tags http://${GIT_USERNAME}:${GIT_PASSWORD}@${GIT_REPO.split('http://')[1]} | awk -F'/' '{print \$3}'", returnStdout: true).trim().split("\n")
def userInput = input(id: 'userInput', message: '选择Tag', parameters: [choice(name: 'TAG', choices: tags.join('\n'), description: '请选择Tag进行构建')])
env.SELECTED_TAG = userInput
}
}
}
}
stage('发送钉钉通知') {
steps {
script {
def dingTalkWebhook = "https://oapi.dingtalk.com/robot/send?access_token=${env.DINGTALK_ACCESS_TOKEN}×tamp=${env.TIMESTAMP}&sign=${env.SIGNATURE}"
def message = [
msgtype: 'text',
text: [
content: "请审核此构建: ${env.BUILD_URL}\n项目名称: ${env.PROJECT_NAME}\nTag: ${env.SELECTED_TAG}\n@${env.DINGTALK_USER} 请进行审核。"
],
at: [
atMobiles: ["${env.DINGTALK_USER}"],
isAtAll: false
]
]
def messageJson = groovy.json.JsonOutput.toJson(message)
sh "curl -X POST '${dingTalkWebhook}' -H 'Content-Type: application/json' -d '${messageJson}'"
}
}
}
stage('审批') {
steps {
script {
def userInput = input(
id: 'approval_step',
message: '请在钉钉中审核此构建,然后在此输入结果',
parameters: [
booleanParam(defaultValue: true, description: '通过审核?', name: '审核结果')
]
)
if (userInput) {
echo '审核通过,继续执行后续步骤'
} else {
error '审核未通过,流水线终止'
}
}
}
}
stage('拉取代码') {
steps {
script {
// 使用凭证检出代码和选择的 tag
withCredentials([usernamePassword(credentialsId: 'git登录凭证(jenkins)', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
sh "git clone http://${GIT_USERNAME}:${GIT_PASSWORD}@${GIT_REPO.split('http://')[1]} . || true"
sh "git fetch --tags"
sh "git checkout tags/${env.SELECTED_TAG}"
}
}
}
}
stage('构建') {
steps {
sh "${MAVEN_CMD}"
}
}
stage('备份和部署') {
steps {
script {
def backupTimestamp = sh(script: 'date +"%Y%m%d%H%M%S"', returnStdout: true).trim()
// 备份文件
sshPublisher(publishers: [
sshPublisherDesc(configName: 'jenkins上配置的ssh服务器名称', transfers: [
sshTransfer(
sourceFiles: "${REMOTE_DIR}/${TARGET_FILE}",
remoteDirectory: "${BACKUP_DIR}",
execCommand: "mv ${REMOTE_DIR}/${TARGET_FILE} ${BACKUP_DIR}/${TARGET_FILE}-${backupTimestamp}"
),
], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)
])
// 部署文件
sshPublisher(publishers: [
sshPublisherDesc(configName: 'jenkins上配置的ssh服务器名称', transfers: [
sshTransfer(
sourceFiles: "${TARGET_DIR}/${TARGET_FILE}",
remoteDirectory: "${REMOTE_DIR}",
removePrefix: "${TARGET_DIR}",
execCommand: "${DEPLOY_SCRIPT}"
),
], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)
])
}
}
}
stage('发送部署结果通知') {
steps {
script {
def deployResult = '成功' // 这里假设部署成功,如果有部署失败的情况需要根据实际情况修改
def dingTalkWebhook = "https://oapi.dingtalk.com/robot/send?access_token=${env.DINGTALK_ACCESS_TOKEN}×tamp=${env.TIMESTAMP}&sign=${env.SIGNATURE}"
def message = [
msgtype: 'text',
text: [
content: "项目名称: ${env.PROJECT_NAME}\n发布结果: ${deployResult}\n发布的Tag: ${env.SELECTED_TAG}"
],
at: [
atMobiles: ["${env.DINGTALK_USER}"],
isAtAll: false
]
]
def messageJson = groovy.json.JsonOutput.toJson(message)
sh "curl -X POST '${dingTalkWebhook}' -H 'Content-Type: application/json' -d '${messageJson}'"
}
}
}
}
}
上述流水线脚本大致满足需求,点击构建触发后会hold住,等待选择tag,选择完tag后会推送钉钉消息通知审批,等待审批结束后流程才会走下去。
待优化的地方还有很多,欢迎大家指正