From da6d70025531dc557ce547e46094cd0baed4b363 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Wed, 6 Nov 2024 07:28:55 -0300 Subject: [PATCH] fix(repo): Verify user permissions to run integration tests (#4489) --- .changeset/famous-shoes-walk.md | 2 + .github/workflows/ci.yml | 23 +++++- .github/workflows/run-integration-tests.yml | 90 --------------------- 3 files changed, 21 insertions(+), 94 deletions(-) create mode 100644 .changeset/famous-shoes-walk.md delete mode 100644 .github/workflows/run-integration-tests.yml diff --git a/.changeset/famous-shoes-walk.md b/.changeset/famous-shoes-walk.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/famous-shoes-walk.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a29b956c3a..611d3df9de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,10 +138,6 @@ jobs: integration-tests: name: Integration Tests - # Skip for fork PRs to prevent security vulnerabilities (no secrets) - # Runs if it comes from the root repo or once it gets approved by a maintainer - if: | - github.event.inputs.run_integration_tests == 'true' || github.event.pull_request.head.repo.full_name == github.repository needs: formatting-linting runs-on: ${{ vars.RUNNER_LARGE || 'ubuntu-latest-l' }} timeout-minutes: ${{ vars.TIMEOUT_MINUTES_LONG && fromJSON(vars.TIMEOUT_MINUTES_LONG) || 15 }} @@ -163,11 +159,30 @@ jobs: next-version: '15' steps: + # Skip integration tests from fork PRs to prevent secret exfiltration + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@v2 + with: + require: write + username: ${{ github.triggering_actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.triggering_actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + echo "Job originally triggered by ${{ github.actor }}" + exit 1 + - name: Checkout Repo uses: actions/checkout@v4 with: fetch-depth: 0 show-progress: false + # We must first verify the user permissions before checking out PR code + ref: ${{ github.event.pull_request.head.sha }} - name: Setup id: config diff --git a/.github/workflows/run-integration-tests.yml b/.github/workflows/run-integration-tests.yml deleted file mode 100644 index 330c9d94b7..0000000000 --- a/.github/workflows/run-integration-tests.yml +++ /dev/null @@ -1,90 +0,0 @@ -# This workflow exists as a security measure for handling fork PRs. -# Since GitHub doesn't share repository secrets with fork PRs (for security), -# this workflow acts as a manual approval mechanism where Clerk org members can -# trigger integration tests on fork PRs by commenting '!run-integration-tests' -name: Run Integration Tests -run-name: Executed by ${{ github.actor }} - -on: - issue_comment: - types: [created] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.actor }} - cancel-in-progress: true - -jobs: - run-tests: - if: ${{ startsWith(github.event.comment.body, '!run-integration-tests') && github.repository == 'clerk/javascript' && github.event.issue.pull_request }} - runs-on: ${{ vars.RUNNER_LARGE || 'ubuntu-latest-l' }} - timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} - - permissions: - contents: read - id-token: write - - steps: - - name: Limit action to Clerk members - uses: actions/github-script@v7 - with: - result-encoding: string - retries: 3 - retry-exempt-status-codes: 400,401 - github-token: ${{ secrets.CLERK_COOKIE_PAT }} - script: | - const isMember = await github.rest.orgs.checkMembershipForUser({ - org: 'clerk', - username: context.actor - }); - if (!isMember) { - core.setFailed(`@${actor} is not a member of the Clerk organization`); - } - - - name: Checkout repo - uses: actions/checkout@v4 - with: - ref: refs/pull/${{ github.event.issue.number }}/head - - - name: Ensure the PR hasn't changed since initiating the !run-integration-tests command - uses: actions/github-script@v7 - with: - result-encoding: string - retries: 3 - retry-exempt-status-codes: 400,401 - github-token: ${{ secrets.CLERK_COOKIE_PAT }} - script: | - const commentCreated = new Date(context.payload.comment.created_at); - - const pr = await github.rest.pulls.get({ - owner: 'clerk', - repo: 'javascript', - pull_number: context.issue.number, - }); - - const prLastUpdated = new Date(pr.updated_at); - - if (prLastUpdated > commentCreated) { - core.setFailed("The PR has been updated since !run-integration-tests was initiated. Please review the changes and re-run the !run-integration-tests command."); - } - - - name: Trigger Integration Tests - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.CLERK_COOKIE_PAT }} - script: | - await github.rest.actions.createWorkflowDispatch({ - owner: 'clerk', - repo: 'javascript', - workflow_id: 'ci.yml', - ref: context.payload.pull_request.head.ref, - inputs: { - run_integration_tests: 'true' - } - }); - - - name: Update Comment - uses: peter-evans/create-or-update-comment@v3.0.0 - with: - token: ${{ secrets.CLERK_COOKIE_PAT }} - comment-id: ${{ github.event.comment.id }} - reactions: heart