在之前的几篇中,我分别介绍了基础环境的配置,skywaling+nacos的配置,nexus3的配置,围绕sonarqube的配置和构建镜像的配置。
这一篇中,主要配置消息通知
阅读此篇,你将了解如下列表中简单的实现方式:
- jenkins和gitlab触发(已实现)
- jenkins凭据使用(已实现)
- juit配置(已实现)
- sonarqube简单扫描(已实现)
- sonarqube覆盖率(已实现)
- 打包基于java的skywalking agent(上一章已实现)
- sonarqube与gitlab关联 (上一章已实现)
- 配置docker中构建docker (上一章已实现)
- mvn打包(上一章已实现)
- sonarqube简单分支扫描(上一章已实现)
- 基于gitlab来管理kustomize的k8s配置清单 (上一章已实现)
- kubectl部署 (上一章已实现)
- kubeclt deployment的状态跟踪 (上一章已实现)
- 钉钉消息的构建状态推送(本章实现)
前面我们断断续续的将最简单的持续集成做好,在cd阶段,使用了kustomize和argocd,并且搭配了kustomize和argocd做了gitops的部分事宜,现在们在添加一个基于钉钉的构建通知
我们创建一个钉钉机器人,关键字是DEVOPS
我们创建一个函数,其中采用markdown语法,如下:
分别需要向DingTalk传递几个行参,分别是:
- mdTitle 标签,这里的标签也就是我们创建的关键字: DEVOPS
- mdText 详细文本
- atUser 需要@谁
- atAll @所有人
- SedContent 通知标题
函数体如下:
def DingTalk(mdTitle, mdText, atAll, atUser = '' ,SedContent){
webhook = "https://oapi.dingtalk.com/robot/send?access_token=55d35d6f09f05388c1a8f7d73955cd9b7eaf4a0dd38"
sh """
curl --location --request POST ${webhook} \
--header 'Content-Type: application/json' \
--data '{
"msgtype": "markdown",
"markdown": {
"title": "${mdTitle}",
"text": "${SedContent}\n ${mdText}"
},
"at": {
"atMobiles": [
"${atUser}"
],
"isAtAll": "${atAll}"
}
}'
"""
}
而在流水线阶段添加post,如下
post {
success{
script{
// ItmesName="${JOB_NAME.split('/')[-1]}"
env.SedContent="构建通知"
mdText = "### ✅ \n ### 发起人: ${BUILD_TRIGGER_BY} \n ### 项目: ${JOB_NAME} \n ### 标签: $IPATH \n ### 时间: ${TIMENOW_CN} \n ### 提交SHA: ${GIT_COMMIT_TAGSHA} \n ### Commit Info: ${GIT_COMMIT_DESCRIBE} \n ### By:  \n"
DingTalk("DEVOPS", mdText, true, SedContent)
}
}
failure{
script{
env.SedContent="构建通知"
mdText = "### ❌ \n 发起人: ${BUILD_TRIGGER_BY} \n ### 项目: ${JOB_NAME} \n ### 标签: $IPATH \n ### 时间: ${TIMENOW_CN} \n ### 提交SHA: ${GIT_COMMIT_TAGSHA} \n ### Commit Info: ${GIT_COMMIT_DESCRIBE} \n ### By:  \n"
DingTalk("DEVOPS", mdText, true, SedContent)
}
}
}
当然,现在你看到了上面的函数传递中有很多变量,这些需要我们去获取
我们在任意一个阶段中的script中,并用env.声明到全局环境变量,添加如下
- GIT_COMMIT_DESCRIBE: 提交信息
- GIT_COMMIT_TAGSHA:提交的SHA值
- TIMENOW_CN:可阅读的时间格式
env.GIT_COMMIT_DESCRIBE = "${sh(script:'git log --oneline --no-merges|head -1', returnStdout: true)}"
env.GIT_COMMIT_TAGSHA=sh(script: """cut -b -40 .git/refs/remotes/origin/master""",returnStdout: true).trim()
env.TIMENOW_CN=sh(script: """date +%Y年%m月%d日%H时%M分%S秒""",returnStdout: true).trim()
进行构建,一旦构建完成,将会发送一段消息到钉钉
如下
而最终的管道流水线试图如下:
完整的流水线管道代码如下
try {
if ( "${onerun}" == "gitlabs"){
println("Trigger Branch: ${info_ref}")
RefName="${info_ref.split("/")[-1]}"
//自定义显示名称
currentBuild.displayName = "#${info_event_name}-${RefName}-${info_checkout_sha}"
//自定义描述
currentBuild.description = "Trigger by user ${info_user_username} 自动触发 \n branch: ${RefName} \n commit message: ${info_commits_0_message}"
BUILD_TRIGGER_BY="${info_user_username}"
BASEURL="${info_project_git_http_url}"
}
}catch(e){
BUILD_TRIGGER_BY="${currentBuild.getBuildCauses()[0].userId}"
currentBuild.description = "Trigger by user ${BUILD_TRIGGER_BY} 非自动触发 \n branch: ${branch} \ngit: ${BASEURL}"
}
pipeline{
//指定运行此流水线的节点
agent any
environment {
def tag_time = new Date().format("yyyyMMddHHmm")
def IPATH="harbor.marksugar.com/java/${JOB_NAME}:${tag_time}"
def kustomize_Git="git@172.16.100.47:devops/k8s-yaml.git"
def JOB_NAMES=sh (script: """echo ${kustomize_Git.split("/")[-1]} | cut -d . -f 1""",returnStdout: true).trim()
def Projects_Area="dev"
def apps_name="java-demo"
def projectGroup="java-demo"
def PACK_PATH="/usr/local/package"
}
//管道运行选项
options {
skipDefaultCheckout true
skipStagesAfterUnstable()
buildDiscarder(logRotator(numToKeepStr: '2'))
}
//流水线的阶段
stages{
//阶段1 获取代码
stage("CheckOut"){
steps {
script {
println("下载代码 --> 分支: ${env.branch}")
checkout( [$class: 'GitSCM',
branches: [[name: "${branch}"]],
extensions: [],
userRemoteConfigs: [[
credentialsId: 'gitlab-mark',
url: "${BASEURL}"]]])
}
}
}
stage("unit Test"){
steps{
script{
env.GIT_COMMIT_DESCRIBE = "${sh(script:'git log --oneline --no-merges|head -1', returnStdout: true)}"
env.TIMENOW_CN=sh(returnStdout: true, script: 'date +%Y年%m月%d日%H时%M分%S秒')
env.GIT_COMMIT_TAGSHA=sh (script: """cut -b -40 .git/refs/remotes/origin/master""",returnStdout: true).trim()
sh """
cd linuxea && mvn test -s /var/jenkins_home/.m2/settings.xml2
"""
}
}
post {
success {
script {
junit 'linuxea/target/surefire-reports/*.xml'
}
}
}
}
stage("coed sonar"){
environment {
def JOB_NAMES=sh (script: """echo ${BASEURL.split("/")[-1]} | cut -d . -f 1""",returnStdout: true).trim()
def Projects_GitId=sh (script: """curl --silent --heade "PRIVATE-TOKEN: zrv1vpfZTtEFCJGrJczB" "http://gitlab.marksugar.com/api/v4/projects?simple=true"| /usr/local/package/jq-1.6/jq -rc '.[]|select(.path_with_namespace == "java/java-demo")'| /usr/local/package/jq-1.6/jq .id""",returnStdout: true).trim()
def SONAR_git_TOKEN="K8DtxxxifxU1gQeDgvDK"
def GitLab_Address="http://172.16.100.47"
}
steps{
script {
withCredentials([string(credentialsId: 'sonarqube-token', variable: 'SONAR_TOKEN')]) {
sh """
cd linuxea && \
/usr/local/package/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner \
-Dsonar.host.url=${GitLab_Address}:9000 \
-Dsonar.projectKey=${JOB_NAME} \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectVersion=${BUILD_NUMBER} \
-Dsonar.login=${SONAR_TOKEN} \
-Dsonar.ws.timeout=30 \
-Dsonar.projectDescription="my first project!" \
-Dsonar.links.homepage=${env.BASEURL} \
-Dsonar.links.ci=${BUILD_URL} \
-Dsonar.sources=src \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.java.binaries=target/classes \
-Dsonar.java.test.binaries=target/test-classes \
-Dsonar.java.surefire.report=target/surefire-reports \
-Dsonar.core.codeCoveragePlugin=jacoco \
-Dsonar.jacoco.reportPaths=target/jacoco.exec \
-Dsonar.branch.name=${branch} \
-Dsonar.gitlab.commit_sha=${GIT_COMMIT_TAGSHA} \
-Dsonar.gitlab.ref_name=${branch} \
-Dsonar.gitlab.project_id=${Projects_GitId} \
-Dsonar.dynamicAnalysis=reuseReports \
-Dsonar.gitlab.failure_notification_mode=commit-status \
-Dsonar.gitlab.url=${GitLab_Address} \
-Dsonar.gitlab.user_token=${SONAR_git_TOKEN} \
-Dsonar.gitlab.api_version=v4
"""
}
}
}
}
stage("mvn build"){
steps {
script {
sh """
cd linuxea
mvn clean install -Dautoconfig.skip=true -Dmaven.test.skip=false -Dmaven.test.failure.ignore=true -s /var/jenkins_home/.m2/settings.xml2
"""
}
}
}
stage("docker build"){
steps{
script{
sh """
cd linuxea
docker ps -a
cp -r /usr/local/package/skywalking-agent ./
docker build -f ./Dockerfile -t $IPATH .
docker push $IPATH
docker rmi -f $IPATH
"""
}
}
}
stage('Deploy') {
steps {
sh '''
[ ! -d ${JOB_NAMES} ] || rm -rf ${JOB_NAMES} }
git clone ${kustomize_Git} && cd ${JOB_NAMES} && git checkout ${apps_name}
echo "push latest images: $IPATH"
echo "`date +%F-%T` imageTag: $IPATH buildId: ${BUILD_NUMBER} " >> ./buildhistory-$Projects_Area-${apps_name}.log
cd overlays/$Projects_Area
${PACK_PATH}/kustomize edit set image $IPATH
cd ../..
git add .
git config --global push.default matching
git config user.name zhengchao.tang
git config user.email usertzc@163.com
git commit -m "image tag $IPATH-> ${imageUrlPath}"
git push -u origin ${apps_name}
${PACK_PATH}/argocd app sync ${apps_name} --retry-backoff-duration=10s -l marksugar/app=${apps_name}
'''
// ${PACK_PATH}/argocd app sync ${apps_name} --retry-backoff-duration=10s -l marksugar/app=${apps_name}
} // ${PACK_PATH}/kustomize build overlays/$Projects_Area/ | ${PACK_PATH}/kubectl --kubeconfig /var/jenkins_home/.kube/config-1.23.1-dev apply -f -
}
stage('status watch') {
steps {
sh '''
${PACK_PATH}/kubectl --kubeconfig /var/jenkins_home/.kube/config-1.23.1-dev -n ${projectGroup} rollout status deployment ${apps_name} --watch --timeout=10m
'''
}
}
}
post {
success{
script{
// ItmesName="${JOB_NAME.split('/')[-1]}"
env.SedContent="构建通知"
mdText = "### ✅ \n ### 发起人: ${BUILD_TRIGGER_BY} \n ### 项目: ${JOB_NAME} \n ### 标签: $IPATH \n ### 时间: ${TIMENOW_CN} \n ### 提交SHA: ${GIT_COMMIT_TAGSHA} \n ### Commit Info: ${GIT_COMMIT_DESCRIBE} \n ### By:  \n"
DingTalk("DEVOPS", mdText, true, SedContent)
}
}
failure{
script{
env.SedContent="构建通知"
mdText = "### ❌ \n 发起人: ${BUILD_TRIGGER_BY} \n ### 项目: ${JOB_NAME} \n ### 标签: $IPATH \n ### 时间: ${TIMENOW_CN} \n ### 提交SHA: ${GIT_COMMIT_TAGSHA} \n ### Commit Info: ${GIT_COMMIT_DESCRIBE} \n ### By:  \n"
DingTalk("DEVOPS", mdText, true, SedContent)
}
}
}
}
def DingTalk(mdTitle, mdText, atAll, atUser = '' ,SedContent){
webhook = "https://oapi.dingtalk.com/robot/send?access_token=55d35d6f09f05388c1a8f7d73955cd9b7eaf4a0dd3803abdd1452e83d5b607ab"
sh """
curl --location --request POST ${webhook} \
--header 'Content-Type: application/json' \
--data '{
"msgtype": "markdown",
"markdown": {
"title": "${mdTitle}",
"text": "${SedContent}\n ${mdText}"
},
"at": {
"atMobiles": [
"${atUser}"
],
"isAtAll": "${atAll}"
}
}'
"""
}
现在,一个最简单的gitops的demo项目搭建完成
评论