New pipeline: nf-core/eisca #1814
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: RFC approval automation | |
| on: | |
| issues: | |
| types: [opened, closed, labeled, unlabeled] | |
| issue_comment: | |
| types: [created, edited] | |
| jobs: | |
| rfc_approval: | |
| # Only run for RFC proposal issues | |
| if: startsWith(github.event.issue.title, 'New RFC') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Handle RFC approval logic | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 | |
| with: | |
| github-token: ${{ secrets.nf_core_bot_auth_token }} | |
| script: | | |
| const ApprovalManager = require('./.github/workflows/lib/approval.js'); | |
| const issueNumber = context.issue.number; | |
| const org = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Initialize approval manager | |
| const approvalManager = await new ApprovalManager(github, org, repo, issueNumber).initialize(); | |
| // Ignore comments on closed issues | |
| if (context.eventName === 'issue_comment' && context.payload.issue.state === 'closed') { | |
| console.log('Comment event on closed issue, ignoring.'); | |
| return; | |
| } | |
| const quorum = Math.ceil(approvalManager.coreTeamMembers.length / 2); | |
| console.log(`Quorum set to ${quorum}.`); | |
| function generateStatusBody(status) { | |
| const approvers = [...approvalManager.coreApprovals]; | |
| const rejecters = [...approvalManager.coreRejections]; | |
| const awaiting = approvalManager.awaitingCore; | |
| let body = `## Approval status: ${status}\n\nRFC has approvals from ${approvalManager.coreApprovals.size}/${quorum} required @nf-core/core quorum.\n\n`; | |
| if (approvers.length > 0 || rejecters.length > 0 || awaiting.length > 0) { | |
| body += `|Review Status|Core Team members|\n|--|--|\n`; | |
| if (approvers.length > 0) { | |
| body += `| ✅ Approved | ${approvalManager.formatUserList(approvers)} |\n`; | |
| } | |
| if (rejecters.length > 0) { | |
| body += `| ❌ Rejected | ${approvalManager.formatUserList(rejecters)} |\n`; | |
| } | |
| if (awaiting.length > 0) { | |
| body += `| 🕐 Pending | ${approvalManager.formatUserList(awaiting)} |\n`; | |
| } | |
| } | |
| return body; | |
| } | |
| // Handle label changes | |
| if (context.eventName === 'issues' && (context.payload.action === 'labeled' || context.payload.action === 'unlabeled')) { | |
| const label = context.payload.label.name; | |
| if (label === 'timed-out') { | |
| console.log('Timed-out label detected, updating status'); | |
| const statusBody = generateStatusBody('⏰ Timed Out'); | |
| await approvalManager.updateStatusComment(statusBody); | |
| return; | |
| } | |
| } | |
| // Handle new issue creation | |
| if (context.eventName === 'issues' && context.payload.action === 'opened') { | |
| const body = generateStatusBody('🕐 Pending'); | |
| console.log('Creating initial comment for review status'); | |
| await approvalManager.updateStatusComment(body); | |
| await approvalManager.updateIssueStatus('🕐 Pending'); | |
| return; | |
| } | |
| // Determine status | |
| let status = '🕐 Pending'; | |
| if (context.eventName === 'issues' && context.payload.action === 'closed' && context.payload.issue.state_reason === 'not_planned' && (approvalManager.coreRejections.size > 0)) { | |
| status = '❌ Rejected'; | |
| } else if (approvalManager.coreApprovals.size >= quorum) { | |
| status = '✅ Approved'; | |
| } | |
| const statusBody = generateStatusBody(status); | |
| console.log('New status body to post:\n', statusBody); | |
| await approvalManager.updateStatusComment(statusBody); | |
| await approvalManager.updateIssueStatus(status); |