Skip to content

Commit cecf4c3

Browse files
committed
Block release if checks are failing
1 parent b419342 commit cecf4c3

1 file changed

Lines changed: 71 additions & 3 deletions

File tree

.github/workflows/release.yaml

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ on:
88
- main
99

1010
permissions:
11+
checks: read
1112
contents: write
13+
statuses: read
1214

1315
jobs:
1416
generate-tag:
@@ -29,6 +31,72 @@ jobs:
2931
git tag "$GIT_TAG"
3032
git push origin "$GIT_TAG"
3133
34+
validate-production-tag:
35+
name: Validate production tag checks
36+
runs-on: ubuntu-latest
37+
needs: [generate-tag]
38+
permissions:
39+
checks: read
40+
contents: read
41+
statuses: read
42+
steps:
43+
- name: Fail if the tagged commit has failing or pending checks
44+
if: github.ref_type == 'tag' && !contains(needs.generate-tag.outputs.tag, '-')
45+
uses: actions/github-script@v9
46+
with:
47+
script: |
48+
const failingConclusions = new Set([
49+
"action_required",
50+
"cancelled",
51+
"failure",
52+
"stale",
53+
"startup_failure",
54+
"timed_out",
55+
]);
56+
57+
const checkRuns = await github.paginate(
58+
github.rest.checks.listForRef,
59+
{
60+
...context.repo,
61+
ref: context.sha,
62+
filter: "latest",
63+
per_page: 100,
64+
},
65+
);
66+
const currentRunPath = `/actions/runs/${context.runId}/`;
67+
const blockingChecks = checkRuns.filter((check) => {
68+
// Do not block the release on jobs from this workflow run.
69+
if (check.details_url?.includes(currentRunPath)) {
70+
return false;
71+
}
72+
return check.status !== "completed" ||
73+
failingConclusions.has(check.conclusion);
74+
});
75+
76+
const { data: combinedStatus } =
77+
await github.rest.repos.getCombinedStatusForRef({
78+
...context.repo,
79+
ref: context.sha,
80+
});
81+
const blockingStatuses = combinedStatus.statuses.filter(
82+
(status) => status.state !== "success",
83+
);
84+
85+
if (blockingChecks.length || blockingStatuses.length) {
86+
const blockers = [
87+
...blockingChecks.map(
88+
(check) =>
89+
`check run: ${check.name} (${check.conclusion ?? check.status})`,
90+
),
91+
...blockingStatuses.map(
92+
(status) => `commit status: ${status.context} (${status.state})`,
93+
),
94+
];
95+
core.setFailed(
96+
`Production release blocked because ${context.sha} has failing or pending checks:\n${blockers.join("\n")}`,
97+
);
98+
}
99+
32100
build-melange-packages:
33101
needs: [generate-tag]
34102
if: contains(needs.generate-tag.outputs.tag, '-')
@@ -48,7 +116,7 @@ jobs:
48116
arch: ${{ matrix.runner.arch }}
49117

50118
build-securebuild:
51-
needs: [generate-tag]
119+
needs: [generate-tag, validate-production-tag]
52120
if: github.ref_type == 'tag' && !contains(needs.generate-tag.outputs.tag, '-')
53121
uses: ./.github/workflows/publish-securebuild.yml
54122
with:
@@ -205,7 +273,7 @@ jobs:
205273
goreleaser:
206274
runs-on: ubuntu-latest
207275
if: github.ref_type != 'branch'
208-
needs: [generate-tag, build-web]
276+
needs: [generate-tag, validate-production-tag, build-web]
209277
steps:
210278
- name: Checkout
211279
uses: actions/checkout@v7
@@ -384,7 +452,7 @@ jobs:
384452

385453
generate-kots-release-notes-pr:
386454
runs-on: ubuntu-latest
387-
needs: [generate-tag]
455+
needs: [generate-tag, validate-production-tag]
388456
if: github.ref_type != 'branch'
389457
steps:
390458
- name: Checkout

0 commit comments

Comments
 (0)