Skip to content

Commit

Permalink
use Gitlab get commit statuses API to get previous pipeline
Browse files Browse the repository at this point in the history
Signed-off-by: Ricky Hariady <[email protected]>
  • Loading branch information
rhariady committed Jan 22, 2025
1 parent 86767f1 commit 9648c1d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 60 deletions.
43 changes: 18 additions & 25 deletions server/events/vcs/gitlab_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,41 +416,34 @@ func (g *GitlabClient) UpdateStatus(logger logging.SimpleLogging, repo models.Re

retries := 1
delay := 2 * time.Second
var commit *gitlab.Commit
var statuses []*gitlab.CommitStatus
var commitStatuses []*gitlab.CommitStatus
var resp *gitlab.Response
var err error

// get the last commit status with the same ref
getCommitStatusesOptions := &gitlab.GetCommitStatusesOptions{
ListOptions: gitlab.ListOptions{
Sort: "desc",
PerPage: 1,
},
Ref: gitlab.Ptr(pull.HeadBranch),
}

// Try a couple of times to get the pipeline ID for the commit
for i := 0; i <= retries; i++ {
commit, resp, err = g.Client.Commits.GetCommit(repo.FullName, pull.HeadCommit, nil)
commitStatuses, resp, err = g.Client.Commits.GetCommitStatuses(repo.FullName, pull.HeadCommit, getCommitStatusesOptions)

if resp != nil {
logger.Debug("GET /projects/%s/repository/commits/%d: %d", pull.BaseRepo.ID(), pull.HeadCommit, resp.StatusCode)
}
if err != nil {
return err
}
if commit.LastPipeline != nil {
if commit.LastPipeline.Ref == pull.HeadBranch {
logger.Info("Pipeline found for commit %s, setting pipeline ID to %d", pull.HeadCommit, commit.LastPipeline.ID)
// Set the pipeline ID to the last pipeline that ran for the commit
setCommitStatusOptions.PipelineID = gitlab.Ptr(commit.LastPipeline.ID)
break
} else {
getCommitStatusesOptions := &gitlab.GetCommitStatusesOptions{
Ref: gitlab.Ptr(pull.HeadBranch),
Sort: gitlab.Ptr("desc"),
PerPage: gitlab.Ptr(1)
}

statuses, resp, err = g.Client.Commits.GetCommitStatus(repo.FullName, pull.HeadCommit, getCommitStatusesOptions)
if len(statuses) > 0 {
logger.Info("Pipeline found for commit %s, setting pipeline ID to %d", pull.HeadCommit, statuses[0].PipelineId)
// Set the pipeline ID to the last pipeline that ran for the commit
setCommitStatusOptions.PipelineID = gitlab.Ptr(statuses[0].PipelineId)
break
}
}
if len(commitStatuses) > 0 {
logger.Info("Pipeline found for commit %s, setting pipeline ID to %d", pull.HeadCommit, commitStatuses[0].PipelineId)
// Set the pipeline ID to the last pipeline that ran for the commit
setCommitStatusOptions.PipelineID = gitlab.Ptr(commitStatuses[0].PipelineId)
break
}
if i != retries {
logger.Info("No pipeline found for commit %s, retrying in %s", pull.HeadCommit, delay)
Expand All @@ -475,7 +468,7 @@ func (g *GitlabClient) UpdateStatus(logger logging.SimpleLogging, repo models.Re
"attempt", i+1,
"max_attempts", maxAttempts,
"repo", repo.FullName,
"commit", commit.ShortID,
"commit", pull.HeadCommit,
"state", state.String(),
)

Expand Down
61 changes: 26 additions & 35 deletions server/events/vcs/gitlab_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,13 @@ type UpdateStatusJsonBody struct {
Ref string `json:"ref"`
}

/* GetCommit response last_pipeline JSON object */
type GetCommitResponseLastPipeline struct {
ID int `json:"id"`
type CommitStatus struct {
Ref string `json:"ref"`
PipelineID int `json:"pipeline_id"`
}

/* GetCommit response JSON object */
type GetCommitResponse struct {
LastPipeline GetCommitResponseLastPipeline `json:"last_pipeline"`
}
/* GetCommitStatuses response JSON object */
type GetCommitStatusesResponse []CommitStatus

/* Empty struct for JSON marshalling */
type EmptyStruct struct{}
Expand Down Expand Up @@ -348,19 +345,19 @@ func TestGitlabClient_UpdateStatus(t *testing.T) {
_, err = w.Write(setStatusJsonResponse)
Ok(t, err)

case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha":
case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha/statuses?per_page=1&ref=test&sort=desc":
w.WriteHeader(http.StatusOK)

getCommitResponse := GetCommitResponse{
LastPipeline: GetCommitResponseLastPipeline{
ID: gitlabPipelineSuccessMrID,
getCommitStatusesResponse := GetCommitStatusesResponse{
CommitStatus{
Ref: updateStatusHeadBranch,
PipelineID: gitlabPipelineSuccessMrID,
},
}
getCommitJsonResponse, err := json.Marshal(getCommitResponse)
getCommitStatusesJsonResponse, err := json.Marshal(getCommitStatusesResponse)
Ok(t, err)

_, err = w.Write(getCommitJsonResponse)
_, err = w.Write(getCommitStatusesJsonResponse)
Ok(t, err)

case "/api/v4/":
Expand Down Expand Up @@ -471,25 +468,25 @@ func TestGitlabClient_UpdateStatusGetCommitRetryable(t *testing.T) {
_, err = w.Write(getCommitJsonResponse)
Ok(t, err)

case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha":
case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha/statuses?per_page=1&ref=test&sort=desc":
handledNumberOfRequests++
noCommitLastPipeline := handledNumberOfRequests <= c.commitsWithNoLastPipeline

w.WriteHeader(http.StatusOK)
if noCommitLastPipeline {
getCommitJsonResponse, err := json.Marshal(EmptyStruct{})
getCommitStatusesJsonResponse, err := json.Marshal([]EmptyStruct{})
Ok(t, err)

_, err = w.Write(getCommitJsonResponse)
_, err = w.Write(getCommitStatusesJsonResponse)
Ok(t, err)
} else {
getCommitResponse := GetCommitResponse{
LastPipeline: GetCommitResponseLastPipeline{
ID: gitlabPipelineSuccessMrID,
getCommitStatusesResponse := GetCommitStatusesResponse{
CommitStatus{
Ref: updateStatusHeadBranch,
PipelineID: gitlabPipelineSuccessMrID,
},
}
getCommitJsonResponse, err := json.Marshal(getCommitResponse)
getCommitJsonResponse, err := json.Marshal(getCommitStatusesResponse)
Ok(t, err)

_, err = w.Write(getCommitJsonResponse)
Expand Down Expand Up @@ -608,19 +605,19 @@ func TestGitlabClient_UpdateStatusSetCommitStatusConflictRetryable(t *testing.T)
_, err = w.Write(getCommitJsonResponse)
Ok(t, err)

case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha":
case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha/statuses?per_page=1&ref=test&sort=desc":
w.WriteHeader(http.StatusOK)

getCommitResponse := GetCommitResponse{
LastPipeline: GetCommitResponseLastPipeline{
ID: gitlabPipelineSuccessMrID,
getCommitStatusesResponse := GetCommitStatusesResponse{
CommitStatus{
Ref: updateStatusHeadBranch,
PipelineID: gitlabPipelineSuccessMrID,
},
}
getCommitJsonResponse, err := json.Marshal(getCommitResponse)
getCommitStatusesJsonResponse, err := json.Marshal(getCommitStatusesResponse)
Ok(t, err)

_, err = w.Write(getCommitJsonResponse)
_, err = w.Write(getCommitStatusesJsonResponse)
Ok(t, err)

case "/api/v4/":
Expand Down Expand Up @@ -721,19 +718,13 @@ func TestGitlabClient_UpdateStatusDifferentRef(t *testing.T) {
_, err = w.Write(setStatusJsonResponse)
Ok(t, err)

case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha":
case "/api/v4/projects/runatlantis%2Fatlantis/repository/commits/sha/statuses?per_page=1&ref=test&sort=desc":
w.WriteHeader(http.StatusOK)

getCommitResponse := GetCommitResponse{
LastPipeline: GetCommitResponseLastPipeline{
ID: gitlabPipelineSuccessMrID,
Ref: updateStatusHeadBranchDuplicate,
},
}
getCommitJsonResponse, err := json.Marshal(getCommitResponse)
getCommitStatusesJsonResponse, err := json.Marshal([]EmptyStruct{})
Ok(t, err)

_, err = w.Write(getCommitJsonResponse)
_, err = w.Write(getCommitStatusesJsonResponse)
Ok(t, err)

case "/api/v4/":
Expand Down

0 comments on commit 9648c1d

Please sign in to comment.