Unverified 提交 0f8ee17d authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

ci: auto-label conflicting PRs with cc:rebase on main push (#2587)

## Summary - Adds a new GitHub Actions workflow that runs on every push to `main` - Checks all open, non-draft PRs by `wwwillchen` and `wwwillchen-bot` for merge conflicts - Automatically adds the `cc:rebase` label to conflicting PRs, which triggers the existing `claude-rebase` workflow to auto-rebase them ## Test plan - [ ] Push to main and verify the workflow runs - [ ] Confirm PRs with merge conflicts get the `cc:rebase` label added - [ ] Confirm PRs that are already mergeable are skipped - [ ] Confirm PRs with existing `cc:rebase` or `cc:rebasing` labels are not re-labeled 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2587" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > CI-only change that adds an automated labeling workflow; main risk is unintended label churn or extra API usage, not production code impact. > > **Overview** > Adds a new GitHub Actions workflow (`label-rebase-prs.yml`) that runs on every push to `main` and iterates through open PRs from `wwwillchen`/`wwwillchen-bot`, skipping drafts. > > For PRs whose `mergeable_state` is `dirty`, it auto-applies the `cc:rebase` label (with retries when mergeability is initially `null`) while avoiding PRs already labeled `cc:rebase`, `cc:rebasing`, or `cc:rebase-failed`, enabling the existing `cc:rebase`-triggered rebase automation to kick in. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6bb04a1103190000f1aa4e9d71c4bea7def321c6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds a workflow that runs on every push to main and auto-labels conflicting PRs with cc:rebase to trigger the existing auto-rebase job. Reduces manual rebase work and keeps bot/author PRs up to date. - **New Features** - Runs on push to main; scans open, non-draft PRs by wwwillchen and wwwillchen-bot. - Detects conflicts via mergeable_state: 'dirty' and adds cc:rebase; skips PRs already labeled cc:rebase, cc:rebasing, or cc:rebase-failed. - Retries mergeability up to 3 times with exponential backoff; uses a concurrency group and per-PR try/catch to avoid duplicate runs and job aborts. <sup>Written for commit 6bb04a1103190000f1aa4e9d71c4bea7def321c6. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
上级 88afa495
name: Label PRs needing rebase
on:
push:
branches: [main]
concurrency:
group: label-rebase-prs
cancel-in-progress: true
permissions:
pull-requests: write
issues: write
jobs:
label-conflicting-prs:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const allowedAuthors = ['wwwillchen', 'wwwillchen-bot'];
const prs = await github.paginate(github.rest.pulls.list, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
});
for (const pr of prs) {
try {
if (!allowedAuthors.includes(pr.user.login)) continue;
if (pr.draft) continue;
// mergeable status requires an individual GET call
let latest = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
})).data;
// GitHub may not have computed mergeability yet (null).
// Retry with exponential backoff.
if (latest.mergeable === null) {
for (let attempt = 0; attempt < 3 && latest.mergeable === null; attempt++) {
await new Promise(r => setTimeout(r, 3000 * (attempt + 1)));
latest = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
})).data;
}
if (latest.mergeable === null) {
console.log(`PR #${pr.number}: mergeability still unknown after retries, skipping`);
continue;
}
}
if (latest.mergeable_state === 'dirty') {
const labels = latest.labels.map(l => l.name);
// Don't add if already labeled, actively rebasing, or previously failed
if (labels.includes('cc:rebase') || labels.includes('cc:rebasing') || labels.includes('cc:rebase-failed')) {
console.log(`PR #${pr.number} already has rebase label, skipping`);
continue;
}
console.log(`Adding cc:rebase to PR #${pr.number}: ${pr.title}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['cc:rebase'],
});
} else {
console.log(`PR #${pr.number} is mergeable (state: ${latest.mergeable_state}), skipping`);
}
} catch (err) {
console.log(`Error processing PR #${pr.number}: ${err.message}`);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论