From 43b0f0d6d073d38fb56483ff68ee7626b4ae9db4 Mon Sep 17 00:00:00 2001 From: Michael Lombardi Date: Wed, 6 Apr 2022 09:54:44 -0500 Subject: [PATCH] (MAINT) Reimplement GHA for branch auth checking This commit reimplements the GitHub Action workflow for verifying that a pull request to the live branch has been submitted by a user who is authorized to do so. It replaces the default GitHub Action token with a repository secret, `VALID_BRANCH_TOKEN`, which is a PAT with the minimum permissions needed to retrieve the permissions of repository collaborators: - `repo:public_repo` - `read:org` It refactors the logic of the check itself to: 1. Replace the graphql query with a simpler endpoint query, passing the owner of the repository, the repository name, and the login of the pull request author to retrieve that user's permissions for the repo. 2. Adds an error handling check, throwing an error (and all output from the api call) if the query's exit code is non-zero. 3. Adds a null response check, throwing an error if the query does not return the permissions needed for further verification. 4. Converts the previous array membership check into simpler check on the new data form returned by the API. 5. Echoes the pull request author's current permissions for the repo into the run log to aid with debugging. --- .github/workflows/targeting-valid-branch.yml | 50 ++++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/targeting-valid-branch.yml b/.github/workflows/targeting-valid-branch.yml index 67e5bec941cf..a5890a82d847 100644 --- a/.github/workflows/targeting-valid-branch.yml +++ b/.github/workflows/targeting-valid-branch.yml @@ -13,33 +13,33 @@ jobs: shell: pwsh if: github.base_ref == 'live' steps: - - name: Authorized to Target Live Branch + - name: Authorized to Target Live Branch? env: - GITHUB_TOKEN: ${{ github.token }} + GITHUB_TOKEN: ${{ secrets.VALID_BRANCH_TOKEN }} run: | - $Query = @' - query author_collaborator_permission($owner: String!, $repo: String!, $actor: String!) { - repository(owner: $owner, name: $repo) { - collaborators(query: $actor) { - edges { - permission - } - } - } + $Owner = '${{ github.event.pull_request.base.repo.owner.login}}' + $Repo = '${{ github.event.pull_request.base.repo.name }}' + $Actor = '${{ github.event.pull_request.user.login }}' + + $ResultString = gh api repos/$Owner/$Repo/collaborators/$Actor/permission + $ExitCode = $LASTEXITCODE + if ($ExitCode -ne 0) { + throw "GitHub API call failed with exit code ${ExitCode}:`n$ResultString" } - '@ - $ApiParameters = @( - 'api', 'graphql' - '-F', "owner=${{ github.event.pull_request.base.repo.owner.login}}" - '-F', "repo=${{ github.event.pull_request.base.repo.name }}" - '-F', "actor=${{ github.event.pull_request.user.login }}" - '-f', "query=$Query" - '--jq', '.data.repository.collaborators.edges[].permission' - ) - [string[]]$Permissions = gh @ApiParameters - echo "Author '${{ github.event.pull_request.user.login }}' has permissions: '$($Permissions -join ',')'" - if ($Permissions -notcontains 'MAINTAIN' -and $Permissions -notcontains 'ADMIN') { - throw "Author does not have permissions to target ${{ github.base_ref }}" - } else { + + $Permissions = $ResultString + | ConvertFrom-Json + | Select-Object -Property @{ Name = 'Permissions' ; Expression = { $_.user.permissions } } + | Select-Object -ExpandProperty Permissions + + if ($null -eq $Permissions) { + throw "Unable to retrieve permissions for author '$Actor':`n$ResultString" + } + + echo "Author '$Actor' has permissions:`n$($Permissions | Format-List | Out-String)" + + if ($Permissions.admin -or $Permissions.maintain) { echo "Author has permissions to target ${{ github.base_ref }}" + } else { + throw "Author does not have permissions to target ${{ github.base_ref }}" }