55// ==============================================================================
66
77package io .jenkins .plugins ;
8+
89import edu .umd .cs .findbugs .annotations .NonNull ;
910import hudson .EnvVars ;
1011import hudson .Extension ;
1819import hudson .util .FormValidation ;
1920import jenkins .tasks .SimpleBuildStep ;
2021import org .apache .commons .lang .StringUtils ;
22+ import org .json .JSONObject ;
2123import org .kohsuke .stapler .DataBoundConstructor ;
2224import org .kohsuke .stapler .DataBoundSetter ;
2325import org .kohsuke .stapler .QueryParameter ;
26+
2427import javax .servlet .ServletException ;
28+ import java .io .BufferedWriter ;
29+ import java .io .FileWriter ;
2530import java .io .IOException ;
31+ import java .util .Objects ;
2632import java .util .Properties ;
2733
2834public 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 ;
0 commit comments