New pipeline: dragen #2019
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: Pipeline proposal approval automation | |
| on: | |
| issues: | |
| types: [opened, closed, labeled, unlabeled] | |
| issue_comment: | |
| types: [created, edited] | |
| jobs: | |
| pipeline_approval: | |
| # Only run for pipeline proposal issues | |
| if: startsWith(github.event.issue.title, 'New pipeline') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Handle pipeline proposal 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; | |
| } | |
| function generateStatusBody(status) { | |
| const coreApprovers = [...approvalManager.coreApprovals]; | |
| const maintainerApprovers = [...approvalManager.maintainerApprovals]; | |
| const rejecters = [...approvalManager.coreRejections, ...approvalManager.maintainerRejections]; | |
| const awaitingCore = [...approvalManager.awaitingCore]; | |
| const awaitingMaintainers = [...approvalManager.awaitingMaintainers]; | |
| let body = `## Approval status: ${status}\n\n`; | |
| body += `Required approvals: Either 2 core team members OR 1 core team member + 1 maintainer\n\n`; | |
| if (coreApprovers.length > 0 || maintainerApprovers.length > 0 || rejecters.length > 0 || awaitingCore.length > 0 || awaitingMaintainers.length > 0) { | |
| body += `|Review Status|Team members|\n|--|--|\n`; | |
| if (coreApprovers.length > 0) { | |
| body += `| ✅ Approved (Core) | ${approvalManager.formatUserList(coreApprovers)} |\n`; | |
| } | |
| if (maintainerApprovers.length > 0) { | |
| body += `| ✅ Approved (Maintainer) | ${approvalManager.formatUserList(maintainerApprovers)} |\n`; | |
| } | |
| if (rejecters.length > 0) { | |
| body += `| ❌ Rejected | ${approvalManager.formatUserList(rejecters)} |\n`; | |
| } | |
| if (awaitingCore.length > 0) { | |
| body += `| 🕐 Pending (Core) | ${approvalManager.formatUserList(awaitingCore)} |\n`; | |
| } | |
| if (awaitingMaintainers.length > 0) { | |
| body += `| 🕐 Pending (Maintainer) | ${approvalManager.formatUserList(awaitingMaintainers)} |\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 || approvalManager.maintainerRejections.size > 0)) { | |
| status = '❌ Rejected'; | |
| } else if ((approvalManager.coreApprovals.size >= 2) || (approvalManager.coreApprovals.size >= 1 && approvalManager.maintainerApprovals.size >= 1)) { | |
| status = '✅ Approved'; | |
| } | |
| const statusBody = generateStatusBody(status); | |
| console.log('New status body to post:\n', statusBody); | |
| await approvalManager.updateStatusComment(statusBody); | |
| await approvalManager.updateIssueStatus(status); |