Skip to content

Commit

Permalink
Merge pull request #241 from Ugzuzg/feat/required-checks
Browse files Browse the repository at this point in the history
Add checks mode input
  • Loading branch information
GrantBirki authored Feb 17, 2024
2 parents 0ae2f57 + aecb736 commit 78f0f04
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 3 deletions.
120 changes: 118 additions & 2 deletions __tests__/functions/prechecks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ beforeEach(() => {
allowForks: true,
skipCi: '',
skipReviews: '',
draft_permitted_targets: ''
draft_permitted_targets: '',
checks: 'all'
}
}

Expand Down Expand Up @@ -87,7 +88,23 @@ beforeEach(() => {
totalCount: 3
},
statusCheckRollup: {
state: 'SUCCESS'
state: 'SUCCESS',
contexts: {
nodes: [
{
isRequired: true,
conclusion: 'SUCCESS'
},
{
isRequired: true,
conclusion: 'SKIPPED'
},
{
isRequired: false,
conclusion: 'SUCCESS'
}
]
}
}
}
}
Expand Down Expand Up @@ -133,6 +150,57 @@ test('runs prechecks and finds that the IssueOps command is valid for a branch d
})
})

test('runs prechecks and finds that the IssueOps command is valid for a branch deployment with required checks', async () => {
octokit.graphql = jest.fn().mockReturnValue({
repository: {
pullRequest: {
reviewDecision: 'APPROVED',
mergeStateStatus: 'CLEAN',
commits: {
nodes: [
{
commit: {
checkSuites: {
totalCount: 3
},
statusCheckRollup: {
state: 'FAILURE',
contexts: {
nodes: [
{
isRequired: true,
conclusion: 'SUCCESS'
},
{
isRequired: true,
conclusion: 'SKIPPED'
},
{
isRequired: false,
conclusion: 'FAILURE'
}
]
}
}
}
}
]
}
}
}
})

data.inputs.checks = 'required'

expect(await prechecks(context, octokit, data)).toStrictEqual({
message: '✅ PR is approved and all CI checks passed',
noopMode: false,
ref: 'test-ref',
status: true,
sha: 'abc123'
})
})

test('runs prechecks and finds that the IssueOps command is valid for a rollback deployment', async () => {
octokit.rest.repos.getBranch = jest
.fn()
Expand Down Expand Up @@ -619,6 +687,54 @@ test('runs prechecks and finds the PR is approved but CI is failing', async () =
})
})

test('runs prechecks and finds the PR is approved but CI is failing', async () => {
octokit.graphql = jest.fn().mockReturnValue({
repository: {
pullRequest: {
reviewDecision: 'APPROVED',
commits: {
nodes: [
{
commit: {
checkSuites: {
totalCount: 3
},
statusCheckRollup: {
state: 'FAILURE',
contexts: {
nodes: [
{
isRequired: true,
conclusion: 'SUCCESS'
},
{
isRequired: true,
conclusion: 'FAILURE'
},
{
isRequired: false,
conclusion: 'SUCCESS'
}
]
}
}
}
}
]
}
}
}
})

data.inputs.checks = 'required'

expect(await prechecks(context, octokit, data)).toStrictEqual({
message:
'### ⚠️ Cannot proceed with deployment\n\n- reviewDecision: `APPROVED`\n- commitStatus: `FAILURE`\n\n> Your pull request is approved but CI checks are failing',
status: false
})
})

test('runs prechecks and finds the PR does not require approval but CI is failing', async () => {
octokit.graphql = jest.fn().mockReturnValue({
repository: {
Expand Down
10 changes: 10 additions & 0 deletions __tests__/schemas/action.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@ inputs:
default:
type: string
required: false
checks:
description:
type: string
required: true
required:
type: boolean
required: true
default:
type: string
required: true
skip_reviews:
description:
type: string
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ inputs:
description: 'A comma separated list of environments that will not use passing CI as a requirement for deployment. Use this option to explicitly bypass branch protection settings for a certain environment in your repository. Default is an empty string "" - Example: "development,staging"'
required: false
default: ""
checks:
description: 'The mode to use for CI checks. "all" requires all checks to pass no matter what, "required" only waits for required checks.'
required: false
default: "all"
skip_reviews:
description: 'A comma separated list of environment that will not use reviews/approvals as a requirement for deployment. Use this options to explicitly bypass branch protection settings for a certain environment in your repository. Default is an empty string "" - Example: "development,staging"'
required: false
Expand Down
24 changes: 24 additions & 0 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions src/functions/prechecks.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export async function prechecks(context, octokit, data) {
const skipCi = skipCiArray.includes(data.environment)
const skipReviews = skipReviewsArray.includes(data.environment)
const allowDraftDeploy = draftPermittedTargetsArray.includes(data.environment)
const checks = data.inputs.checks

var ref = pr.data.head.ref
var noopMode = data.environmentObj.noop
Expand Down Expand Up @@ -118,6 +119,14 @@ export async function prechecks(context, octokit, data) {
}
statusCheckRollup {
state
contexts(first:100) {
nodes {
... on CheckRun {
isRequired(pullRequestNumber:$number)
conclusion
}
}
}
}
}
}
Expand Down Expand Up @@ -183,6 +192,18 @@ export async function prechecks(context, octokit, data) {
core.info('💡 no CI checks have been defined for this pull request')
commitStatus = null

// If only the required checks need to pass
} else if (checks === 'required') {
commitStatus =
result.repository.pullRequest.commits.nodes[0].commit.statusCheckRollup.contexts.nodes
.filter(x => x.isRequired)
.reduce(
(acc, x) => acc && ['SUCCESS', 'SKIPPED'].includes(x.conclusion),
true
)
? 'SUCCESS'
: 'FAILURE'

// If there are CI checked defined, we need to check for the 'state' of the latest commit
} else {
commitStatus =
Expand Down
3 changes: 3 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export async function run() {
const required_contexts = core.getInput('required_contexts')
const allowForks = core.getBooleanInput('allow_forks')
const skipCi = core.getInput('skip_ci')
const checks = core.getInput('checks')
const skipReviews = core.getInput('skip_reviews')
const mergeDeployMode = core.getBooleanInput('merge_deploy_mode')
const unlockOnMergeMode = core.getBooleanInput('unlock_on_merge_mode')
Expand Down Expand Up @@ -202,6 +203,7 @@ export async function run() {
required_contexts: required_contexts,
allowForks: allowForks,
skipCi: skipCi,
checks: checks,
skipReviews: skipReviews,
draft_permitted_targets,
admins: admins,
Expand Down Expand Up @@ -454,6 +456,7 @@ export async function run() {
issue_number: issue_number,
allowForks: allowForks,
skipCi: skipCi,
checks: checks,
skipReviews: skipReviews,
draft_permitted_targets: draft_permitted_targets
}
Expand Down

0 comments on commit 78f0f04

Please sign in to comment.