Skip to content

Commit

Permalink
workflow: Add check-main-status workflow
Browse files Browse the repository at this point in the history
The workflow checks the result of check runs on the latest commit on
the main branch. When checks on main are failing the check will fail.
If main is pending the check will retry every 5 mintues for an hour.
This prevents introducing more potenisal issues when main is already
broken.

To skip the check when making a fix for main, add the fix-ci label to
the PR.

Signed-off-by: Gregers Gram Rygg <gregers.gram.rygg@nordicsemi.no>
  • Loading branch information
gregersrygg committed Oct 11, 2024
1 parent 8f7d61e commit 3b7870e
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/check-main-status.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Check Main Branch Status
on:
pull_request:
merge_group:
workflow_dispatch:
inputs:
pr_number:
description: "Pull Request number"
required: true

jobs:
check-main-status:
runs-on: ubuntu-24.04
env:
PR_NUMBER: ${{ github.event.number || github.event.inputs.pr_number }}
steps:
- uses: actions/checkout@v3
- uses: actions/github-script@v7
name: Check if PR has 'fix-ci' label
id: has_fix_ci_label
with:
retries: 3
script: |
const checkMain = require('./.github/workflows/lib/checkMain.js');
const result = checkMain.hasFixCiLabel(github, context.owner, context.repo, process.env.PR_NUMBER);
console.log(`Has 'fix-ci' label: ${result}`);
return result;
- uses: actions/github-script@v7
name: Ensure Main Branch Check Runs Are Successful
if: ${{ steps.has_fix_ci_label.outputs.result == 'false' }}
with:
retries: 3
script: |
const checkMain = require('./.github/workflows/lib/checkMain.js');
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
try {
await checkMain.ensureChecksRunsSuccessful(delay, github, context.owner, context.repo);
} catch (error) {
core.setFailed(error.message);
}
1 change: 1 addition & 0 deletions .github/workflows/dfu_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: DFU image compatibility check

on:
workflow_call:
merge_group:
push:
branches:
- main
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/lib/checkMain.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module.exports = {
async hasFixCiLabel(octokit, owner, repo, prNumber) {
const labels = await octokit.issues.listLabelsOnIssue({
owner,
repo,
issue_number: prNumber,
});

return labels.data.map(label => label.name).includes('fix-ci');
},

async ensureChecksRunsSuccessful(delay, octokit, owner, repo) {
let retryPending = 12; // Retry for up to 1 hour (12 retries with 5 minutes interval)

while (retryPending > 0) {
const mainRef = await octokit.git.getRef({
owner,
repo,
ref: 'heads/main',
});

const mainSha = mainRef.data.object.sha;
console.log(`Main branch SHA: ${mainSha}`);

let checkRuns = await octokit.checks.listForRef({
owner,
repo,
ref: mainSha,
});

console.log(`Check runs (${checkRuns.data.total_count}):`);
for (let run of checkRuns.data.check_runs) {
console.log(`- ${run.name}`);
console.log(`\tstatus: ${run.status}`);
console.log(`\tconclusion: ${run.conclusion}`);
}

const failedChecks = checkRuns.data.check_runs.filter(run => run.conclusion !== null && run.conclusion !== 'success');
const pendingChecks = checkRuns.data.check_runs.filter(run => run.status !== 'completed');

if (failedChecks.length > 0) {
throw new Error('Cannot merge: The main branch has failing checks.');
} else if (pendingChecks.length === 0) {
console.log('Main branch is healthy.');
break;
} else {
console.log('Checks are still pending.');

retryPending--;
if (retryPending === 0) {
throw new Error('Timeout waiting for pending checks on main branch.');
}

console.log('Waiting for 5 minutes before retrying...');
await delay(5 * 60 * 1000); // Wait for 5 minutes
}
}
},
};

0 comments on commit 3b7870e

Please sign in to comment.