5-22持续交付课程帖

课程内如记录:
sharedlib → saveReportToDB

import groovy.grape.Grape


/**
 * Created by sungaofei on 19/3/1.
 */

@Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.7')
@Grab(group = 'org.jsoup', module = 'jsoup', version = '1.10.3')
import org.jsoup.Jsoup
import groovyx.net.http.HTTPBuilder


import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import groovy.transform.Field

//可以指定maven仓库
//@GrabResolver(name = 'aliyun', root = 'http://maven.aliyun.com/nexus/content/groups/public/')
//加载数据库连接驱动包
//@Grab('mysql:mysql-connector-java:5.1.25')
//@GrabConfig(systemClassLoader=true)

//global variable
@Field jenkinsURL = "http://k8s.testing-studio.com:5003"

@Field int passed
@Field int failed
@Field int skipped
@Field int broken
@Field int unknown
@Field int total
@Field Map<String, Map<String, Integer>> map = new HashMap<>()

@NonCPS
def getResultFromAllure() {
    def reportURL = "/job/DailyBuild/${BUILD_NUMBER}/allure/"

//    if (env.BRANCH_NAME != "" && env.BRANCH_NAME != null) {
//        reportURL = "http://k8s.testing-studio.com:5003/job/Daily%20Build/allure/"
//    } else {
//        reportURL = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/allure/"
//    }

//    reportURL = "/view/API/job/sage-sdk-test/185/allure/"
    println(jenkinsURL+"${reportURL}widgets/summary.json")

    HTTPBuilder http = new HTTPBuilder("http://k8s.testing-studio.com:5003")
    //根据responsedata中的Content-Type header,调用json解析器处理responsedata
    http.get(path: "${reportURL}widgets/summary.json") { resp, json ->
        println resp.status
        passed = Integer.parseInt((String) json.statistic.passed)
        failed = Integer.parseInt((String) json.statistic.failed)
        skipped = Integer.parseInt((String) json.statistic.skipped)
        broken = Integer.parseInt((String) json.statistic.broken)
        unknown = Integer.parseInt((String) json.statistic.unknown)
        total = Integer.parseInt((String) json.statistic.total)
    }


}


def call() {
    getResultFromAllure()

    getDatabaseConnection(type: 'GLOBAL') {
//        map.each { feature, valueMap ->
//            def sqlString = "INSERT INTO func_test (name, build_id, feature, version, total, passed, unknown, skipped, failed, broken, create_time) VALUES ('${JOB_NAME}', '${BUILD_ID}', '${feature}', '${version}', " +
//                    "${valueMap['total']}, ${valueMap['passed']}, ${valueMap['unknown']}, ${valueMap['skipped']}, ${valueMap['failed']}, ${valueMap['broken']}, NOW())"
//            println(sqlString)
//
//            sql sql: sqlString
//        }

//        def lineCov = 0
//        def branchCov = 0
//        if (coverage != null && coverage != ""){
//            lineCov = getLineCov()
//            branchCov = getBranchCov() * 100
//
//        }

        def sqlString = "INSERT INTO func_test_summary (name, build_id, total, passed, unknown, skipped, failed, broken, create_time) VALUES ('${JOB_NAME}', '${BUILD_ID}', " +
                "${total}, ${passed}, ${unknown}, ${skipped}, ${failed}, ${broken}, NOW())"

        sql sql: sqlString

    }
}

sendEmail:

/**
 * Created by sungaofei on 20/2/8.
 */
@Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.7')

import groovyx.net.http.HTTPBuilder

import static groovyx.net.http.ContentType.*


import static groovyx.net.http.Method.*
import groovy.transform.Field


//global variable
@Field jenkinsURL = "http://auto.4paradigm.com"
@Field failed = "FAILED"
@Field success = "SUCCESS"
@Field inProgress = "IN_PROGRESS"
@Field abort = "ABORTED"

@NonCPS
def String checkJobStatus() {

    def url = ""

    if (env.BRANCH_NAME!= "" && env.BRANCH_NAME != null){
        String jobName = "${JOB_NAME}".split("/")[0]
        url = "/view/API/job/${jobName}/job/${env.BRANCH_NAME}/${BUILD_NUMBER}/wfapi/describe"
    }else {
        url = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/wfapi/describe"
    }
    HTTPBuilder http = new HTTPBuilder(jenkinsURL)
    String status = success

    println("1111111111")
    println("${JOB_NAME}")
    println(url)
    http.get(path: url) { resp, json ->
        if (resp.status != 200) {
            throw new RuntimeException("请求 ${url} 返回 ${resp.status} ")
        }
        List stages = json.stages

        for (int i = 0; i < stages.size(); i++) {
            def stageStatus = json.stages[i].status
            if (stageStatus == failed) {
                status = failed
                break
            }
            if (stageStatus == abort) {
                status = abort
                break
            }
        }
    }

    return status;

}


