Skip to content

Commit c0d1b6f

Browse files
authored
Merge pull request #619 from bensonhome/main
🎨 jenkins插件支持质量门禁
2 parents 0a53984 + 63dc9f3 commit c0d1b6f

6 files changed

Lines changed: 104 additions & 5 deletions

File tree

plugins/jenkins_plugin/README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,21 @@
33
Jenkins 2.277.1及以上
44

55
# 如何使用插件
6-
https://github.com/Tencent/CodeAnalysis/blob/main/plugins/jenkins_plugin/TCA_Jenkins_Plugin.pdf
6+
https://github.com/Tencent/CodeAnalysis/blob/main/plugins/jenkins_plugin/TCA_Jenkins_Plugin.pdf
7+
8+
# 设置质量门禁
9+
10+
1. 在TCA插件配置`质量门禁`参数,填写一个整数,当前分支的扫描问题量大于质量门禁值时,判断为不通过;否则为通过。完成后会将TCA结果状态(`success`|`failure`)输出到工作空间下的`tca_threshold.txt`文件中,供后续步骤判断和终止流水线。
11+
2. 在TCA插件后增加shell命令步骤,输入以下脚本内容:
12+
13+
```commandline
14+
tca_status=`cat tca_threshold.txt`
15+
if [ "${tca_status}" == "success" ]; then
16+
echo ">> tca scan pass!"
17+
else
18+
echo ">> tca scan fail! exit code 255"
19+
exit 255
20+
fi
21+
```
22+
23+
当质量门禁不通过时,会终止流水线(退出码:255)。

plugins/jenkins_plugin/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
33
<modelVersion>4.0.0</modelVersion>
4+
<dependencies>
5+
<dependency>
6+
<groupId>org.json</groupId>
7+
<artifactId>json</artifactId>
8+
<version>20200518</version>
9+
</dependency>
10+
</dependencies>
411
<parent>
512
<groupId>org.jenkins-ci.plugins</groupId>
613
<artifactId>plugin</artifactId>
@@ -29,6 +36,11 @@
2936
<scope>import</scope>
3037
<type>pom</type>
3138
</dependency>
39+
<dependency>
40+
<groupId>org.json</groupId>
41+
<artifactId>json</artifactId>
42+
<version>20160810</version>
43+
</dependency>
3244
</dependencies>
3345
</dependencyManagement>
3446

