Skip to content

Commit 9704d27

Browse files
Jacksunweicopybara-github
authored andcommitted
ci: Add a github action to automatically close the PR imported and committed by Copybara
Include a manual mode for testing first and will remove after verifying it works. When a commit with `Merge https://github.com/google/adk-python/pull/3333` in description is pushed by copybara, the workflow will automatically close the PR. Co-authored-by: Wei Sun (Jack) <weisun@google.com> PiperOrigin-RevId: 826058313
1 parent ec86608 commit 9704d27

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

.github/copybara-pr-handler.yml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Copybara PR Handler
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
inputs:
9+
pr_number:
10+
description: 'PR number to close (for testing)'
11+
required: true
12+
type: string
13+
commit_sha:
14+
description: 'Commit SHA reference (optional, for testing)'
15+
required: false
16+
type: string
17+
18+
jobs:
19+
close-imported-pr:
20+
runs-on: ubuntu-latest
21+
permissions:
22+
pull-requests: write
23+
issues: write
24+
contents: read
25+
26+
steps:
27+
- name: Check for Copybara commits and close PRs
28+
uses: actions/github-script@v7
29+
with:
30+
github-token: ${{ secrets.ADK_TRIAGE_AGENT }}
31+
script: |
32+
// Check if this is a manual test run
33+
const isManualRun = context.eventName === 'workflow_dispatch';
34+
35+
let prsToClose = [];
36+
37+
if (isManualRun) {
38+
// Manual testing mode
39+
const prNumber = parseInt(context.payload.inputs.pr_number);
40+
const commitSha = context.payload.inputs.commit_sha || context.sha.substring(0, 7);
41+
42+
console.log('=== MANUAL TEST MODE ===');
43+
console.log(`Testing with PR #${prNumber}, commit ${commitSha}`);
44+
45+
prsToClose.push({ prNumber, commitSha });
46+
} else {
47+
// Normal mode: process commits from push event
48+
const commits = context.payload.commits || [];
49+
console.log(`Found ${commits.length} commit(s) in this push`);
50+
51+
// Process each commit
52+
for (const commit of commits) {
53+
const sha = commit.id;
54+
const committer = commit.committer.name;
55+
const message = commit.message;
56+
57+
console.log(`\n--- Processing commit ${sha.substring(0, 7)} ---`);
58+
console.log(`Committer: ${committer}`);
59+
60+
// Check if this is a Copybara commit
61+
if (committer !== 'Copybara-Service') {
62+
console.log('Not a Copybara commit, skipping');
63+
continue;
64+
}
65+
66+
// Extract PR number from commit message
67+
// Pattern: "Merge https://github.com/google/adk-python/pull/3333"
68+
const prMatch = message.match(/Merge https:\/\/github\.com\/google\/adk-python\/pull\/(\d+)/);
69+
70+
if (!prMatch) {
71+
console.log('No PR number found in Copybara commit message');
72+
continue;
73+
}
74+
75+
const prNumber = parseInt(prMatch[1]);
76+
const commitSha = sha.substring(0, 7);
77+
78+
prsToClose.push({ prNumber, commitSha });
79+
}
80+
}
81+
82+
// Process PRs to close
83+
for (const { prNumber, commitSha } of prsToClose) {
84+
console.log(`\n--- Processing PR #${prNumber} ---`);
85+
86+
// Get PR details to check if it's open
87+
let pr;
88+
try {
89+
pr = await github.rest.pulls.get({
90+
owner: context.repo.owner,
91+
repo: context.repo.repo,
92+
pull_number: prNumber
93+
});
94+
} catch (error) {
95+
console.log(`PR #${prNumber} not found or inaccessible:`, error.message);
96+
continue;
97+
}
98+
99+
// Only close if PR is still open
100+
if (pr.data.state !== 'open') {
101+
console.log(`PR #${prNumber} is already ${pr.data.state}, skipping`);
102+
continue;
103+
}
104+
105+
const author = pr.data.user.login;
106+
107+
try {
108+
// Add comment with commit reference
109+
await github.rest.issues.createComment({
110+
owner: context.repo.owner,
111+
repo: context.repo.repo,
112+
issue_number: prNumber,
113+
body: `Thank you @${author} for your contribution! 🎉\n\nYour changes have been successfully imported and merged via Copybara in commit ${commitSha}.\n\nClosing this PR as the changes are now in the main branch.`
114+
});
115+
116+
// Close the PR
117+
await github.rest.pulls.update({
118+
owner: context.repo.owner,
119+
repo: context.repo.repo,
120+
pull_number: prNumber,
121+
state: 'closed'
122+
});
123+
124+
console.log(`Successfully closed PR #${prNumber}`);
125+
} catch (error) {
126+
console.log(`Error closing PR #${prNumber}:`, error.message);
127+
}
128+
}
129+
130+
if (isManualRun) {
131+
console.log('\n=== TEST COMPLETED ===');
132+
} else {
133+
console.log('\n--- Finished processing all commits ---');
134+
}

0 commit comments

Comments
 (0)