@NonCPS
def call(String to) {
    println("邮件列表:${to}")

    def reportURL = ""
    String jobName = "${JOB_NAME}"
    String blueOCeanURL = ""

    if (env.BRANCH_NAME!= "" && env.BRANCH_NAME != null){
        jobName = "${JOB_NAME}".split("/")[0]
        reportURL = "/view/API/job/${jobName}/job/${env.BRANCH_NAME}/${BUILD_NUMBER}/allure/"
//            http://auto.4paradigm.com/blue/organizations/jenkins/gitlabtest/detail/master/217/pipeline
        blueOCeanURL = "${jenkinsURL}/blue/organizations/jenkins/${jobName}/detail/${env.BRANCH_NAME}/${BUILD_NUMBER}/pipeline"
    }else{
        reportURL = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/allure/"
        blueOCeanURL = "${jenkinsURL}/blue/organizations/jenkins/${JOB_NAME}/detail/${JOB_NAME}/${BUILD_NUMBER}/pipeline"
    }

    def sendSuccess = {
//        blueOCeanURL = "${jenkinsURL}/blue/organizations/jenkins/${JOB_NAME}/detail/${JOB_NAME}/${BUILD_NUMBER}/pipeline"

        def fileContents = ""
        def passed = ""
        def failed = ""
        def skipped = ""
        def broken = ""
        def unknown = ""
        def total = ""
        HTTPBuilder http = new HTTPBuilder('http://auto.4paradigm.com')
        //根据responsedata中的Content-Type header,调用json解析器处理responsedata
        http.get(path: "${reportURL}widgets/summary.json") { resp, json ->
            println resp.status
            passed = json.statistic.passed
            failed = json.statistic.failed
            skipped = json.statistic.skipped
            broken = json.statistic.broken
            unknown = json.statistic.unknown
            total = json.statistic.total

        }

        println(passed)

        emailext body: """
<html>
  <style type="text/css">
  <!--
  ${fileContents}
  -->
  </style>
  <body>
  <div id="content">
  <h1>Summary</h1>
  <div id="sum2">
      <h2>Jenkins Build</h2>
      <ul>
      <li>Job 地址 : <a href='${BUILD_URL}'>${BUILD_URL}</a></li>
       <li>测试报告地址 : <a href='${jenkinsURL}${reportURL}'>${jenkinsURL}${reportURL}</a></li>
       <li>Pipeline 流程地址 : <a href='${blueOCeanURL}'>${blueOCeanURL}</a></li>
      </ul>

      <h2>测试结果汇总</h2>
      <ul>
      <li>用例总数 : ${total}</li>
      <li>pass数量 : ${passed}</li>
       <li>failed数量 :${failed} </li>
       <li>skip数量 : ${skipped}</li>
       <li>broken数量 : ${broken}</li>
      </ul>
  </div>
  </div></body></html>
    """, mimeType: 'text/html', subject: "${JOB_NAME} 测试结束", to: to

    }

    def send = { String subject ->
        emailext body: """
<html>
  <style type="text/css">
  <!--
  -->
  </style>
  <body>
  <div id="sum2">
      <h2>Jenkins Build</h2>
      <ul>
      <li>Job 地址 : <a href='${BUILD_URL}'>${BUILD_URL}</a></li>
        <li>测试报告地址 : <a href='${jenkinsURL}${reportURL}'>${jenkinsURL}${reportURL}</a></li>
       <li>Pipeline 流程地址 : <a href='${blueOCeanURL}'>${blueOCeanURL}</a></li>
      </ul>
  </div>
  </div></body></html>
    """, mimeType: 'text/html', subject: subject, to: to
    }

    String status = checkJobStatus()
//    String status = $BUILD_STATUS
    println("当前job 的运行状态为: ${status}")
    switch (status) {
        case ["SUCCESS", "UNSTABLE"]:
            sendSuccess()
            break
        case "FAILED":
            send("Job运行失败")
            break
        case "ABORTED":
            send("Job在运行中被取消")
            break
        default:
            send("Job运行结束")
    }

}

sendWeChart:

import groovy.grape.Grape

@Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.7')
@Grab(group = 'org.jsoup', module = 'jsoup', version = '1.10.3')
import org.jsoup.Jsoup
import groovyx.net.http.HTTPBuilder


import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import groovy.transform.Field

import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.URL
import java.net.URLConnection
//import com.alibaba.fastjson.JSONObject;

//可以指定maven仓库
//@GrabResolver(name = 'aliyun', root = 'http://maven.aliyun.com/nexus/content/groups/public/')
//加载数据库连接驱动包
//@Grab('mysql:mysql-connector-java:5.1.25')
//@GrabConfig(systemClassLoader=true)

//global variable
@Field jenkinsURL = "http://auto.4paradigm.com"

@Field int passed
@Field int failed
@Field int skipped
@Field int broken
@Field int unknown
@Field int total
@Field Map<String, Map<String, Integer>> map = new HashMap<>()

@NonCPS
def sendWechatAlarm() {
    def reportURL = ""
    if (env.BRANCH_NAME != "" && env.BRANCH_NAME != null) {
        reportURL = "/view/API/job/${jobName}/job/${env.BRANCH_NAME}/${BUILD_NUMBER}/allure/"
    } else {
        reportURL = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/allure/"
    }
    def s1=''
    def pic1 = 'https://a1.qpic.cn/psc?/V50K8Aj22Pi7jG1cQHUv13mYFX1nzj4i/ruAMsa53pVQWN7FLK88i5tD45cdngcdQjsTSVi5*o5lEyjoe7mOItBetTiR97DTcNquldh*u9wz8kCo8hgP9NIufqR5EyOROUWzZNvoLrRE!/m&ek=1&kp=1&pt=0&bo=2wEJAQAAAAABF.I!&tl=3&vuin=1677684467&tm=1597251600&sce=60-3-3&rf=0-0'
    def pic2 = 'http://a1.qpic.cn/psc?/V50K8Aj22Pi7jG1cQHUv13mYFX1nzj4i/ruAMsa53pVQWN7FLK88i5tHP1AzYWSQYCpP9GLLjmX2kVPpmgDpWYZyT7qEjJ9gca9K5NwjMAhXGJm7RwGD61afF2eRZuzBuLTCavKor4Pw!/m&ek=1&kp=1&pt=0&bo=2wEJAQAAAAABF.I!&tl=3&vuin=1677684467&tm=1597251600&sce=60-3-3&rf=0-0'
    def pic = ''
    def total=0
    def passed=0
    //reportURL = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/allure/"
    //reportURL = "/view/SDP/job/ui-auto-linkoop/9/allure/"
    HTTPBuilder http = new HTTPBuilder(jenkinsURL)
    http.get(path: "${reportURL}widgets/summary.json") { resp, json ->
        println resp.status
        passed = Integer.parseInt((String) json.statistic.passed)
        failed = Integer.parseInt((String) json.statistic.failed)
        skipped = Integer.parseInt((String) json.statistic.skipped)
        broken = Integer.parseInt((String) json.statistic.broken)
        unknown = Integer.parseInt((String) json.statistic.unknown)
        total = Integer.parseInt((String) json.statistic.total)
        s1="""Passed:${passed}  Failed:${failed}  Broken:${broken}\n环境信息 ${SGAE_URL}\n\n[查看测试报告]"""
        
    }
    if(total==passed && passed!=0) { 
            pic=pic1
    } else{ 
            pic=pic2
    }

    // webURL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=c916b757-a1a2-416d-bf63-10fb8cf769e5"
    HTTPBuilder http1 = new HTTPBuilder("${WEBHOOK_URL}")
    
    
    String s="""
    {
    "msgtype": "news",
    "news": {
       "articles" : [
           {
               "title" : "${VERSION}自动化运行结果",
               "description" : "${s1}",
               "url" : "${JENKINS_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/allure/#/behaviors",
               "picurl" : "${pic}"
           }
           
        ]
    }
   }
   """
    println s
    def jsonSlurper = new groovy.json.JsonSlurper()
    def object1 = jsonSlurper.parseText(s)
    print object1
    
    http1.request( POST, JSON ) { req ->
	    
	   
	    String picurl="http://a1.qpic.cn/psc?/V50K8Aj22Pi7jG1cQHUv13mYFX1nzj4i/ruAMsa53pVQWN7FLK88i5tHP1AzYWSQYCpP9GLLjmX2kVPpmgDpWYZyT7qEjJ9gca9K5NwjMAhXGJm7RwGD61afF2eRZuzBuLTCavKor4Pw!/m&ek=1&kp=1&pt=0&bo=2wEJAQAAAAABF.I!&tl=3&vuin=1677684467&tm=1597251600&sce=60-3-3&rf=0-0"
        Map<String, String> bodyParam = new HashMap<>()
        
	    bodyParam['picurl'] = picurl
	    bodyParam['title'] = "测试title"
        bodyParam['description'] = "测试description"
    
        Map<String, Map<String, String>> articles = new HashMap<>()
        articles['articles']=bodyParam
	    articles1 = [ articles ]
	    
	    body = object1
	    
	
	response.success = { resp, json ->
		// TODO process json data
		println resp.status
	}
}

}
def sendPostRequest(urlString, paramString) {
    def url = new URL(urlString)
    def conn = url.openConnection()
    conn.setDoOutput(true)
    def writer = new OutputStreamWriter(conn.getOutputStream())

    writer.write(paramString)
    writer.flush()
    String line
    def reader = new BufferedReader(new     InputStreamReader(conn.getInputStream()))
    while ((line = reader.readLine()) != null) {
      println line
    }
    writer.close()
    reader.close()
}




