Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVEREST-107 Add workflow for auto-updating PR's base branch #692

Merged
merged 1 commit into from
Mar 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions .github/workflows/auto-update-base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Auto-Update PR Base

on:
push:
branches:
- main

jobs:
auto-update-base:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
github-token: ${{ secrets.ROBOT_TOKEN }}
script: |
let retriesNeeded = true;
let attemptCount = 0;
const maxAttempts = 10; // Set a limit for the maximum number of attempts
let errorEncountered = false; // Track if any errors occur

while (retriesNeeded && attemptCount < maxAttempts) {
retriesNeeded = false; // Assume no retries needed, unless 'unknown' state is found.
attemptCount += 1;

try {
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: "open",
});

for (const pull of pulls) {
const hasAutoUpdateLabel = pull.labels.some(label => label.name === "auto-update-base");

if (!hasAutoUpdateLabel) {
continue;
}

try {
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
});

switch (pr.mergeable) {
case null:
console.log(`[INFO] PR #${pull.number}: "${pull.title}" - GitHub is still computing the mergeability. Will retry later.`);
retriesNeeded = true;
break;
case false:
console.log(`[INFO] PR #${pull.number}: "${pull.title}" - Skipping update due to merge conflict.`);
break;
case true:
try {
const { data: baseBranch } = await github.rest.repos.getBranch({
owner: context.repo.owner,
repo: context.repo.repo,
branch: pr.base.ref,
});

if (pr.base.sha === baseBranch.commit.sha) {
console.log(`[INFO] PR #${pull.number}: "${pull.title}" - Base branch is already up-to-date.`);
break;
}

console.log(`[UPDATE] PR #${pull.number}: "${pull.title}" - Updating base branch...`);
try {
await github.rest.pulls.updateBranch({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
});
console.log(`[SUCCESS] PR #${pull.number}: "${pull.title}" - Base branch updated.`);
} catch (updateError) {
console.error(`[ERROR] PR #${pull.number}: Failed to update base branch - ${updateError.message}`);
errorEncountered = true;
}

break;
} catch (baseError) {
console.error(`[ERROR] PR #${pull.number}: Failed to get base branch - ${baseError.message}`);
errorEncountered = true;
break;
}
}
} catch (prError) {
console.error(`[ERROR] Failed to get PR #${pull.number} - ${prError.message}`);
errorEncountered = true;
}
}
} catch (error) {
console.error(`[ERROR] Failed to list pull requests - ${error.message}`);
errorEncountered = true;
}

if (retriesNeeded && attemptCount < maxAttempts) {
console.log(`[INFO] Retrying for PRs with 'unknown' mergeable state (Attempt ${attemptCount}/${maxAttempts})...`);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}

if (attemptCount >= maxAttempts) {
console.error(`[ERROR] Maximum attempts (${maxAttempts}) reached. Some PRs may still have 'unknown' mergeable state.`);
errorEncountered = true;
}

if (errorEncountered) {
core.setFailed(`[ERROR] Some PRs failed to update base branch.`);
} else {
console.log(`[INFO] All PRs with 'auto-update-base' label have been processed.`);
}