From 3c4fd8ec2bead3c7c52ddde6f6b81677bed6df7c Mon Sep 17 00:00:00 2001 From: johnniang Date: Mon, 30 Aug 2021 17:10:27 +0800 Subject: [PATCH 1/3] Make parameters in PipelineRunSpec available --- ..._v1alpha4_pipelinerun_with_parameters.yaml | 75 +++++++++++++++++++ .../pipelinerun/pipelinerun_controller.go | 13 ++-- controllers/jenkins/pipelinerun/utils.go | 20 ++++- controllers/jenkins/pipelinerun/utils_test.go | 51 +++++++++++++ go.mod | 3 +- go.sum | 2 + 6 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 config/samples/devops_v1alpha4_pipelinerun_with_parameters.yaml diff --git a/config/samples/devops_v1alpha4_pipelinerun_with_parameters.yaml b/config/samples/devops_v1alpha4_pipelinerun_with_parameters.yaml new file mode 100644 index 00000000..730cbc7c --- /dev/null +++ b/config/samples/devops_v1alpha4_pipelinerun_with_parameters.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: devops.kubesphere.io/v1alpha3 +kind: DevOpsProject +metadata: + annotations: + kubesphere.io/creator: admin + name: demo-devopsproject +status: + adminNamespace: default +--- +apiVersion: devops.kubesphere.io/v1alpha3 +kind: Pipeline +metadata: + annotations: + kubesphere.io/creator: admin + name: demo-pipeline + namespace: default +spec: + pipeline: + disable_concurrent: true + discarder: + days_to_keep: "7" + num_to_keep: "10" + jenkinsfile: | + pipeline { + agent any + + parameters { + string defaultValue: 'rick', description: 'just for testing', name: 'name', trim: true + booleanParam defaultValue: false, description: 'You can use this flag to debug your Pipeline', name: 'debug' + choice choices: ['v1.18.8', 'v1.18.9'], description: 'Please choose the target Kubernetes version', name: 'kubernetesVersion' + } + + stages{ + stage('simple'){ + steps{ + echo "My name is ${params.name}." + echo "Target Kubernetes version is " + params.kubernetesVersion + + script { + if ("${params.debug}" == "true") { + echo "You can put some debug info at here." + echo "Another way to use param: " + params.name + } + } + } + } + + stage('debug stage') { + when { + equals expected: true, actual: params.debug + } + steps { + echo "It's joke, there're debug info here." + } + } + } + } + name: good + type: pipeline + +--- +apiVersion: devops.kubesphere.io/v1alpha4 +kind: PipelineRun +metadata: + name: demo-pipelinerun + namespace: default +spec: + pipelineRef: + name: demo-pipeline + parameters: + - name: "debug" + value: "true" + - name: "name" + value: "devops" diff --git a/controllers/jenkins/pipelinerun/pipelinerun_controller.go b/controllers/jenkins/pipelinerun/pipelinerun_controller.go index 8a7ce492..492dc425 100644 --- a/controllers/jenkins/pipelinerun/pipelinerun_controller.go +++ b/controllers/jenkins/pipelinerun/pipelinerun_controller.go @@ -127,7 +127,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { } // first run - pipelineBuild, err := r.triggerJenkinsJob(devopsProjectName, pipelineName) + pipelineBuild, err := r.triggerJenkinsJob(devopsProjectName, pipelineName, &pr.Spec) if err != nil { log.Error(err, "unable to run pipeline", "devopsProjectName", devopsProjectName, "pipeline", pipeline.Name) return ctrl.Result{}, err @@ -165,9 +165,12 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { return ctrl.Result{RequeueAfter: 1 * time.Second}, nil } -func (r *Reconciler) triggerJenkinsJob(projectName, pipelineName string) (*job.PipelineBuild, error) { - boClient := job.BlueOceanClient{JenkinsCore: r.JenkinsCore, Organization: ""} - return boClient.Build("jenkins", projectName, pipelineName) +func (r *Reconciler) triggerJenkinsJob(devopsProjectName, pipelineName string, prSpec *devopsv1alpha4.PipelineRunSpec) (*job.PipelineBuild, error) { + boClient := job.BlueOceanClient{JenkinsCore: r.JenkinsCore, Organization: "jenkins"} + return boClient.Build(job.BuildOption{ + Pipelines: []string{devopsProjectName, pipelineName}, + Parameters: parameterConverter{parameters: prSpec.Parameters}.convert(), + }) } func (r *Reconciler) getPipelineRunResult(projectName, pipelineName string, pr *devopsv1alpha4.PipelineRun) (*job.PipelineBuild, error) { @@ -176,7 +179,7 @@ func (r *Reconciler) getPipelineRunResult(projectName, pipelineName string, pr * return nil, fmt.Errorf("unable to get PipelineRun result due to not found run ID") } boClient := job.BlueOceanClient{JenkinsCore: r.JenkinsCore, Organization: "jenkins"} - return boClient.GetBuild("jenkins", runIDStr, projectName, pipelineName) + return boClient.GetBuild(runIDStr, projectName, pipelineName) } func (r *Reconciler) updateLabelsAndAnnotations(ctx context.Context, pr *devopsv1alpha4.PipelineRun) error { diff --git a/controllers/jenkins/pipelinerun/utils.go b/controllers/jenkins/pipelinerun/utils.go index e3f17488..3d5a3d62 100644 --- a/controllers/jenkins/pipelinerun/utils.go +++ b/controllers/jenkins/pipelinerun/utils.go @@ -42,7 +42,7 @@ type pipelineBuildApplier struct { *job.PipelineBuild } -func (pbApplier *pipelineBuildApplier) apply(prStatus *devopsv1alpha4.PipelineRunStatus) { +func (pbApplier pipelineBuildApplier) apply(prStatus *devopsv1alpha4.PipelineRunStatus) { condition := devopsv1alpha4.Condition{ Type: devopsv1alpha4.ConditionReady, Status: devopsv1alpha4.ConditionUnknown, @@ -76,7 +76,7 @@ func (pbApplier *pipelineBuildApplier) apply(prStatus *devopsv1alpha4.PipelineRu prStatus.UpdateTime = &v1.Time{Time: time.Now()} } -func (pbApplier *pipelineBuildApplier) whenPipelineRunFinished(condition *devopsv1alpha4.Condition, prStatus *devopsv1alpha4.PipelineRunStatus) { +func (pbApplier pipelineBuildApplier) whenPipelineRunFinished(condition *devopsv1alpha4.Condition, prStatus *devopsv1alpha4.PipelineRunStatus) { // mark as completed if !pbApplier.EndTime.IsZero() { prStatus.CompletionTime = &v1.Time{Time: pbApplier.EndTime.Time} @@ -107,3 +107,19 @@ func (pbApplier *pipelineBuildApplier) whenPipelineRunFinished(condition *devops prStatus.Phase = devopsv1alpha4.Failed } } + +// parameterConverter is responsible to convert Parameter slice of PipelineRun into job.Parameter slice. +type parameterConverter struct { + parameters []devopsv1alpha4.Parameter +} + +func (converter parameterConverter) convert() []job.Parameter { + var params []job.Parameter = nil + for _, param := range converter.parameters { + params = append(params, job.Parameter{ + Name: param.Name, + Value: param.Value, + }) + } + return params +} diff --git a/controllers/jenkins/pipelinerun/utils_test.go b/controllers/jenkins/pipelinerun/utils_test.go index 7b653e24..c28b4c4b 100644 --- a/controllers/jenkins/pipelinerun/utils_test.go +++ b/controllers/jenkins/pipelinerun/utils_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" devopsv1alpha4 "kubesphere.io/devops/pkg/api/devops/v1alpha4" + "reflect" "testing" "time" ) @@ -280,3 +281,53 @@ func Test_pipelineBuildApplier_apply(t *testing.T) { }) } } + +func Test_parameterConverter_convert(t *testing.T) { + type fields struct { + parameters []devopsv1alpha4.Parameter + } + tests := []struct { + name string + fields fields + want []job.Parameter + }{{ + name: "Nil parameters", + fields: fields{ + parameters: nil, + }, + want: nil, + }, { + name: "Single parameter", + fields: fields{ + parameters: []devopsv1alpha4.Parameter{ + {Name: "fake_name", Value: "fake_value"}, + }, + }, + want: []job.Parameter{ + {Name: "fake_name", Value: "fake_value"}, + }, + }, { + name: "Two parameters", + fields: fields{ + parameters: []devopsv1alpha4.Parameter{ + {Name: "fake_name_1", Value: "fake_value_1"}, + {Name: "fake_name_2", Value: "fake_value_2"}, + }, + }, + want: []job.Parameter{ + {Name: "fake_name_1", Value: "fake_value_1"}, + {Name: "fake_name_2", Value: "fake_value_2"}, + }, + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + converter := parameterConverter{ + parameters: tt.fields.parameters, + } + if got := converter.convert(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("convert() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index 5a88763f..49a82c3b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.5 github.com/google/go-querystring v1.1.0 // indirect - github.com/jenkins-zh/jenkins-client v0.0.2 + github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22 github.com/kubesphere/sonargo v0.0.2 github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.15.0 @@ -65,4 +65,5 @@ replace ( k8s.io/component-base => k8s.io/component-base v0.18.6 k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 sigs.k8s.io/application => sigs.k8s.io/application v0.8.4-0.20201016185654-c8e2959e57a0 + github.com/jenkins-zh/jenkins-client => /home/johnniang/workspace/jenkins/jenkins-client ) diff --git a/go.sum b/go.sum index 7ec3724a..a27551b5 100644 --- a/go.sum +++ b/go.sum @@ -387,6 +387,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i github.com/jenkins-zh/jenkins-cli v0.0.32/go.mod h1:uE1mH9PNITrg0sugv6HXuM/CSddg0zxXoYu3w57I3JY= github.com/jenkins-zh/jenkins-client v0.0.2 h1:x4yHjGIkJ51n62Qybr6mz4wXWocb59UWDqRGpRJXO1A= github.com/jenkins-zh/jenkins-client v0.0.2/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU= +github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22 h1:4Nuu6zx0c9zx3O6t0V+SS6OiwfuHDEcNCOACvAekHQc= +github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU= github.com/jenkins-zh/jenkins-formulas v0.0.5/go.mod h1:zS8fm8u5L6FcjZM0QznXsLV9T2UtSVK+hT6Sm76iUZ4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= From b7d7836808d2d72e4b4c337394d1face609cbfbe Mon Sep 17 00:00:00 2001 From: johnniang Date: Tue, 31 Aug 2021 10:30:58 +0800 Subject: [PATCH 2/3] Bump version of jenkins-zh/jenkins-client --- go.mod | 3 +-- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 49a82c3b..89ea74d7 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.5 github.com/google/go-querystring v1.1.0 // indirect - github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22 + github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830140903-1ae131e1f28b github.com/kubesphere/sonargo v0.0.2 github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.15.0 @@ -65,5 +65,4 @@ replace ( k8s.io/component-base => k8s.io/component-base v0.18.6 k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 sigs.k8s.io/application => sigs.k8s.io/application v0.8.4-0.20201016185654-c8e2959e57a0 - github.com/jenkins-zh/jenkins-client => /home/johnniang/workspace/jenkins/jenkins-client ) diff --git a/go.sum b/go.sum index a27551b5..02415aea 100644 --- a/go.sum +++ b/go.sum @@ -385,10 +385,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jenkins-zh/jenkins-cli v0.0.32/go.mod h1:uE1mH9PNITrg0sugv6HXuM/CSddg0zxXoYu3w57I3JY= -github.com/jenkins-zh/jenkins-client v0.0.2 h1:x4yHjGIkJ51n62Qybr6mz4wXWocb59UWDqRGpRJXO1A= -github.com/jenkins-zh/jenkins-client v0.0.2/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU= -github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22 h1:4Nuu6zx0c9zx3O6t0V+SS6OiwfuHDEcNCOACvAekHQc= -github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830015934-b0d674f61d22/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU= +github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830140903-1ae131e1f28b h1:+5d4wUkSGy/Ql5/ZBDAPjXA+Aab39V3nvw5Ec6TCHx8= +github.com/jenkins-zh/jenkins-client v0.0.3-0.20210830140903-1ae131e1f28b/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU= github.com/jenkins-zh/jenkins-formulas v0.0.5/go.mod h1:zS8fm8u5L6FcjZM0QznXsLV9T2UtSVK+hT6Sm76iUZ4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= From 81ac8f824c070f1530978636a3bcc0f7c9f7e3f9 Mon Sep 17 00:00:00 2001 From: johnniang Date: Tue, 31 Aug 2021 10:35:08 +0800 Subject: [PATCH 3/3] Drop `= nil` from declaration of var params --- controllers/jenkins/pipelinerun/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/jenkins/pipelinerun/utils.go b/controllers/jenkins/pipelinerun/utils.go index 3d5a3d62..d459050b 100644 --- a/controllers/jenkins/pipelinerun/utils.go +++ b/controllers/jenkins/pipelinerun/utils.go @@ -114,7 +114,7 @@ type parameterConverter struct { } func (converter parameterConverter) convert() []job.Parameter { - var params []job.Parameter = nil + var params []job.Parameter for _, param := range converter.parameters { params = append(params, job.Parameter{ Name: param.Name,