Skip to content

Commit

Permalink
Support trigger a parameterized Pipeline in PipelineRun reconciler (#210
Browse files Browse the repository at this point in the history
)

* Make parameters in PipelineRunSpec available

* Bump version of jenkins-zh/jenkins-client

* Drop `= nil` from declaration of var params
  • Loading branch information
JohnNiang authored Sep 2, 2021
1 parent 304af63 commit db19554
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 10 deletions.
75 changes: 75 additions & 0 deletions config/samples/devops_v1alpha4_pipelinerun_with_parameters.yaml
Original file line number Diff line number Diff line change
@@ -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"
13 changes: 8 additions & 5 deletions controllers/jenkins/pipelinerun/pipelinerun_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand Down
20 changes: 18 additions & 2 deletions controllers/jenkins/pipelinerun/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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
for _, param := range converter.parameters {
params = append(params, job.Parameter{
Name: param.Name,
Value: param.Value,
})
}
return params
}
51 changes: 51 additions & 0 deletions controllers/jenkins/pipelinerun/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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)
}
})
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.20210830140903-1ae131e1f28b
github.com/kubesphere/sonargo v0.0.2
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.15.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +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.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=
Expand Down

0 comments on commit db19554

Please sign in to comment.