From 8f5c07432f656706c4a9da8106ceeec953d104c5 Mon Sep 17 00:00:00 2001 From: Sergey Smolnikov Date: Tue, 27 May 2025 10:32:41 +0200 Subject: [PATCH] 147-distinguish-tags-from-branches-when-triggering-builds (#108) * Changed go version. Using Git refs type * Fixed unit-test * Renamed the property GitEventRefsType to GitRefsType * Using GitRef instead of Branch * Added correctly GitRef and GitRefType to job params * Upgraded linter version --- .github/workflows/pr.yaml | 2 +- Dockerfile | 10 ++++++---- Makefile | 6 +++++- go.mod | 4 ++-- handler/webhook_handler.go | 33 ++++++++++++++++++++++----------- handler/webhook_handler_test.go | 29 +++++++++++++++++++---------- metrics/custom_metrics.go | 27 ++++++++++++++------------- models/job_summary.go | 31 ++++++++++++++++++++++++++++++- models/pipeline_parameters.go | 16 ++++++++++++++++ radix/api_server.go | 2 +- radix/api_server_mock.go | 8 ++++---- radix/api_server_stub.go | 4 ++-- 12 files changed, 122 insertions(+), 50 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 477b83a..30aaf82 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -27,7 +27,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.60.3 + version: v1.64.3 test: name: Unit Test diff --git a/Dockerfile b/Dockerfile index eba5f00..aef3d3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,14 @@ -# Build stage -FROM docker.io/golang:1.22-alpine3.20 as builder +FROM --platform=$BUILDPLATFORM docker.io/golang:1.24.2-alpine3.21 AS builder +ARG TARGETARCH ENV CGO_ENABLED=0 \ - GOOS=linux + GOOS=linux \ + GOARCH=${TARGETARCH} + WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN go build -ldflags "-s -w" -o /build/radix-github-webhook +RUN go build -ldflags="-s -w" -o /build/radix-github-webhook # Final stage, ref https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md for distroless FROM gcr.io/distroless/static diff --git a/Makefile b/Makefile index 7b8e6a6..36693ac 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,12 @@ docker-build: $(addsuffix -image,$(IMAGES)) docker-push: $(addsuffix -push,$(IMAGES)) %-push: + az acr login --name $(DOCKER_REGISTRY) docker push $(DOCKER_REGISTRY)/$*:$(IMAGE_TAG) +.PHONY: deploy +deploy: docker-build docker-push + .PHONY: mocks mocks: bootstrap mockgen -source ./radix/api_server.go -destination ./radix/api_server_mock.go -package radix @@ -55,7 +59,7 @@ HAS_MOCKGEN := $(shell command -v mockgen;) .PHONY: bootstrap bootstrap: ifndef HAS_GOLANGCI_LINT - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.58.2 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v1.64.3 endif ifndef HAS_MOCKGEN go install github.com/golang/mock/mockgen@v1.6.0 diff --git a/go.mod b/go.mod index 5d1d59e..41e6e91 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/equinor/radix-github-webhook -go 1.22.0 +go 1.24.0 -toolchain go1.23.0 +toolchain go1.24.2 require ( github.com/equinor/radix-common v1.9.7 diff --git a/handler/webhook_handler.go b/handler/webhook_handler.go index 91f5a47..009fe21 100644 --- a/handler/webhook_handler.go +++ b/handler/webhook_handler.go @@ -42,8 +42,8 @@ var ( createPipelineJobErrorMessage = func(appName string, apiError error) string { return fmt.Sprintf("Failed to create pipeline job for Radix application %s. ApiError was: %s", appName, apiError) } - createPipelineJobSuccessMessage = func(jobName, appName, branch, commitID string) string { - return fmt.Sprintf("Pipeline job %s created for Radix application %s on branch %s for commit %s", jobName, appName, branch, commitID) + createPipelineJobSuccessMessage = func(jobName, appName, gitRefs, gitRefsType, commitID string) string { + return fmt.Sprintf("Pipeline job %s created for Radix application %s on %s %s for commit %s", jobName, appName, gitRefsType, gitRefs, commitID) } ) @@ -116,12 +116,12 @@ func (wh *webhookHandler) HandleFunc(c *gin.Context) { switch e := payload.(type) { case *github.PushEvent: - branch := getBranch(e) + gitRef, gitRefType := getGitRefWithType(e) commitID := getCommitID(e) sshURL := e.Repo.GetSSHURL() triggeredBy := getPushTriggeredBy(e) - metrics.IncreasePushGithubEventTypeCounter(sshURL, branch, commitID) + metrics.IncreasePushGithubEventTypeCounter(sshURL, gitRef, gitRefType, commitID) if isPushEventForRefDeletion(e) { writeSuccessResponse(http.StatusAccepted, refDeletionPushEventUnsupportedMessage(*e.Ref)) @@ -135,19 +135,19 @@ func (wh *webhookHandler) HandleFunc(c *gin.Context) { return } - metrics.IncreasePushGithubEventTypeTriggerPipelineCounter(sshURL, branch, commitID, applicationSummary.Name) - jobSummary, err := wh.apiServer.TriggerPipeline(c.Request.Context(), applicationSummary.Name, branch, commitID, triggeredBy) + metrics.IncreasePushGithubEventTypeTriggerPipelineCounter(sshURL, gitRef, gitRefType, commitID, applicationSummary.Name) + jobSummary, err := wh.apiServer.TriggerPipeline(c.Request.Context(), applicationSummary.Name, gitRef, gitRefType, commitID, triggeredBy) if err != nil { if e, ok := err.(*radix.ApiError); ok && e.Code == 400 { writeSuccessResponse(http.StatusAccepted, createPipelineJobErrorMessage(applicationSummary.Name, err)) return } - metrics.IncreasePushGithubEventTypeFailedTriggerPipelineCounter(sshURL, branch, commitID) + metrics.IncreasePushGithubEventTypeFailedTriggerPipelineCounter(sshURL, gitRef, gitRefType, commitID) writeErrorResponse(http.StatusBadRequest, errors.New(createPipelineJobErrorMessage(applicationSummary.Name, err))) return } - writeSuccessResponse(http.StatusOK, createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.Branch, jobSummary.CommitID)) + writeSuccessResponse(http.StatusOK, createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.GetGitRefOrDefault(), jobSummary.GetGitRefTypeOrDefault(), jobSummary.CommitID)) case *github.PingEvent: // sshURL := getSSHUrlFromPingURL(*e.Hook.URL) @@ -170,6 +170,16 @@ func (wh *webhookHandler) HandleFunc(c *gin.Context) { } } +func getApiGitRefType(gitRefsType string) string { + switch gitRefsType { + case "heads": + return "branch" + case "tags": + return "tag" + } + return "" +} + func getCommitID(e *github.PushEvent) string { if e.Ref != nil && strings.HasPrefix(*e.Ref, "refs/tags/") && e.BaseRef == nil { // The property After has not an existing commit-ID, but other object ID @@ -254,10 +264,11 @@ func getPushTriggeredBy(pushEvent *github.PushEvent) string { return "" } -func getBranch(pushEvent *github.PushEvent) string { - // Remove refs/heads from ref +func getGitRefWithType(pushEvent *github.PushEvent) (string, string) { ref := strings.Split(*pushEvent.Ref, "/") - return strings.Join(ref[2:], "/") + gitRef := strings.Join(ref[2:], "/") // Remove refs/heads from ref + gitRefType := ref[1] + return gitRef, getApiGitRefType(gitRefType) } func isPushEventForRefDeletion(pushEvent *github.PushEvent) bool { diff --git a/handler/webhook_handler_test.go b/handler/webhook_handler_test.go index d3d9bc0..bc197ae 100644 --- a/handler/webhook_handler_test.go +++ b/handler/webhook_handler_test.go @@ -301,7 +301,7 @@ func (s *handlerTestSuite) Test_PushEventUnmatchedRepo() { Times(1) jobSummary := models.JobSummary{Name: "jobname", AppName: expectAppDetail.appName, Branch: "master", CommitID: commitID, TriggeredBy: ""} s.apiServer.EXPECT(). - TriggerPipeline(gomock.Any(), expectAppDetail.appName, "master", commitID, ""). + TriggerPipeline(gomock.Any(), expectAppDetail.appName, "master", "branch", commitID, ""). Return(&jobSummary, nil). Times(1) } @@ -457,7 +457,7 @@ func (s *handlerTestSuite) Test_PushEventTriggerPipelineReturnsError() { s.apiServer.EXPECT().ShowApplications(gomock.Any(), "git@github.com:equinor/repo-4.git").Return([]*models.ApplicationSummary{&appSummary}, nil).Times(1) s.apiServer.EXPECT().GetApplication(gomock.Any(), appName).Return(appDetail, nil).Times(1) - s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, "master", commitID, "").Return(nil, scenario.apiError).Times(1) + s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, "master", "branch", commitID, "").Return(nil, scenario.apiError).Times(1) sut := NewWebHookHandler(s.apiServer) req, _ := http.NewRequest("POST", "/", bytes.NewReader(payload)) @@ -490,7 +490,7 @@ func (s *handlerTestSuite) Test_PushEventCorrectSecret() { jobSummary := models.JobSummary{Name: "jobname", AppName: "jobappname", Branch: "jobbranchname", CommitID: "jobcommitID", TriggeredBy: "anyuser"} s.apiServer.EXPECT().ShowApplications(gomock.Any(), "git@github.com:equinor/repo-4.git").Return([]*models.ApplicationSummary{&appSummary}, nil).Times(1) s.apiServer.EXPECT().GetApplication(gomock.Any(), appName).Return(appDetail, nil).Times(1) - s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, "master", commitID, "").Return(&jobSummary, nil).Times(1) + s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, "master", "branch", commitID, "").Return(&jobSummary, nil).Times(1) sut := NewWebHookHandler(s.apiServer) req, _ := http.NewRequest("POST", "/", bytes.NewReader(payload)) @@ -502,7 +502,7 @@ func (s *handlerTestSuite) Test_PushEventCorrectSecret() { var res response err := json.Unmarshal(s.w.Body.Bytes(), &res) require.NoError(s.T(), err) - s.Equal(createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.Branch, jobSummary.CommitID), res.Message) + s.Equal(createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.Branch, "branch", jobSummary.CommitID), res.Message) s.ctrl.Finish() } @@ -528,9 +528,18 @@ func (s *handlerTestSuite) Test_PushEventWithRefDeleted() { } func Test_GetBranch_RemovesRefsHead(t *testing.T) { - assert.Equal(t, "master", getBranch(&github.PushEvent{Ref: strPtr("refs/heads/master")})) - assert.Equal(t, "feature/RA-326-TestBranch", getBranch(&github.PushEvent{Ref: strPtr("refs/heads/feature/RA-326-TestBranch")})) - assert.Equal(t, "hotfix/api/refs/heads/fix1", getBranch(&github.PushEvent{Ref: strPtr("refs/heads/hotfix/api/refs/heads/fix1")})) + gitRef, gitRefType := getGitRefWithType(&github.PushEvent{Ref: strPtr("refs/tags/v1.0.2")}) + assert.Equal(t, "v1.0.2", gitRef) + assert.Equal(t, "tag", gitRefType) + gitRef, gitRefType = getGitRefWithType(&github.PushEvent{Ref: strPtr("refs/heads/master")}) + assert.Equal(t, "master", gitRef) + assert.Equal(t, "branch", gitRefType) + gitRef, gitRefType = getGitRefWithType(&github.PushEvent{Ref: strPtr("refs/heads/feature/RA-326-TestBranch")}) + assert.Equal(t, "feature/RA-326-TestBranch", gitRef) + assert.Equal(t, "branch", gitRefType) + gitRef, gitRefType = getGitRefWithType(&github.PushEvent{Ref: strPtr("refs/heads/hotfix/api/refs/heads/fix1")}) + assert.Equal(t, "hotfix/api/refs/heads/fix1", gitRef) + assert.Equal(t, "branch", gitRefType) } func (s *handlerTestSuite) Test_PushEventWithAnnotatedTag() { @@ -550,7 +559,7 @@ func (s *handlerTestSuite) Test_PushEventWithAnnotatedTag() { jobSummary := models.JobSummary{Name: "jobname", AppName: "jobappname", Branch: "jobbranchname", CommitID: headCommitID, TriggeredBy: "anyuser"} s.apiServer.EXPECT().ShowApplications(gomock.Any(), "git@github.com:equinor/repo-1.git").Return([]*models.ApplicationSummary{&appSummary}, nil).Times(1) s.apiServer.EXPECT().GetApplication(gomock.Any(), appName).Return(appDetail, nil).Times(1) - s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, tag, headCommitID, "").Return(&jobSummary, nil).Times(1) + s.apiServer.EXPECT().TriggerPipeline(gomock.Any(), appName, tag, "tag", headCommitID, "").Return(&jobSummary, nil).Times(1) sut := NewWebHookHandler(s.apiServer) req, _ := http.NewRequest("POST", "/", bytes.NewReader(payload)) @@ -562,7 +571,7 @@ func (s *handlerTestSuite) Test_PushEventWithAnnotatedTag() { var res response err := json.Unmarshal(s.w.Body.Bytes(), &res) require.NoError(s.T(), err) - s.Equal(createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.Branch, jobSummary.CommitID), res.Message) + s.Equal(createPipelineJobSuccessMessage(jobSummary.Name, jobSummary.AppName, jobSummary.Branch, "branch", jobSummary.CommitID), res.Message) s.ctrl.Finish() } @@ -571,7 +580,7 @@ type response struct { Error string `json:"error"` } -// GitHubPayloadBuilder Handles construction of github payload +// GitHubPayloadBuilder Handles construction of GitHub payload type GitHubPayloadBuilder interface { withRef(refs string) GitHubPayloadBuilder withAfter(after string) GitHubPayloadBuilder diff --git a/metrics/custom_metrics.go b/metrics/custom_metrics.go index 71d9f16..bad8dc7 100644 --- a/metrics/custom_metrics.go +++ b/metrics/custom_metrics.go @@ -5,10 +5,11 @@ import ( ) const ( - sshURLLabel = "radix_webhook_request_ssh_url" - branchLabel = "radix_webhook_request_branch" - commitIDLabel = "radix_webhook_request_commit_id" - appNameLabel = "radix_webhook_request_app_name" + sshURLLabel = "radix_webhook_request_ssh_url" + gitRefsLabel = "radix_webhook_request_branch" + gitRefsTypeLabel = "radix_webhook_request_refs_type" + commitIDLabel = "radix_webhook_request_commit_id" + appNameLabel = "radix_webhook_request_app_name" ) var ( @@ -55,21 +56,21 @@ var ( Name: "radix_webhook_request_push_github_event_type_counter", Help: "Counter for push GitHub event type requests", }, - []string{sshURLLabel, branchLabel, commitIDLabel}, + []string{sshURLLabel, gitRefsLabel, gitRefsTypeLabel, commitIDLabel}, ) pushEventTypeTriggerPipelineCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "radix_webhook_request_push_github_event_type_trigger_pipeline_counter", Help: "Counter for push GitHub event type trigger pipeline requests", }, - []string{sshURLLabel, branchLabel, commitIDLabel, appNameLabel}, + []string{sshURLLabel, gitRefsLabel, gitRefsTypeLabel, commitIDLabel, appNameLabel}, ) pushEventTypeFailedTriggerPipelineCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "radix_webhook_request_push_github_event_type_failed_trigger_pipeline_counter", Help: "Counter for push GitHub event type failed trigger pipeline requests", }, - []string{sshURLLabel, branchLabel, commitIDLabel}, + []string{sshURLLabel, gitRefsLabel, gitRefsTypeLabel, commitIDLabel}, ) ) @@ -116,16 +117,16 @@ func IncreaseFailedCloneURLValidationCounter(sshURL string) { } // IncreasePushGithubEventTypeCounter increases all GitHub push event type request counter -func IncreasePushGithubEventTypeCounter(sshURL, branch, commitID string) { - pushEventTypeCounter.With(prometheus.Labels{sshURLLabel: sshURL, branchLabel: branch, commitIDLabel: commitID}).Inc() +func IncreasePushGithubEventTypeCounter(sshURL, gitRefs, gitRefsType, commitID string) { + pushEventTypeCounter.With(prometheus.Labels{sshURLLabel: sshURL, gitRefsLabel: gitRefs, gitRefsTypeLabel: gitRefsType, commitIDLabel: commitID}).Inc() } // IncreasePushGithubEventTypeTriggerPipelineCounter increases GitHub push event type trigger pipeline request counter -func IncreasePushGithubEventTypeTriggerPipelineCounter(sshURL, branch, commitID, appName string) { - pushEventTypeTriggerPipelineCounter.With(prometheus.Labels{sshURLLabel: sshURL, branchLabel: branch, commitIDLabel: commitID, appNameLabel: appName}).Inc() +func IncreasePushGithubEventTypeTriggerPipelineCounter(sshURL, gitRefs, gitRefsType, commitID, appName string) { + pushEventTypeTriggerPipelineCounter.With(prometheus.Labels{sshURLLabel: sshURL, gitRefsLabel: gitRefs, gitRefsTypeLabel: gitRefsType, commitIDLabel: commitID, appNameLabel: appName}).Inc() } // IncreasePushGithubEventTypeFailedTriggerPipelineCounter increases GitHub push event type failed trigger pipeline request counter -func IncreasePushGithubEventTypeFailedTriggerPipelineCounter(sshURL, branch, commitID string) { - pushEventTypeFailedTriggerPipelineCounter.With(prometheus.Labels{sshURLLabel: sshURL, branchLabel: branch, commitIDLabel: commitID}).Inc() +func IncreasePushGithubEventTypeFailedTriggerPipelineCounter(sshURL, gitRefs, gitRefsType, commitID string) { + pushEventTypeFailedTriggerPipelineCounter.With(prometheus.Labels{sshURLLabel: sshURL, gitRefsLabel: gitRefs, gitRefsTypeLabel: gitRefsType, commitIDLabel: commitID}).Inc() } diff --git a/models/job_summary.go b/models/job_summary.go index c5bfc72..1a1604a 100644 --- a/models/job_summary.go +++ b/models/job_summary.go @@ -8,12 +8,41 @@ type JobSummary struct { // AppName of the application AppName string `json:"appName"` - // Branch branch to build from + // Branch to build from Branch string `json:"branch"` + // GitRef Branch or tag to build from + // + // example: master + GitRef string `json:"gitRef,omitempty"` + + // GitRefType When the pipeline job should be built from branch or tag specified in GitRef: + // - branch + // - tag + // - - either branch or tag + // + // example: "branch" + GitRefType string `json:"gitRefType,omitempty"` + // CommitID the commit ID of the branch to build CommitID string `json:"commitID"` // TriggeredBy of the job TriggeredBy string `json:"triggeredBy"` } + +// GetGitRefOrDefault returns the GitRef if set, otherwise returns the Branch +func (jobSummary JobSummary) GetGitRefOrDefault() string { + if jobSummary.GitRef != "" { + return jobSummary.GitRef + } + return jobSummary.Branch +} + +// GetGitRefTypeOrDefault returns the GitRefType if set, otherwise returns the Branch +func (jobSummary JobSummary) GetGitRefTypeOrDefault() string { + if jobSummary.GitRefType != "" { + return jobSummary.GitRefType + } + return "branch" +} diff --git a/models/pipeline_parameters.go b/models/pipeline_parameters.go index c778353..fad9afe 100644 --- a/models/pipeline_parameters.go +++ b/models/pipeline_parameters.go @@ -19,4 +19,20 @@ type PipelineParameters struct { // required: true // example: 4faca8595c5283a9d0f17a623b9255a0d9866a2e TriggeredBy string `json:"triggeredBy"` + + // GitRef Branch or tag to build from + // + // required: false + // example: master + GitRef string `json:"gitRef,omitempty"` + + // GitRefType When the pipeline job should be built from branch or tag specified in GitRef: + // - branch + // - tag + // - - either branch or tag + // + // required false + // enum: branch,tag,"" + // example: "branch" + GitRefType string `json:"gitRefType,omitempty"` } diff --git a/radix/api_server.go b/radix/api_server.go index aa6ae67..6586404 100644 --- a/radix/api_server.go +++ b/radix/api_server.go @@ -10,5 +10,5 @@ import ( type APIServer interface { ShowApplications(ctx context.Context, sshURL string) ([]*models.ApplicationSummary, error) GetApplication(ctx context.Context, appName string) (*models.Application, error) - TriggerPipeline(ctx context.Context, appName, branch, commitID, triggeredBy string) (*models.JobSummary, error) + TriggerPipeline(ctx context.Context, appName, gitRef, gitRefType, commitID, triggeredBy string) (*models.JobSummary, error) } diff --git a/radix/api_server_mock.go b/radix/api_server_mock.go index 770f068..532d205 100644 --- a/radix/api_server_mock.go +++ b/radix/api_server_mock.go @@ -66,16 +66,16 @@ func (mr *MockAPIServerMockRecorder) ShowApplications(ctx, sshURL interface{}) * } // TriggerPipeline mocks base method. -func (m *MockAPIServer) TriggerPipeline(ctx context.Context, appName, branch, commitID, triggeredBy string) (*models.JobSummary, error) { +func (m *MockAPIServer) TriggerPipeline(ctx context.Context, appName, gitRef, gitRefType, commitID, triggeredBy string) (*models.JobSummary, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TriggerPipeline", ctx, appName, branch, commitID, triggeredBy) + ret := m.ctrl.Call(m, "TriggerPipeline", ctx, appName, gitRef, gitRefType, commitID, triggeredBy) ret0, _ := ret[0].(*models.JobSummary) ret1, _ := ret[1].(error) return ret0, ret1 } // TriggerPipeline indicates an expected call of TriggerPipeline. -func (mr *MockAPIServerMockRecorder) TriggerPipeline(ctx, appName, branch, commitID, triggeredBy interface{}) *gomock.Call { +func (mr *MockAPIServerMockRecorder) TriggerPipeline(ctx, appName, gitRef, gitRefType, commitID, triggeredBy interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerPipeline", reflect.TypeOf((*MockAPIServer)(nil).TriggerPipeline), ctx, appName, branch, commitID, triggeredBy) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerPipeline", reflect.TypeOf((*MockAPIServer)(nil).TriggerPipeline), ctx, appName, gitRef, gitRefType, commitID, triggeredBy) } diff --git a/radix/api_server_stub.go b/radix/api_server_stub.go index 080c331..90feec7 100644 --- a/radix/api_server_stub.go +++ b/radix/api_server_stub.go @@ -65,9 +65,9 @@ func (api *APIServerStub) GetApplication(ctx context.Context, appName string) (* } // TriggerPipeline Implementation -func (api *APIServerStub) TriggerPipeline(ctx context.Context, appName, branch, commitID, triggeredBy string) (*models.JobSummary, error) { +func (api *APIServerStub) TriggerPipeline(ctx context.Context, appName, gitRef, gitRefType, commitID, triggeredBy string) (*models.JobSummary, error) { url := fmt.Sprintf(api.apiServerEndPoint+startPipelineEndPointPattern, appName, buildDeployPipeline) - parameters := models.PipelineParameters{Branch: branch, CommitID: commitID, TriggeredBy: triggeredBy} + parameters := models.PipelineParameters{GitRef: gitRef, GitRefType: gitRefType, CommitID: commitID, TriggeredBy: triggeredBy} body, err := json.Marshal(parameters) if err != nil {