| name: Test Workflows on PR Comment |
|
|
| on: |
| issue_comment: |
| types: [created] |
|
|
| permissions: |
| pull-requests: read |
| contents: read |
|
|
| jobs: |
| handle_comment_command: |
| name: Handle /test-workflows Command |
| if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/test-workflows') |
| runs-on: ubuntu-latest |
| outputs: |
| permission_granted: ${{ steps.pr_check_and_details.outputs.permission_granted }} |
| git_ref: ${{ steps.pr_check_and_details.outputs.head_sha }} |
| pr_number: ${{ steps.pr_check_and_details.outputs.pr_number_string }} |
|
|
| steps: |
| - name: Validate User, Get PR Details, and React |
| id: pr_check_and_details |
| uses: actions/github-script@v7 |
| with: |
| github-token: ${{ secrets.GITHUB_TOKEN }} |
| script: | |
| const commenter = context.actor; |
| const issueOwner = context.repo.owner; |
| const issueRepo = context.repo.repo; |
| const commentId = context.payload.comment.id; |
| const prNumber = context.issue.number; // In issue_comment on a PR, issue.number is the PR number |
| |
| // Function to add a reaction to the comment |
| async function addReaction(content) { |
| try { |
| await github.rest.reactions.createForIssueComment({ |
| owner: issueOwner, |
| repo: issueRepo, |
| comment_id: commentId, |
| content: content |
| }); |
| } catch (reactionError) { |
| // Log if reaction fails but don't fail the script for this |
| console.log(`Failed to add reaction '${content}': ${reactionError.message}`); |
| } |
| } |
|
|
| // Initialize outputs to a non-triggering state |
| core.setOutput('permission_granted', 'false'); |
| core.setOutput('head_sha', ''); |
| core.setOutput('pr_number_string', ''); |
|
|
| // 1. Check user permissions |
| try { |
| const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({ |
| owner: issueOwner, |
| repo: issueRepo, |
| username: commenter |
| }); |
|
|
| const allowedPermissions = ['admin', 'write', 'maintain']; |
| if (!allowedPermissions.includes(permissions.permission)) { |
| console.log(`User @${commenter} has '${permissions.permission}' permission. Needs 'admin', 'write', or 'maintain'.`); |
| await addReaction('-1'); // User does not have permission |
| return; // Exit script, tests will not be triggered |
| } |
| console.log(`User @${commenter} has '${permissions.permission}' permission.`); |
| } catch (error) { |
| console.log(`Could not verify permissions for @${commenter}: ${error.message}`); |
| await addReaction('confused'); // Error checking permissions |
| return; // Exit script |
| } |
|
|
| // 2. Fetch PR details (if permission check passed) |
| let headSha; |
| try { |
| const { data: pr } = await github.rest.pulls.get({ |
| owner: issueOwner, |
| repo: issueRepo, |
| pull_number: prNumber, |
| }); |
| headSha = pr.head.sha; |
| console.log(`Workspaced PR details: SHA - ${headSha}, PR Number - ${prNumber}`); |
|
|
| // Set outputs for the next job |
| core.setOutput('permission_granted', 'true'); |
| core.setOutput('head_sha', headSha); |
| core.setOutput('pr_number_string', prNumber.toString()); |
| await addReaction('+1'); // Command accepted, tests will be triggered |
|
|
| } catch (error) { |
| console.log(`Failed to fetch PR details for PR |
| core.setOutput('permission_granted', 'false'); // Ensure this is false if PR fetch fails |
| await addReaction('confused'); // Error fetching PR details |
| } |
|
|
| trigger_reusable_tests: |
| name: Trigger Reusable Test Workflow |
| needs: handle_comment_command |
|
|
| if: > |
| always() && |
| needs.handle_comment_command.result != 'skipped' && |
| needs.handle_comment_command.outputs.permission_granted == 'true' && |
| needs.handle_comment_command.outputs.git_ref != '' |
| uses: ./.github/workflows/test-workflows-callable.yml |
| with: |
| git_ref: ${{ needs.handle_comment_command.outputs.git_ref }} |
| secrets: inherit |
|
|