Skip to content

New pipeline: dragen #2019

New pipeline: dragen

New pipeline: dragen #2019

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);