-
Notifications
You must be signed in to change notification settings - Fork 17
/
ExtendedSCMBinder.java
141 lines (125 loc) · 6.2 KB
/
ExtendedSCMBinder.java
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
136
137
138
139
140
141
package org.jenkinsci.plugins.workflow.multibranch.extended.scm;
import hudson.AbortException;
import hudson.Extension;
import hudson.model.*;
import hudson.plugins.git.BranchSpec;
import hudson.plugins.git.GitSCM;
import hudson.scm.SCM;
import org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition;
import org.jenkinsci.plugins.workflow.flow.FlowDefinition;
import org.jenkinsci.plugins.workflow.flow.FlowDefinitionDescriptor;
import org.jenkinsci.plugins.workflow.flow.FlowExecution;
import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
/**
* This class consist of necessary methods for binding another Jenkins file from another repository to Multibranch pipeline.
*
* @author Aytunc BEKEN, aytuncbeken.ab@gmail.com
*/
public class ExtendedSCMBinder extends FlowDefinition {
private String remoteJenkinsFile = "";
private String remoteJenkinsFileBranch = "";
private SCM remoteJenkinsFileSCM;
private String scmSourceBranchName;
private boolean matchBranches;
private String fallbackBranch;
private String matchBranchFailMessage;
private String matchBranchFallbackMessage;
/**
* Constructor for the class.
*
* @param remoteJenkinsFile Path of the remote jenkins file from Remote Jenkins File Plugin descriptor
* @param remoteJenkinsFileSCM SCM definition from Remote Jenkins File Plugin descriptor
*/
public ExtendedSCMBinder(String remoteJenkinsFile, SCM remoteJenkinsFileSCM, String scmSourceBranchName, boolean matchBranches, String fallbackBranch) {
this.remoteJenkinsFile = remoteJenkinsFile;
this.remoteJenkinsFileSCM = remoteJenkinsFileSCM;
this.matchBranches = matchBranches;
this.scmSourceBranchName = scmSourceBranchName;
this.remoteJenkinsFileBranch = scmSourceBranchName;
this.fallbackBranch = fallbackBranch;
this.matchBranchFailMessage = "Failed to checkout for " + this.scmSourceBranchName + " branch for Jenkins File.";
this.matchBranchFallbackMessage = "Try to checkout " + this.fallbackBranch + " branch for Jenkins File. ";
}
/**
* Overwrites create method of FlowDefinition class. This methods sets the defined Jenkins file and defined SCM on
* Remote Jenkins Plugin to Pipeline job which will be created by MultiBranch Pipeline.
*
* @param handle {@link FlowExecutionOwner}
* @param listener {@link TaskListener}
* @param actions List of {@link Action}
* @return {@link FlowExecution}
* @throws Exception
*/
@Override
public FlowExecution create(FlowExecutionOwner handle, TaskListener listener, List<? extends Action> actions) throws Exception {
if (this.matchBranches && this.remoteJenkinsFileSCM instanceof GitSCM) {
try {
this.remoteJenkinsFileBranch = this.scmSourceBranchName;
return new CpsScmFlowDefinition(this.generateSCMWithNewBranch(this.scmSourceBranchName), this.remoteJenkinsFile).create(handle, listener, actions);
} catch (Exception ex) {
if (ex instanceof AbortException) {
// This can be reason of there is no branch named in the Remote Jenkinsfile Provider Repository
// Fallback to master branch
listener.getLogger().println(this.matchBranchFailMessage);
listener.getLogger().println(this.matchBranchFallbackMessage);
this.remoteJenkinsFileBranch = this.fallbackBranch;
return new CpsScmFlowDefinition(this.generateSCMWithNewBranch(this.fallbackBranch), this.remoteJenkinsFile).create(handle, listener, actions);
}
}
}
// If matchBranches not checked or SCM is not GitSCM, return with Remote Jenkinsfile Provider SCM as defined in Jenkins
return new CpsScmFlowDefinition(this.remoteJenkinsFileSCM, this.remoteJenkinsFile).create(handle, listener, actions);
}
/**
* Descriptor Implementation for {@link FlowDefinitionDescriptor}.
*/
@Extension
public static class DescriptorImpl extends FlowDefinitionDescriptor {
@Override
public String getDisplayName() {
return "Pipeline from Remote Jenkins File Plugin";
}
}
/**
* This method hides Remote Jenkins Plugin from other Pipeline Jobs and make visible to only MultiBranch Pipeline
*
* @see DescriptorVisibilityFilter
*/
@Extension
public static class HideMe extends DescriptorVisibilityFilter {
@Override
public boolean filter(Object context, @Nonnull Descriptor descriptor) {
if (descriptor instanceof DescriptorImpl) {
return context instanceof WorkflowJob && ((WorkflowJob) context).getParent() instanceof WorkflowMultiBranchProject;
}
return true;
}
}
/**
* Genereate new {@link SCM} object with a given branch name from defined Remote Jenkins File SCM definition
* @param branchName Branch name to use in new {@link SCM}
* @return new {@link SCM} defined with new branch
*/
private GitSCM generateSCMWithNewBranch(String branchName) {
GitSCM configuredGitSCM = (GitSCM) this.remoteJenkinsFileSCM;
return new GitSCM(configuredGitSCM.getUserRemoteConfigs(), Collections.singletonList(new BranchSpec(branchName)), configuredGitSCM.isDoGenerateSubmoduleConfigurations(), configuredGitSCM.getSubmoduleCfg(), configuredGitSCM.getBrowser(), configuredGitSCM.getGitTool(), configuredGitSCM.getExtensions());
}
public SCM getRemoteJenkinsFileSCM() {
return remoteJenkinsFileSCM;
}
public String getRemoteJenkinsFile() {
return remoteJenkinsFile;
}
public String getRemoteJenkinsFileBranch() {
// This null check is required for the jobs which were using version 1.12 ( or older).
// This value was not implemented on that version. Therefore, It becomes as null
if( remoteJenkinsFileBranch == null)
return "N/A";
return remoteJenkinsFileBranch;
}
}