plugins/jenkins_plugin/src/main/java/io/jenkins/plugins/StartClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public static void startClient(String osName,
5353
+ constant_scanPlan
5454
+ isTotal;
5555

56+
listener.getLogger().println("run command: " + startCommand);
57+
5658
Process p = Runtime.getRuntime().exec(
5759
startCommand,
5860
new String[]{"PATH=" + env.get("PATH")},

plugins/jenkins_plugin/src/main/java/io/jenkins/plugins/TCABuilder.java

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// ==============================================================================
66

77
package io.jenkins.plugins;
8+
89
import edu.umd.cs.findbugs.annotations.NonNull;
910
import hudson.EnvVars;
1011
import hudson.Extension;
@@ -18,11 +19,16 @@
1819
import hudson.util.FormValidation;
1920
import jenkins.tasks.SimpleBuildStep;
2021
import org.apache.commons.lang.StringUtils;
22+
import org.json.JSONObject;
2123
import org.kohsuke.stapler.DataBoundConstructor;
2224
import org.kohsuke.stapler.DataBoundSetter;
2325
import org.kohsuke.stapler.QueryParameter;
26+
2427
import javax.servlet.ServletException;
28+
import java.io.BufferedWriter;
29+
import java.io.FileWriter;
2530
import java.io.IOException;
31+
import java.util.Objects;
2632
import java.util.Properties;
2733

2834
public class TCABuilder extends Builder implements SimpleBuildStep {
@@ -40,6 +46,8 @@ public class TCABuilder extends Builder implements SimpleBuildStep {
4046
private final String refSchemeID;
4147
private final String scanPlan;
4248

49+
private final String threshold;
50+
4351
@DataBoundConstructor
4452
public TCABuilder(String codeAnalysisPath,
4553
String token,
@@ -48,7 +56,8 @@ public TCABuilder(String codeAnalysisPath,
4856
String teamId,
4957
String projectName,
5058
String refSchemeID,
51-
String scanPlan) {
59+
String scanPlan,
60+
String threshold) {
5261
this.codeAnalysisPath = codeAnalysisPath;
5362
this.token = token;
5463
this.branchName = branchName;
@@ -57,6 +66,7 @@ public TCABuilder(String codeAnalysisPath,
5766
this.projectName = projectName;
5867
this.refSchemeID = refSchemeID;
5968
this.scanPlan = scanPlan;
69+
this.threshold = threshold;
6070
}
6171
public String getCodeAnalysisPath() {
6272
return codeAnalysisPath;
@@ -99,9 +109,11 @@ public void setTotal(boolean total) {
99109
this.total = total;
100110
}
101111

112+
public String getThreshold() { return threshold; }
113+
102114
@Override
103115
public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull EnvVars env,
104-
@NonNull Launcher launcher, @NonNull TaskListener listener) {
116+
@NonNull Launcher launcher, @NonNull TaskListener listener) throws IOException {
105117
try {
106118
Properties props = System.getProperties();
107119
String[] osNameArray = props.getProperty("os.name").split(" ");
@@ -167,12 +179,53 @@ public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNul
167179
branch,
168180
language,
169181
isTotal,
170-
constant_refSchemeID,
171-
constant_scanPlan,
182+
constant_refSchemeID,
183+
constant_scanPlan,
172184
listener,
173185
env);
174186
String fileName = clientPath + "/scan_status.json";
175187
String jsonStr = ReadJsonFile.readJsonFile(fileName);
188+
189+
// 如果设置了质量门禁,判断结果是否符合
190+
if (StringUtils.isNotBlank(threshold)){
191+
String tca_status = "success";
192+
assert jsonStr != null;
193+
JSONObject jsonObj = new JSONObject(jsonStr);
194+
String status = jsonObj.getString("status");
195+
if(Objects.equals(status, "success")){
196+
JSONObject scan_report = jsonObj.getJSONObject("scan_report");
197+
JSONObject lintscan = scan_report.getJSONObject("lintscan");
198+
JSONObject total = lintscan.getJSONObject("total");
199+
JSONObject state_detail = total.getJSONObject("state_detail");
200+
int total_active_issues = state_detail.getInt("active");
201+
if (total_active_issues > Integer.parseInt(threshold)){
202+
tca_status = "failure";
203+
jsonObj.put("status", tca_status);
204+
int error_code = 255;
205+
jsonObj.put("error_code", error_code);
206+
String msg = "扫描不通过! 问题量: " + total_active_issues + " , 超过质量门禁限制(" + threshold + ")";
207+
jsonObj.put("text", msg);
208+
jsonStr = jsonObj.toString(2);
209+
listener.getLogger().println("质量红线: " + msg);
210+
}else{
211+
String msg = "扫描通过! 问题量: " + total_active_issues + " , 满足质量门禁限制(" + threshold + ")";
212+
jsonObj.put("text", msg);
213+
jsonStr = jsonObj.toString(2);
214+
listener.getLogger().println("质量红线: " + msg);
215+
}
216+
}
217+
// 将门禁结果状态(success|failure)写入到工作空间目录下的txt文件中,方便后续步骤进行门禁判断
218+
try {
219+
String filepath = localCodePath + "/tca_threshold.txt";
220+
BufferedWriter out = new BufferedWriter(new FileWriter(filepath));
221+
out.write(tca_status);
222+
out.close();
223+
listener.getLogger().println("质量门禁结果已写入文件: " + filepath);
224+
} catch (IOException e) {
225+
e.printStackTrace();
226+
}
227+
}
228+
176229
run.addAction(new ViewReportAction(jsonStr));
177230
}
178231

@@ -241,10 +294,18 @@ public FormValidation doCheckTotal(@QueryParameter boolean value) throws IOExcep
241294
return FormValidation.ok();
242295
}
243296

297+
public FormValidation doCheckThreshold(@QueryParameter String value) throws IOException, ServletException {
298+
if (StringUtils.isBlank(value)){
299+
return FormValidation.warning("选填,质量门禁,填一个整数,问题量大于该值时,结果状态设置为失败,可在后续增加判断步骤终止流水线");
300+
}
301+
return FormValidation.ok();
302+
}
303+
244304
@Override
245305
public String getDisplayName() {
246306
return "TCA";
247307
}
308+
248309
@Override
249310
public boolean isApplicable(Class<? extends AbstractProject> aClass) {
250311
return true;

plugins/jenkins_plugin/src/main/resources/io/jenkins/plugins/TCABuilder/config.jelly

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@
3737
<f:checkbox />
3838
</f:entry>
3939

40+
<f:entry title="质量门禁" field="threshold">
41+
<f:textbox />
42+
</f:entry>
43+
4044
</j:jelly>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
质量门禁,填一个整数,问题量大于该值时,结果状态设置为失败,可在后续增加判断步骤终止流水线
3+
</div>

0 commit comments

Comments
 (0)