@@ -24,34 +24,17 @@ jobs:
2424 github-token : ${{ secrets.GITHUB_TOKEN }}
2525 result-encoding : string
2626 script : |
27- try {
28- const permission = await github.rest.repos.getCollaboratorPermissionLevel({
29- owner: context.repo.owner,
30- repo: context.repo.repo,
31- username: context.actor
32- });
33-
34- const hasPermission = ['admin', 'write'].includes(permission.data.permission);
35- console.log(`User ${context.actor} has permission: ${permission.data.permission}`);
36- return hasPermission ? 'true' : 'false';
37- } catch (error) {
38- console.error('Error checking permissions:', error);
39- return 'false';
40- }
27+ const script = require('./.github/scripts/check-permissions.js');
28+ return await script({ github, context });
4129
4230 - name : Exit if unauthorized
4331 if : steps.check-permissions.outputs.result != 'true'
4432 uses : actions/github-script@v7
4533 with :
4634 github-token : ${{ secrets.GITHUB_TOKEN }}
4735 script : |
48- await github.rest.issues.createComment({
49- owner: context.repo.owner,
50- repo: context.repo.repo,
51- issue_number: context.issue.number,
52- body: '❌ Only repository admins and maintainers can trigger CI runs. You have insufficient permissions.'
53- });
54- core.setFailed('Insufficient permissions to trigger CI');
36+ const script = require('./.github/scripts/post-unauthorized-comment.js');
37+ await script({ github, context, core });
5538
5639 - name : Get PR details
5740 if : steps.check-permissions.outputs.result == 'true'
6043 with :
6144 github-token : ${{ secrets.GITHUB_TOKEN }}
6245 script : |
63- const pr = await github.rest.pulls.get({
64- owner: context.repo.owner,
65- repo: context.repo.repo,
66- pull_number: context.issue.number
67- });
68-
69- return {
70- head_ref: pr.data.head.ref,
71- head_sha: pr.data.head.sha,
72- head_repo_full_name: pr.data.head.repo.full_name,
73- base_ref: pr.data.base.ref,
74- title: pr.data.title,
75- number: pr.data.number,
76- user: pr.data.user.login
77- };
46+ const script = require('./.github/scripts/get-pr-details.js');
47+ return await script({ github, context });
7848
7949 - name : Checkout repo
8050 if : steps.check-permissions.outputs.result == 'true'
@@ -88,128 +58,7 @@ jobs:
8858 with :
8959 github-token : ${{ secrets.GITHUB_TOKEN }}
9060 script : |
61+ const script = require('./.github/scripts/create-ci-pr.js');
9162 const prDetails = ${{ steps.pr-details.outputs.result }};
92- const ciBranchName = `ci-test/${prDetails.number}`;
93-
94- // Add remote for the external fork if it's from a fork
95- if (prDetails.head_repo_full_name !== `${context.repo.owner}/${context.repo.repo}`) {
96- await exec.exec('git', ['remote', 'add', 'external', `https://github.com/${prDetails.head_repo_full_name}.git`]);
97- await exec.exec('git', ['fetch', 'external', prDetails.head_ref]);
98- await exec.exec('git', ['checkout', '-b', ciBranchName, `external/${prDetails.head_ref}`]);
99- } else {
100- await exec.exec('git', ['fetch', 'origin', prDetails.head_ref]);
101- await exec.exec('git', ['checkout', '-b', ciBranchName, `origin/${prDetails.head_ref}`]);
102- }
103-
104- // Push the branch to origin (force push to update if exists)
105- await exec.exec('git', ['push', '-f', 'origin', ciBranchName]);
106-
107- // Check if a CI PR already exists for this original PR
108- const existingPRs = await github.rest.pulls.list({
109- owner: context.repo.owner,
110- repo: context.repo.repo,
111- state: 'open',
112- head: `${context.repo.owner}:${ciBranchName}`
113- });
114-
115- let ciPR;
116- let isNewPR = false;
117-
118- if (existingPRs.data.length > 0) {
119- // Filter to find the CI test PR (should be labeled with 'ci-test')
120- const ciTestPR = existingPRs.data.find(pr =>
121- pr.labels.some(label => label.name === 'ci-test')
122- );
123-
124- if (ciTestPR) {
125- // Update existing PR
126- ciPR = ciTestPR;
127- await github.rest.pulls.update({
128- owner: context.repo.owner,
129- repo: context.repo.repo,
130- pull_number: ciPR.number,
131- body: `🤖 **Automated CI Test PR**
132-
133- This is an automated PR created to run CI tests for PR # ${prDetails.number} by @${prDetails.user}.
134-
135- **Original PR:** # ${prDetails.number}
136- **Last triggered by:** @${context.actor}
137- **Source branch:** \`${prDetails.head_ref}\`
138- **Source SHA:** \`${prDetails.head_sha}\`
139-
140- ⚠️ **This PR will be automatically closed once CI completes.** Do not merge this PR.
141-
142- ---
143- _This PR was last updated in response to the \`/run-ci\` command in # ${prDetails.number}_`
144- });
145- } else {
146- // Existing PR found but it's not labeled as a CI test PR
147- // Verify it's actually a CI test PR by checking the title
148- const existingPR = existingPRs.data[0];
149- if (existingPR.title.startsWith('[CI Test]')) {
150- // Use the existing PR and add the labels
151- ciPR = existingPR;
152- isNewPR = true; // Treat as new to ensure labels are added
153- }
154- // If it's not a CI test PR, ciPR remains undefined and a new PR will be created
155- }
156- }
157-
158- if (!ciPR) {
159- // Create a new draft PR
160- const newPR = await github.rest.pulls.create({
161- owner : context.repo.owner,
162- repo : context.repo.repo,
163- title : ` [CI Test] ${prDetails.title}` ,
164- head : ciBranchName,
165- base : prDetails.base_ref,
166- body : ` 🤖 **Automated CI Test PR**
167-
168- This is an automated PR created to run CI tests for PR #${prDetails.number} by @${prDetails.user}.
169-
170- **Original PR:** #${prDetails.number}
171- **Triggered by:** @${context.actor}
172- **Source branch:** \` ${prDetails.head_ref}\`
173- **Source SHA:** \` ${prDetails.head_sha}\`
174-
175- ⚠️ **This PR will be automatically closed once CI completes.** Do not merge this PR.
176-
177- ---
178- _This PR was created in response to the \` /run-ci\` command in #${prDetails.number}_` ,
179- draft : true
180- });
181- ciPR = newPR.data;
182- isNewPR = true;
183- }
184-
185- // Ensure labels are present on the CI PR (handles both new and existing PRs)
186- // Labels can be strings or objects with 'name' property depending on the API response
187- const currentLabels = ciPR.labels?.map(l => typeof l === 'string' ? l : l.name) || [];
188- const requiredLabels = ['ci-test', 'automated'];
189- const missingLabels = requiredLabels.filter(label => !currentLabels.includes(label));
190-
191- if (missingLabels.length > 0) {
192- await github.rest.issues.addLabels({
193- owner : context.repo.owner,
194- repo : context.repo.repo,
195- issue_number : ciPR.number,
196- labels : missingLabels
197- });
198- }
199-
200- // Comment on the original PR
201- const prAction = isNewPR ? 'created' : ' updated' ;
202- await github.rest.issues.createComment({
203- owner : context.repo.owner,
204- repo : context.repo.repo,
205- issue_number : context.issue.number,
206- body : ` ✅ CI test ${prAction} by @${context.actor}!
207-
208- CI is now running in draft PR #${ciPR.number}. You can monitor the progress there.
209-
210- Once the tests complete, you can review the results and the draft PR will be automatically closed.`
211- });
212-
213- core.setOutput('ci_pr_number', ciPR.number);
214- core.setOutput('ci_branch_name', ciBranchName);
63+ await script({ github, context, core, exec }, prDetails);
21564
0 commit comments