fix: Fix GitHub pull request mergeability for multiple required workflow runs (#5057)

Signed-off-by: Roman Ryzhyi <ryzhyi.r@ajax.systems>
This commit is contained in:
Roma Ryzhyi
2024-11-19 11:52:53 +02:00
committed by GitHub
parent 5dfd90055c
commit b975301b2b
8 changed files with 165 additions and 12 deletions

View File

@@ -481,6 +481,7 @@ type WorkflowRun struct {
RepositoryFileUrl githubv4.String
RepositoryName githubv4.String
}
RunNumber githubv4.Int
}
type CheckRun struct {
@@ -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 {
@@ -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
@@ -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
}

View File

@@ -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",

View File

@@ -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
}
}
}
@@ -92,4 +93,4 @@
}
}
}
}
}

View File

@@ -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
}
}
}
@@ -92,4 +93,4 @@
}
}
}
}
}

View File

@@ -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
}
}
}
]
}
}
}
}
]
}
}
}
}
}

View File

@@ -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
}
}
}
@@ -92,4 +93,4 @@
}
}
}
}
}

View File

@@ -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
}
}
}
@@ -92,4 +93,4 @@
}
}
}
}
}

View File

@@ -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
}
}
}
@@ -92,4 +93,4 @@
}
}
}
}
}