1- name : Auto Merge on Owner Approval
1+ name : PR Approval Notification
22
33on :
44 pull_request_review :
55 types : [submitted, dismissed]
66
77jobs :
8- auto-merge :
8+ pr-approval-notification :
99 runs-on : ubuntu-latest
1010 # Only run on pull requests, not on other events
1111 if : github.event.pull_request != null || github.event.pull_request_review != null
2020 env :
2121 # Configuration options
2222 REQUIRED_CHECKS : " test-and-build" # Comma-separated list of required check names
23- MERGE_METHOD : " squash" # squash, merge, or rebase
2423 SENSITIVE_PATHS : " .github/workflows/*,OWNER*" # Comma-separated patterns for sensitive files
2524
2625 steps :
@@ -526,7 +525,7 @@ jobs:
526525
527526 return securityPassed;
528527
529- - name : Auto-merge evaluation
528+ - name : PR approval evaluation
530529 if : always() && steps.should-proceed.outputs.result == 'true'
531530 id : auto-merge-evaluation
532531 uses : actions/github-script@v7
@@ -546,120 +545,44 @@ jobs:
546545 const pendingChecks = pendingChecksStr ? JSON.parse(pendingChecksStr) : [];
547546 const securityIssues = securityIssuesStr ? JSON.parse(securityIssuesStr) : [];
548547
549- console.log(`Final auto-merge evaluation for PR #${prNumber}:`);
548+ console.log(`Final approval evaluation for PR #${prNumber}:`);
550549 console.log(`- All approved: ${allApproved}`);
551550 console.log(`- CI passed: ${ciPassed}`);
552551 console.log(`- Security passed: ${securityPassed}`);
553552
554553 if (!allApproved) {
555- console.log(`❌ Cannot auto-merge : need approval from at least one of: ${JSON.parse('${{ steps.identify-owners.outputs.required_owners }}' || '[]').join(', ')}`);
554+ console.log(`❌ Cannot notify approval : need approval from at least one of: ${JSON.parse('${{ steps.identify-owners.outputs.required_owners }}' || '[]').join(', ')}`);
556555 return;
557556 }
558557
559558 if (!ciPassed) {
560559 if (failedChecks.length > 0) {
561- console.log(`❌ Cannot auto-merge : failed CI checks: ${failedChecks.join(', ')}`);
560+ console.log(`❌ Cannot notify approval : failed CI checks: ${failedChecks.join(', ')}`);
562561 }
563562 if (pendingChecks.length > 0) {
564- console.log(`⏳ Cannot auto-merge yet: pending CI checks: ${pendingChecks.join(', ')}`);
563+ console.log(`⏳ Cannot notify approval yet: pending CI checks: ${pendingChecks.join(', ')}`);
565564 }
566565 return;
567566 }
568567
569568 if (!securityPassed) {
570- console.log(`❌ Cannot auto-merge : security issues: ${securityIssues.join(', ')}`);
569+ console.log(`❌ Cannot notify approval : security issues: ${securityIssues.join(', ')}`);
571570 return;
572571 }
573572
574- // All checks passed - ready for merge !
575- console.log('🎉 All conditions met for auto-merge !');
573+ // All checks passed - ready to notify approval !
574+ console.log('🎉 All conditions met for approval notification !');
576575
577- // Set flag to proceed with merge
576+ // Set flag to proceed with notification
578577 core.setOutput('ready_for_merge', 'true');
579578
580- - name : Execute auto-merge
579+ - name : Add approval notification comment
581580 if : steps.auto-merge-evaluation.outputs.ready_for_merge == 'true'
582- id : execute-merge
581+ id : add-approval-comment
583582 uses : actions/github-script@v7
584583 with :
585584 script : |
586585 const prNumber = ${{ steps.pr-info.outputs.pr_number }};
587- const mergeMethod = '${{ env.MERGE_METHOD }}';
588- const requiredOwnersStr = '${{ steps.identify-owners.outputs.required_owners }}';
589- const approvedOwnersStr = '${{ steps.check-approvals.outputs.approved_owners }}';
590- const securityIssuesStr = '${{ steps.check-security.outputs.security_issues }}';
591-
592- const requiredOwners = requiredOwnersStr ? JSON.parse(requiredOwnersStr) : [];
593- const approvedOwners = approvedOwnersStr ? JSON.parse(approvedOwnersStr) : [];
594- const securityIssues = securityIssuesStr ? JSON.parse(securityIssuesStr) : [];
595-
596- console.log(`Executing auto-merge for PR #${prNumber} using ${mergeMethod} method`);
597-
598- try {
599- // Get PR details for commit message
600- const { data: pr } = await github.rest.pulls.get({
601- owner: context.repo.owner,
602- repo: context.repo.repo,
603- pull_number: prNumber,
604- });
605-
606- // Create commit message
607- let commitTitle = pr.title;
608- let commitMessage = '';
609-
610- if (mergeMethod === 'squash') {
611- // For squash merge, include PR number and auto-merge info
612- commitTitle = `${pr.title} (#${prNumber})`;
613- commitMessage = `${pr.body || ''}\n\n`;
614- commitMessage += `Auto-merged by GitHub Actions after approval from: ${approvedOwners.join(', ')}\n`;
615- if (securityIssues.length > 0) {
616- commitMessage += `Security warnings: ${securityIssues.join(', ')}\n`;
617- }
618- }
619-
620- // Execute the merge
621- const { data: mergeResult } = await github.rest.pulls.merge({
622- owner: context.repo.owner,
623- repo: context.repo.repo,
624- pull_number: prNumber,
625- commit_title: commitTitle,
626- commit_message: commitMessage,
627- merge_method: mergeMethod,
628- });
629-
630- console.log(`✅ Successfully merged PR #${prNumber}`);
631- console.log(`Merge commit SHA: ${mergeResult.sha}`);
632- console.log(`Merged: ${mergeResult.merged}`);
633-
634- // Set outputs for next steps
635- core.setOutput('merge_successful', 'true');
636- core.setOutput('merge_sha', mergeResult.sha);
637- core.setOutput('merge_message', mergeResult.message);
638-
639- return {
640- success: true,
641- sha: mergeResult.sha,
642- message: mergeResult.message
643- };
644-
645- } catch (error) {
646- console.log(`❌ Failed to merge PR #${prNumber}: ${error.message}`);
647-
648- // Set outputs for error handling
649- core.setOutput('merge_successful', 'false');
650- core.setOutput('merge_error', error.message);
651-
652- // Re-throw to trigger failure handling
653- throw error;
654- }
655-
656- - name : Add success comment
657- if : steps.execute-merge.outputs.merge_successful == 'true'
658- uses : actions/github-script@v7
659- with :
660- script : |
661- const prNumber = ${{ steps.pr-info.outputs.pr_number }};
662- const mergeSha = '${{ steps.execute-merge.outputs.merge_sha }}';
663586 const approvedOwnersStr = '${{ steps.check-approvals.outputs.approved_owners }}';
664587 const ownerMapStr = '${{ steps.identify-owners.outputs.owner_map }}';
665588 const securityIssuesStr = '${{ steps.check-security.outputs.security_issues }}';
@@ -670,48 +593,26 @@ jobs:
670593 const securityIssues = securityIssuesStr ? JSON.parse(securityIssuesStr) : [];
671594 const sensitiveFiles = sensitiveFilesStr ? JSON.parse(sensitiveFilesStr) : [];
672595
673- // Create success comment
674- let commentBody = '## 🎉 Thanks for your contributions!\n\n';
675- commentBody += `This PR will be automatically merged after receiving approval from one of the required owners.\n\n`;
596+ console.log(`Adding approval notification comment for PR #${prNumber}`);
597+
598+ // Create approval notification comment with vLLM logo
599+ let commentBody = '<div align="center">\n';
600+ commentBody += '<img src="https://raw.githubusercontent.com/vllm-project/semantic-router/main/website/static/img/repo.png" alt="vLLM" width="80%"/>';
601+ commentBody += '</div>\n\n';
602+ commentBody += '## 🎉 Thanks for your contributions!\n\n';
603+ commentBody += `This PR has been approved by the code owners and meets all the requirements for merging. A maintainer will merge it soon.\n\n`;
676604
677605 // Show approval details
678- commentBody += '### ✅ Approvals Received \n';
606+ commentBody += '### ✅ Approved by \n';
679607 for (const owner of approvedOwners) {
680- commentBody += `- ${owner}\n`;
608+ commentBody += `- @ ${owner}\n`;
681609 }
682610 commentBody += '\n';
683611
684- // Show owner mapping
685- if (Object.keys(ownerMap).length > 0) {
686- commentBody += '### 📁 Owner Mapping\n';
687- for (const [dirPath, info] of Object.entries(ownerMap)) {
688- commentBody += `**${dirPath === '.' ? 'Root Directory' : dirPath}**: ${info.owners.join(', ')}\n`;
689- }
690- commentBody += '\n';
691- }
692-
693- // Show security warnings if any
694- if (securityIssues.length > 0) {
695- commentBody += '### ⚠️ Security Warnings\n';
696- for (const issue of securityIssues) {
697- commentBody += `- ${issue}\n`;
698- }
699- commentBody += '\n';
700- }
701-
702- // Show sensitive files if any
703- if (sensitiveFiles.length > 0) {
704- commentBody += '### 🔒 Sensitive Files Modified\n';
705- for (const file of sensitiveFiles) {
706- commentBody += `- \`${file}\`\n`;
707- }
708- commentBody += '\n';
709- }
710-
711- commentBody += `**Merge commit:** ${mergeSha}\n`;
712- commentBody += `**Merge method:** ${{ env.MERGE_METHOD }}\n\n`;
612+ commentBody += '**Status:** ✅ Ready for merge\n';
613+ commentBody += '**Next steps:** Please be patient while a maintainer merges this PR.\n\n';
713614 commentBody += '---\n';
714- commentBody += '*This merge was performed automatically by GitHub Actions based on owner approvals and CI status .*';
615+ commentBody += '*This notification was generated automatically by GitHub Actions.*';
715616
716617 // Add the comment
717618 await github.rest.issues.createComment({
@@ -721,4 +622,14 @@ jobs:
721622 body: commentBody
722623 });
723624
724- console.log(`✅ Added success comment to PR #${prNumber}`);
625+ console.log(`✅ Added approval notification comment to PR #${prNumber}`);
626+
627+ // Set outputs for next steps
628+ core.setOutput('comment_added', 'true');
629+
630+ return {
631+ success: true,
632+ comment_added: true
633+ };
634+
635+
0 commit comments