Skip to content

Commit

Permalink
fix: Fix GitHub pull request mergeability for multiple required workf…
Browse files Browse the repository at this point in the history
…low runs (#5057)

Signed-off-by: Roman Ryzhyi <[email protected]>
  • Loading branch information
ajax-ryzhyi-r authored Nov 19, 2024
1 parent 5dfd900 commit b975301
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 12 deletions.
34 changes: 32 additions & 2 deletions server/events/vcs/github_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ type WorkflowRun struct {
RepositoryFileUrl githubv4.String
RepositoryName githubv4.String
}
RunNumber githubv4.Int
}

type CheckRun struct {
Expand Down Expand Up @@ -718,10 +719,27 @@ func StatusContextPassed(statusContext StatusContext, vcsstatusname string) bool
}

func ExpectedCheckPassed(expectedContext githubv4.String, checkRuns []CheckRun, statusContexts []StatusContext, vcsstatusname string) bool {
// If there's no WorkflowRun, we assume there's only one CheckRun with the given name.
// In this case, we evaluate and return the status of this CheckRun.
// If there is WorkflowRun, we assume there can be multiple checkRuns with the given name,
// so we retrieve the latest checkRun and evaluate and return the status of the latest CheckRun.
latestCheckRunNumber := githubv4.Int(-1)
var latestCheckRun *CheckRun
for _, checkRun := range checkRuns {
if checkRun.Name == expectedContext {
if checkRun.Name != expectedContext {
continue
}
if checkRun.CheckSuite.WorkflowRun == nil {
return CheckRunPassed(checkRun)
}
if checkRun.CheckSuite.WorkflowRun.RunNumber > latestCheckRunNumber {
latestCheckRunNumber = checkRun.CheckSuite.WorkflowRun.RunNumber
latestCheckRun = &checkRun
}
}

if latestCheckRun != nil {
return CheckRunPassed(*latestCheckRun)
}

for _, statusContext := range statusContexts {
Expand All @@ -734,6 +752,11 @@ func ExpectedCheckPassed(expectedContext githubv4.String, checkRuns []CheckRun,
}

func (g *GithubClient) ExpectedWorkflowPassed(expectedWorkflow WorkflowFileReference, checkRuns []CheckRun) (bool, error) {
// If there's no WorkflowRun, we just skip evaluation for given CheckRun.
// If there is WorkflowRun, we assume there can be multiple checkRuns with the given name,
// so we retrieve the latest checkRun and evaluate and return the status of the latest CheckRun.
latestCheckRunNumber := githubv4.Int(-1)
var latestCheckRun *CheckRun
for _, checkRun := range checkRuns {
if checkRun.CheckSuite.WorkflowRun == nil {
continue
Expand All @@ -743,10 +766,17 @@ func (g *GithubClient) ExpectedWorkflowPassed(expectedWorkflow WorkflowFileRefer
return false, err
}
if match {
return CheckRunPassed(checkRun), nil
if checkRun.CheckSuite.WorkflowRun.RunNumber > latestCheckRunNumber {
latestCheckRunNumber = checkRun.CheckSuite.WorkflowRun.RunNumber
latestCheckRun = &checkRun
}
}
}

if latestCheckRun != nil {
return CheckRunPassed(*latestCheckRun), nil
}

return false, nil
}

Expand Down
6 changes: 6 additions & 0 deletions server/events/vcs/github_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,12 @@ func TestGithubClient_PullIsMergeableWithAllowMergeableBypassApply(t *testing.T)
`"APPROVED"`,
true,
},
{
"blocked",
"ruleset-workflow-passed-multiple-runs.json",
`"APPROVED"`,
true,
},
{
"blocked",
"ruleset-workflow-passed-sha-match.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
}
},
"runNumber": 1
}
}
}
Expand All @@ -92,4 +93,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
}
},
"runNumber": 1
}
}
}
Expand All @@ -92,4 +93,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"data": {
"repository": {
"pullRequest": {
"reviewDecision": null,
"baseRef": {
"branchProtectionRule": {
"requiredStatusChecks": []
},
"rules": {
"pageInfo": {
"endCursor": "QWERTY",
"hasNextPage": false
},
"nodes": [
{
"type": "REQUIRED_STATUS_CHECKS",
"repositoryRuleset": {
"enforcement": "ACTIVE"
},
"parameters": {
"requiredStatusChecks": [
{
"context": "atlantis/apply"
}
]
}
},
{
"type": "WORKFLOWS",
"repositoryRuleset": {
"enforcement": "ACTIVE"
},
"parameters": {
"workflows": [
{
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryId": 120519269,
"sha": null
}
]
}
}
]
}
},
"commits": {
"nodes": [
{
"commit": {
"statusCheckRollup": {
"contexts": {
"pageInfo": {
"endCursor": "QWERTY",
"hasNextPage": false
},
"nodes": [
{
"__typename": "StatusContext",
"context": "atlantis/apply",
"state": "PENDING",
"isRequired": true
},
{
"__typename": "StatusContext",
"context": "atlantis/plan",
"state": "SUCCESS",
"isRequired": false
},
{
"__typename": "CheckRun",
"name": "my required check",
"conclusion": "FAILURE",
"isRequired": true,
"checkSuite": {
"workflowRun": {
"file": {
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
},
"runNumber": 1
}
}
},
{
"__typename": "CheckRun",
"name": "my required check",
"conclusion": "SUCCESS",
"isRequired": true,
"checkSuite": {
"workflowRun": {
"file": {
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
},
"runNumber": 2
}
}
}
]
}
}
}
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
}
},
"runNumber": 1
}
}
}
Expand All @@ -92,4 +93,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
}
},
"runNumber": 1
}
}
}
Expand All @@ -92,4 +93,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"path": ".github/workflows/my-required-workflow.yaml",
"repositoryFileUrl": "https://github.com/runatlantis/atlantis/blob/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/.github/workflows/my-required-workflow.yaml",
"repositoryName": "runatlantis/atlantis"
}
},
"runNumber": 1
}
}
}
Expand All @@ -92,4 +93,4 @@
}
}
}
}
}

0 comments on commit b975301

Please sign in to comment.