def call(String coverage = null, String version="release/3.8.2") {
    sendWechatAlarm()
    //sendPostRequest("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=c916b757-a1a2-416d-bf63-10fb8cf769e5", "msgtype=markdown&markdown={\"content\": \"test2\"}")

}

pipeline:

library 'test-lib'

pipeline {
    parameters {
        choice(name: 'ENV', choices: ['http', 'https'], description: '环境协议')
        string(name: 'SGAE_URL', defaultValue: '172.27.128.8:40126', description: '测试环境')
        booleanParam(name: 'IF_START', defaultValue: false, description: '是否初始化环境,适用于一个啥都没有的环境,会步创建hadoop资源,创建workspace、创建租户->上传lincese->配置zk等信息-> 更新内置算子api接口;创建工作区名称为:aios_test')
        booleanParam(name: 'DEPLOY_FLINK', defaultValue: false, description: '是否需要部署Flink')
        choice(name: 'VERSION', choices: ['4.x', '3.x'], description: '上传lincese版本;执行初始化环境才需要选这个')
        string(name: 'WORKSPACE_ID', defaultValue: '1', description: '工作区ID,如果是非空环境,则需填写wsid')
        string(name: 'TEST_VERSION', defaultValue: 'release/4.0.3', description: '测试代码分支')
        string(name: 'TEST_RUN_OP', defaultValue: 'sh run.sh', description: '测试用例运行命令;运行所有case输入:sh run.sh;分组运行case例如:sh run-group.sh "not aio"')
        string(name: 'TUNING_PARAM', defaultValue: '1', description: '由于有些算子由于默认的num-epoch、batch_size等参数设置较大,想快速验证算子是否正常较慢,因此通过该参数来调整不同的大小。其中设置default表示使用默认设置。目前只对paddlex算子')
        string(name: 'WE_TITLE', defaultValue: 'SAGE-SDK 自动化结果', description: '给企业微信发消息的标题,标题名称要控制10个字符以内,不然微信显示的标题就会截取显示了')


    }
    environment {
        WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=997aa130-57f8-42c5-bae7-e69111b67950"
        // WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=fff6a47f-0c07-453b-b6a3-92ca08cacfe4"

    }
    agent { label 'tech' }
    stages {
        stage('pull testing code') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'techUI']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'root', url: 'http://k8s.testing-studio.com:8880/root/uiautomation.git']]])
            }
        }
        stage('UI testing') {
            steps {
                sh '''
                cd techUI
                mvn clean test -Dmaven.test.failure.ignore=true -DsuiteXmlFile=testng-parallel.xml
                '''
                allure commandline: 'allure2.13', includeProperties: false, jdk: '', results: [[path: 'techUI/target/allure-results']]
                
                saveReportToDB()
                
                script {
                    env.RELEASE_SCOPE = input message: '是否通过QA测试', ok: '发布!', submitter: 'admin,root',
                            parameters: [choice(name: 'RELEASE_SCOPE', choices: 'patch\nminor\nmajor', description: 'What is the release scope?')]
                }
            }
        }
    
    }

    post {
        always {
            sh 'echo 11111111'
            
            
            
        }
    }
}

jenkins_pipeline_快速入门

jenkins_pipeline_语法详解

jenkins_pipeline_Sharedlib

jenkins_pipeline与k8s集成

jenkins_pipeline_jenkins集成k8s的原理和配置总结

jenkins_pipeline_多分支pipeline

jacoco代码覆盖率