Skip to content

New pipeline: nf-core/eisca #1814

New pipeline: nf-core/eisca

New pipeline: nf-core/eisca #1814

Workflow file for this run

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