Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions review_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,28 @@ func findAndPlayJob(
jobName string,
jobVars []*gitlab.JobVariableOptions,
) (*gitlab.Job, error) {
// Find the latest pipeline for this ref
// Find the latest pipeline for this ref. Duplicate-triggered pipelines
// end up skipped or canceled, so fetch a small page and pick the newest
// pipeline that actually ran (the API has no negative status filter).
pipelines, err := client.ListProjectPipelines(projectPath, &gitlab.ListProjectPipelinesOptions{
Ref: &ref,
ListOptions: gitlab.ListOptions{
PerPage: 1,
PerPage: 5,
},
})
if err != nil {
return nil, fmt.Errorf("failed to list pipelines for ref %s: %w", ref, err)
}
if len(pipelines) == 0 {
return nil, fmt.Errorf("no pipelines found for ref %s in project %s", ref, projectPath)
var latestPipeline *gitlab.PipelineInfo
for _, pipeline := range pipelines {
if pipeline.Status != string(gitlab.Skipped) && pipeline.Status != string(gitlab.Canceled) {
latestPipeline = pipeline
break
}
}
if latestPipeline == nil {
return nil, fmt.Errorf("no eligible (non-skipped) pipelines found")
}
latestPipeline := pipelines[0]
log.Infof(
"Found latest pipeline %d for ref %s in project %s",
latestPipeline.ID,
Expand Down
34 changes: 32 additions & 2 deletions review_pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,17 @@ func TestFindAndPlayJob(t *testing.T) {
c.On("ListProjectPipelines", projectPath, mock.Anything).
Return([]*gitlab.PipelineInfo{}, nil)
},
expectedErr: "no pipelines found for ref pr_42 in project Northern.tech/Mender/mender-server",
expectedErr: "no eligible (non-skipped) pipelines found",
},
"all pipelines skipped or canceled": {
setupMock: func(c *gitlabmocks.Client) {
c.On("ListProjectPipelines", projectPath, mock.Anything).
Return([]*gitlab.PipelineInfo{
{ID: 102, Status: "skipped"},
{ID: 101, Status: "canceled"},
}, nil)
},
expectedErr: "no eligible (non-skipped) pipelines found",
},
"job not found": {
setupMock: func(c *gitlabmocks.Client) {
Expand Down Expand Up @@ -147,6 +157,26 @@ func TestFindAndPlayJob(t *testing.T) {
},
expectedErr: `failed to play job "review:deploy" (ID: 5): play error`,
},
"skipped duplicate pipeline is bypassed": {
setupMock: func(c *gitlabmocks.Client) {
c.On("ListProjectPipelines", projectPath, mock.Anything).
Return([]*gitlab.PipelineInfo{
{ID: 101, Status: "skipped"},
{ID: 100, Status: "success"},
}, nil)
c.On("ListPipelineJobs", projectPath, int64(100), mock.Anything).
Return([]*gitlab.Job{
{ID: 5, Name: "review:deploy", Status: "manual"},
}, nil)
c.On("PlayJob", projectPath, int64(5), mock.Anything).
Return(&gitlab.Job{
ID: 5,
Name: "review:deploy",
Status: "pending",
WebURL: "https://gitlab.com/job/5",
}, nil)
},
},
"happy path": {
setupMock: func(c *gitlabmocks.Client) {
c.On("ListProjectPipelines", projectPath, mock.Anything).
Expand Down Expand Up @@ -281,7 +311,7 @@ func TestTriggerReviewDeployWithClient(t *testing.T) {
Return([]*gitlab.PipelineInfo{}, nil)
},
setupGH: func(c *githubmocks.Client) {},
errContain: "no pipelines found",
errContain: "no eligible (non-skipped) pipelines found",
},
}

Expand Down