1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| pipeline {
stages { stage ("参数解析") { steps { script { echo params.BUILD_PARAMS_JSON if (params.BUILD_PARAMS_JSON != null && params.BUILD_PARAMS_JSON != '') { buildParams = readJSON text: params.BUILD_PARAMS_JSON } else { error "BUILD_PARAMS_JSON is required params" }
// 通用参数与定制参数赋值 COMMON_PARAMS = buildParams['commonParams'] EXTEND_PARAMS = buildParams['extendParams']
// 入参json数据校验,通用参数必须包含 appCode + gitRepository if (COMMON_PARAMS['appCode'].isEmpty() || COMMON_PARAMS['gitRepository'].isEmpty() ) { error "buildParams['commonParams'] is error, must have appCode and gitRepository" } // gitBranch不存在则默认为master COMMON_PARAMS['gitBranch'].isEmpty() && (COMMON_PARAMS['gitBranch'] = "master") } } }
stage ("代码拉取") { steps { // 不同的应用对应不同的工作空间,避免工作空间相互影响覆盖 dir ("${COMMON_PARAMS['appCode']}") { // 拉取git仓库代码, 默认基于分支拉取 script { if (COMMON_PARAMS['gitEvent'] == "Merge Request Hook" || !COMMON_PARAMS['mrKey'].isEmpty()) { // SCM: MR必须使用此进行拉取代码,否则Sonar Scan无法识别此次SCM是基于MR gitCodeFetch("branch", COMMON_PARAMS['mrSourceBranch'], COMMON_PARAMS['gitRepository'], params.GITLAB_DEPLOY_CRED, "MR", COMMON_PARAMS['mrTargetBranch']) } else { gitCodeFetch("branch", COMMON_PARAMS['gitBranch'], COMMON_PARAMS['gitRepository'], params.GITLAB_DEPLOY_CRED) } } } } }
// 扫描参数此处组织,则业务代码无需sonar-project.properties文件,不侵入业务代码 stage ("扫描参数组织") { steps { script { ANALYSIS_PARAMS = [:] // ================= 通用扫描参数 ========================== // 通用扫描参数,其中个别参数存在值才进行赋值,否则空值可能会出现扫描异常情况 ANALYSIS_PARAMS['sonar.projectKey'] = COMMON_PARAMS['appCode'] ANALYSIS_PARAMS['sonar.projectName'] = COMMON_PARAMS['appCode'] ... // ================= 各语言的约定扫描参数 ====================== // 各语言的约定扫描参数,如:sonar.exclusions,sonar.sourceEncoding,默认扫描报告文件位置: .scannerwork/report-task.txt REPORT_FILE_PATH = ".scannerwork/report-task.txt" if (COMMON_PARAMS['appLanguage'] == "php") { ANALYSIS_PARAMS['sonar.exclusions'] = "vendor/**" } else if (COMMON_PARAMS['appLanguage'] == "go") { ANALYSIS_PARAMS['sonar.exclusions'] = "vendor/**" } else if (COMMON_PARAMS['appLanguage'] == "java") { // 以下mvn sonar:sonar 会默认设置,对于multi-module的仓库同样适用 //ANALYSIS_PARAMS['sonar.sources'] = "src" //ANALYSIS_PARAMS['sonar.java.binaries'] = "target/classes" } else { // TODO echo "TODO" }
// ================= 定制化扫描参数 ====================== // 定制化扫描参数(研发中台页面配置), 放置最后,可覆盖之前约定扫描参数 if (!EXTEND_PARAMS['customAnalysisParams'].isEmpty()) { EXTEND_PARAMS['customAnalysisParams'].each { key,value -> ANALYSIS_PARAMS["${key}"] = value } } } } }
stage ("前置扫描操作") { steps { dir("${COMMON_PARAMS['appCode']}") { script { if (COMMON_PARAMS['appLanguage'] == "java") { // java 语言需前置编译, 下载统一的setting.xml文件 sh "wget -O settings.xml http://.../settings-sonar.xml" } else { echo "Do Nothing" } } } } }
stage ("代码扫描") { environment { GIT_COMMIT = "" // 此环境变量置空, 否则影响MR检测时的Sonar回写Gitlab,注:取值为jenkins pipeline 仓库的Hash值 } steps { dir("${COMMON_PARAMS['appCode']}") { script { // 扫描参数拼接 println(JsonOutput.toJson(ANALYSIS_PARAMS)) def analysisParams = '' ANALYSIS_PARAMS.each { key,value -> analysisParams += "-D" + key + "=" + value + " " }
def scannerHome = tool 'SonarScanner' withSonarQubeEnv("SonarServer") { if (COMMON_PARAMS['appLanguage'] == "java") { // 适应multi-module的仓库, 将 sonar:sonar 作为独立的一步执行 //sh "mvn -s settings.xml clean install -Dmaven.test.skip=true" sh "mvn -s settings.xml clean install" sh "mvn -s settings.xml sonar:sonar ${analysisParams}" } else { sh "${scannerHome}/bin/sonar-scanner ${analysisParams}" } }
// 扫描质量门结果 timeout(time: 1, unit: 'HOURS') { // 返回格式Map,示例: {"status":"OK / ERROR"}, 返回放置在 ARTIFACTS['qualityGate'] ARTIFACTS['qualityGate'] = waitForQualityGate() } } } } } } }
|