Merge pull request #3131 from LinuxSuRen/gitlab-multi-branch-pipeline
Add gitlab multi-branch pipeline support
This commit is contained in:
154
pkg/simple/client/devops/jenkins/internal/gitlab.go
Normal file
154
pkg/simple/client/devops/jenkins/internal/gitlab.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/beevik/etree"
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func AppendGitlabSourceToEtree(source *etree.Element, gitSource *devopsv1alpha3.GitlabSource) {
|
||||
source.CreateAttr("class", "io.jenkins.plugins.gitlabbranchsource.GitLabSCMSource")
|
||||
source.CreateAttr("plugin", "gitlab-branch-source")
|
||||
source.CreateElement("id").SetText(gitSource.ScmId)
|
||||
source.CreateElement("serverName").SetText(gitSource.ServerName)
|
||||
source.CreateElement("credentialsId").SetText(gitSource.CredentialId)
|
||||
source.CreateElement("projectOwner").SetText(gitSource.Owner)
|
||||
source.CreateElement("projectPath").SetText(gitSource.Repo)
|
||||
traits := source.CreateElement("traits")
|
||||
if gitSource.DiscoverBranches != 0 {
|
||||
traits.CreateElement("io.jenkins.plugins.gitlabbranchsource.BranchDiscoveryTrait").
|
||||
CreateElement("strategyId").SetText(strconv.Itoa(gitSource.DiscoverBranches))
|
||||
}
|
||||
if gitSource.DiscoverTags {
|
||||
traits.CreateElement("io.jenkins.plugins.gitlabbranchsource.TagDiscoveryTrait")
|
||||
}
|
||||
if gitSource.DiscoverPRFromOrigin != 0 {
|
||||
traits.CreateElement("io.jenkins.plugins.gitlabbranchsource.OriginMergeRequestDiscoveryTrait").
|
||||
CreateElement("strategyId").SetText(strconv.Itoa(gitSource.DiscoverPRFromOrigin))
|
||||
}
|
||||
if gitSource.DiscoverPRFromForks != nil {
|
||||
forkTrait := traits.CreateElement("io.jenkins.plugins.gitlabbranchsource.ForkMergeRequestDiscoveryTrait")
|
||||
forkTrait.CreateElement("strategyId").SetText(strconv.Itoa(gitSource.DiscoverPRFromForks.Strategy))
|
||||
trustClass := "io.jenkins.plugins.gitlabbranchsource.ForkMergeRequestDiscoveryTrait$"
|
||||
switch gitSource.DiscoverPRFromForks.Trust {
|
||||
case 1:
|
||||
trustClass += "TrustMembers" // it's difference with GitHub
|
||||
case 2:
|
||||
trustClass += "TrustEveryone"
|
||||
case 3:
|
||||
trustClass += "TrustPermission"
|
||||
case 4:
|
||||
trustClass += "TrustNobody"
|
||||
}
|
||||
forkTrait.CreateElement("trust").CreateAttr("class", trustClass)
|
||||
}
|
||||
if gitSource.CloneOption != nil {
|
||||
cloneExtension := traits.CreateElement("jenkins.plugins.git.traits.CloneOptionTrait").CreateElement("extension")
|
||||
cloneExtension.CreateAttr("class", "hudson.plugins.git.extensions.impl.CloneOption")
|
||||
cloneExtension.CreateElement("shallow").SetText(strconv.FormatBool(gitSource.CloneOption.Shallow))
|
||||
cloneExtension.CreateElement("noTags").SetText(strconv.FormatBool(false))
|
||||
cloneExtension.CreateElement("honorRefspec").SetText(strconv.FormatBool(true))
|
||||
cloneExtension.CreateElement("reference")
|
||||
if gitSource.CloneOption.Timeout >= 0 {
|
||||
cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(gitSource.CloneOption.Timeout))
|
||||
} else {
|
||||
cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(10))
|
||||
}
|
||||
|
||||
if gitSource.CloneOption.Depth >= 0 {
|
||||
cloneExtension.CreateElement("depth").SetText(strconv.Itoa(gitSource.CloneOption.Depth))
|
||||
} else {
|
||||
cloneExtension.CreateElement("depth").SetText(strconv.Itoa(1))
|
||||
}
|
||||
}
|
||||
if gitSource.RegexFilter != "" {
|
||||
regexTraits := traits.CreateElement("jenkins.scm.impl.trait.RegexSCMHeadFilterTrait")
|
||||
regexTraits.CreateAttr("plugin", "scm-api@2.4.0")
|
||||
regexTraits.CreateElement("regex").SetText(gitSource.RegexFilter)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetGitlabSourceFromEtree(source *etree.Element) (gitSource *devopsv1alpha3.GitlabSource) {
|
||||
gitSource = &devopsv1alpha3.GitlabSource{}
|
||||
if credential := source.SelectElement("credentialsId"); credential != nil {
|
||||
gitSource.CredentialId = credential.Text()
|
||||
}
|
||||
if serverName := source.SelectElement("serverName"); serverName != nil {
|
||||
gitSource.ServerName = serverName.Text()
|
||||
}
|
||||
if repoOwner := source.SelectElement("projectOwner"); repoOwner != nil {
|
||||
gitSource.Owner = repoOwner.Text()
|
||||
}
|
||||
if repository := source.SelectElement("projectPath"); repository != nil {
|
||||
gitSource.Repo = repository.Text()
|
||||
}
|
||||
traits := source.SelectElement("traits")
|
||||
if branchDiscoverTrait := traits.SelectElement(
|
||||
"io.jenkins.plugins.gitlabbranchsource.BranchDiscoveryTrait"); branchDiscoverTrait != nil {
|
||||
strategyId, _ := strconv.Atoi(branchDiscoverTrait.SelectElement("strategyId").Text())
|
||||
gitSource.DiscoverBranches = strategyId
|
||||
}
|
||||
if tagDiscoverTrait := traits.SelectElement(
|
||||
"io.jenkins.plugins.gitlabbranchsource.TagDiscoveryTrait"); tagDiscoverTrait != nil {
|
||||
gitSource.DiscoverTags = true
|
||||
}
|
||||
if originPRDiscoverTrait := traits.SelectElement(
|
||||
"io.jenkins.plugins.gitlabbranchsource.OriginMergeRequestDiscoveryTrait"); originPRDiscoverTrait != nil {
|
||||
strategyId, _ := strconv.Atoi(originPRDiscoverTrait.SelectElement("strategyId").Text())
|
||||
gitSource.DiscoverPRFromOrigin = strategyId
|
||||
}
|
||||
if forkPRDiscoverTrait := traits.SelectElement(
|
||||
"io.jenkins.plugins.gitlabbranchsource.ForkMergeRequestDiscoveryTrait"); forkPRDiscoverTrait != nil {
|
||||
strategyId, _ := strconv.Atoi(forkPRDiscoverTrait.SelectElement("strategyId").Text())
|
||||
trustClass := forkPRDiscoverTrait.SelectElement("trust").SelectAttr("class").Value
|
||||
trust := strings.Split(trustClass, "$")
|
||||
switch trust[1] {
|
||||
case "TrustMembers": // it's difference with GitHub
|
||||
gitSource.DiscoverPRFromForks = &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: strategyId,
|
||||
Trust: 1,
|
||||
}
|
||||
case "TrustEveryone":
|
||||
gitSource.DiscoverPRFromForks = &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: strategyId,
|
||||
Trust: 2,
|
||||
}
|
||||
case "TrustPermission":
|
||||
gitSource.DiscoverPRFromForks = &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: strategyId,
|
||||
Trust: 3,
|
||||
}
|
||||
case "TrustNobody":
|
||||
gitSource.DiscoverPRFromForks = &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: strategyId,
|
||||
Trust: 4,
|
||||
}
|
||||
}
|
||||
if cloneTrait := traits.SelectElement(
|
||||
"jenkins.plugins.git.traits.CloneOptionTrait"); cloneTrait != nil {
|
||||
if cloneExtension := cloneTrait.SelectElement(
|
||||
"extension"); cloneExtension != nil {
|
||||
gitSource.CloneOption = &devopsv1alpha3.GitCloneOption{}
|
||||
if value, err := strconv.ParseBool(cloneExtension.SelectElement("shallow").Text()); err == nil {
|
||||
gitSource.CloneOption.Shallow = value
|
||||
}
|
||||
if value, err := strconv.ParseInt(cloneExtension.SelectElement("timeout").Text(), 10, 32); err == nil {
|
||||
gitSource.CloneOption.Timeout = int(value)
|
||||
}
|
||||
if value, err := strconv.ParseInt(cloneExtension.SelectElement("depth").Text(), 10, 32); err == nil {
|
||||
gitSource.CloneOption.Depth = int(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if regexTrait := traits.SelectElement(
|
||||
"jenkins.scm.impl.trait.RegexSCMHeadFilterTrait"); regexTrait != nil {
|
||||
if regex := regexTrait.SelectElement("regex"); regex != nil {
|
||||
gitSource.RegexFilter = regex.Text()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/beevik/etree"
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins/internal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -812,19 +813,21 @@ func createMultiBranchPipelineConfigXml(projectName string, pipeline *devopsv1al
|
||||
source := branchSource.CreateElement("source")
|
||||
|
||||
switch pipeline.SourceType {
|
||||
case "git":
|
||||
case devopsv1alpha3.SourceTypeGit:
|
||||
appendGitSourceToEtree(source, pipeline.GitSource)
|
||||
case "github":
|
||||
case devopsv1alpha3.SourceTypeGithub:
|
||||
appendGithubSourceToEtree(source, pipeline.GitHubSource)
|
||||
case "svn":
|
||||
case devopsv1alpha3.SourceTypeGitlab:
|
||||
internal.AppendGitlabSourceToEtree(source, pipeline.GitlabSource)
|
||||
case devopsv1alpha3.SourceTypeSVN:
|
||||
appendSvnSourceToEtree(source, pipeline.SvnSource)
|
||||
case "single_svn":
|
||||
case devopsv1alpha3.SourceTypeSingleSVN:
|
||||
appendSingleSvnSourceToEtree(source, pipeline.SingleSvnSource)
|
||||
case "bitbucket_server":
|
||||
case devopsv1alpha3.SourceTypeBitbucket:
|
||||
appendBitbucketServerSourceToEtree(source, pipeline.BitbucketServerSource)
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("unsupport source type")
|
||||
return "", fmt.Errorf("unsupport source type: %s", pipeline.SourceType)
|
||||
}
|
||||
|
||||
factory := project.CreateElement("factory")
|
||||
@@ -881,21 +884,24 @@ func parseMultiBranchPipelineConfigXml(config string) (*devopsv1alpha3.MultiBran
|
||||
switch source.SelectAttr("class").Value {
|
||||
case "org.jenkinsci.plugins.github_branch_source.GitHubSCMSource":
|
||||
pipeline.GitHubSource = getGithubSourcefromEtree(source)
|
||||
pipeline.SourceType = "github"
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeGithub
|
||||
case "com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource":
|
||||
pipeline.BitbucketServerSource = getBitbucketServerSourceFromEtree(source)
|
||||
pipeline.SourceType = "bitbucket_server"
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeBitbucket
|
||||
case "io.jenkins.plugins.gitlabbranchsource.GitLabSCMSource":
|
||||
pipeline.GitlabSource = internal.GetGitlabSourceFromEtree(source)
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeGitlab
|
||||
|
||||
case "jenkins.plugins.git.GitSCMSource":
|
||||
pipeline.SourceType = "git"
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeGit
|
||||
pipeline.GitSource = getGitSourcefromEtree(source)
|
||||
|
||||
case "jenkins.scm.impl.SingleSCMSource":
|
||||
pipeline.SourceType = "single_svn"
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeSingleSVN
|
||||
pipeline.SingleSvnSource = getSingleSvnSourceFromEtree(source)
|
||||
|
||||
case "jenkins.scm.impl.subversion.SubversionSCMSource":
|
||||
pipeline.SourceType = "svn"
|
||||
pipeline.SourceType = devopsv1alpha3.SourceTypeSVN
|
||||
pipeline.SvnSource = getSvnSourcefromEtree(source)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +250,13 @@ func Test_MultiBranchPipelineConfig(t *testing.T) {
|
||||
SourceType: "svn",
|
||||
SvnSource: &devopsv1alpha3.SvnSource{},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{},
|
||||
},
|
||||
}
|
||||
for _, input := range inputs {
|
||||
outputString, err := createMultiBranchPipelineConfigXml("", input)
|
||||
@@ -365,6 +372,73 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
TimerTrigger: &devopsv1alpha3.TimerTrigger{
|
||||
Interval: "12345566",
|
||||
},
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{
|
||||
Owner: "kubesphere",
|
||||
Repo: "devops",
|
||||
CredentialId: "gitlab",
|
||||
ServerName: "default-gitlab",
|
||||
DiscoverBranches: 1,
|
||||
DiscoverPRFromOrigin: 2,
|
||||
DiscoverTags: true,
|
||||
DiscoverPRFromForks: &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: 1,
|
||||
Trust: 1,
|
||||
},
|
||||
CloneOption: &devopsv1alpha3.GitCloneOption{
|
||||
Timeout: 10,
|
||||
Depth: 10,
|
||||
},
|
||||
RegexFilter: "*-dev",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{
|
||||
DiscoverPRFromForks: &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: 1,
|
||||
Trust: 2,
|
||||
},
|
||||
//CloneOption: &devopsv1alpha3.GitCloneOption{
|
||||
// Depth: -1,
|
||||
// Timeout: -1,
|
||||
//},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{
|
||||
DiscoverPRFromForks: &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: 1,
|
||||
Trust: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{
|
||||
DiscoverPRFromForks: &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: 1,
|
||||
Trust: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
@@ -428,7 +502,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
t.Fatalf("should not get error %+v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(input, output) {
|
||||
t.Fatalf("input [%+v] output [%+v] should equal ", input, output)
|
||||
t.Fatalf("\ninput [%+v] \noutput [%+v] \nshould equal ", input.GitlabSource.CloneOption, output.GitlabSource.CloneOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -475,6 +549,22 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "gitlab",
|
||||
GitlabSource: &devopsv1alpha3.GitlabSource{
|
||||
DiscoverPRFromForks: &devopsv1alpha3.DiscoverPRFromForks{
|
||||
Strategy: 1,
|
||||
Trust: 1,
|
||||
},
|
||||
CloneOption: &devopsv1alpha3.GitCloneOption{
|
||||
Depth: -1,
|
||||
Timeout: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, input := range inputs {
|
||||
@@ -487,8 +577,19 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("should not get error %+v", err)
|
||||
}
|
||||
|
||||
// we'll give it a default value if it's negative
|
||||
if input.GitlabSource != nil && input.GitlabSource.CloneOption != nil {
|
||||
if input.GitlabSource.CloneOption.Timeout < 0 {
|
||||
input.GitlabSource.CloneOption.Timeout = 10
|
||||
}
|
||||
if input.GitlabSource.CloneOption.Depth < 0 {
|
||||
input.GitlabSource.CloneOption.Depth = 1
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(input, output) {
|
||||
t.Fatalf("input [%+v] output [%+v] should equal ", input, output)
|
||||
t.Fatalf("input [%+v] output [%+v] should equal ", input.GitlabSource, output.GitlabSource)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user