jos*_*hlf 8 configuration branch github pull-request
我正在尝试使用以下属性配置 GitHub 项目:
main所有用户 - 包括管理员 - 都需要通过拉取请求提交代码,并且不能直接推送到main我很难同时满足第一个和第三个要求。具体来说,如果我启用“不允许绕过上述设置”设置,那么管理员就无法绕过拉取请求批准。但是,如果我禁用它,那么管理员可以直接推送到main. 有什么办法可以让我鱼与熊掌兼得吗?
以下是我对main分支的完整分支保护设置:
您可以禁用“需要批准”,然后使用 GitHub Actions 工作流程和 GitHub API 检查这两个条件之一是否为真:
并将结果作为必要的检查。
使用GitHub CLI,您可以获得用户的权限级别:$user
gh api "repos/{owner}/{repo}/collaborators/$user/permission" --jq '.permission'
Run Code Online (Sandbox Code Playgroud)
检查 PR 批准有点复杂,因为如果没有所需的批准,reviewDecision则不再填充 PR 对象中的字段。相反,我们必须查看一系列评论,并确定是否至少有一个评论者最近的无评论评论是批准的。
对于使用 ID 的评论$id,这看起来像这样:
gh pr view "$id" --json reviews --jq '
.reviews
| map(select(.state != "COMMENTED"))
| reduce .[] as $item ({}; . + {($item.author.login): $item.state})
| to_entries
| map(select(.value == "APPROVED"))
| length > 0
'
Run Code Online (Sandbox Code Playgroud)
true如果至少有一项批准,则会返回此结果。
当打开拉取请求以及提交审核时,必须触发使用这两项检查的工作流程;此外,同步 PR 可能会驳回审核,因此这也应该是一个触发器。
拉取请求触发器可以按基本分支进行过滤,但评论不能,因此我们必须单独添加此条件。
最后一个障碍是,拥有多个触发器 (pull_request和pull_request_review) 会导致多个状态检查,但我们不能同时要求它们;对于非管理员创建的 PR,pull_request检查通过后检查仍然失败pull_request_review:
为此,工作流程创建了一个单独的第三个检查,这是我们必须在分支保护规则中使用的检查。对于具有最新提交哈希$sha和结果的 PR 分支$state,用于设置状态的 GitHub CLI 命令如下所示
gh api "repos/{owner}/{repo}/statuses/$sha" \
-f "state=$state" -f context='Non-admin PR approval'
Run Code Online (Sandbox Code Playgroud)
如需其他信息,可以添加 URL,如下面的工作流程所示。所需的检查可以在“非管理员 PR 批准”下找到。
即使不满足条件,工作流程也会继续,但如果第一步确定作者是管理员,则会跳过检查 PR 批准的步骤。总体结果是使用STATE环境变量传达的,该变量在最后一步中用于设置状态。
name: Check PR approval for non-admin authors
on:
# PR into main opened, reopened, or synchronized
pull_request:
branches:
- main
# When a review is submitted
pull_request_review:
types:
- submitted
jobs:
checkapproval:
name: Check PR approval
runs-on: ubuntu-20.04
# Event has to be a pull request, or the base branch has to be main
if: >-
github.event_name == 'pull_request'
|| github.event.pull_request.base.ref == 'main'
steps:
- name: Check if author is repo admin
env:
author: ${{ github.event.pull_request.user.login }}
repo: ${{ github.repository }}
GITHUB_TOKEN: ${{ github.token }}
run: |
perm=$(gh api "repos/$repo/collaborators/$author/permission" \
--jq '.permission')
if [[ $perm != 'admin' ]]; then
echo "Author is not admin; approval required" >&2
else
echo "Author is admin; no approval required" >&2
# Set success state in environment
echo "STATE=success" >> "$GITHUB_ENV"
fi
- name: Check for PR approval
# Run only if the previous step failed
if: env.STATE != 'success'
env:
prid: ${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ github.token }}
run: |
approved=$(gh pr view "$prid" --repo "$GITHUB_REPOSITORY" \
--json reviews --jq '
.reviews
| map(select(.state != "COMMENTED"))
| reduce .[] as $item (
{}; . + {($item.author.login): $item.state}
)
| to_entries
| map(select(.value == "APPROVED"))
| length > 0
')
if [[ $approved != 'true' ]]; then
echo "No PR approval found" >&2
# Set failure state in environment
echo "STATE=failure" >> "$GITHUB_ENV"
exit 0
fi
echo "PR approval found" >&2
# Set success state in environment
echo "STATE=success" >> "$GITHUB_ENV"
- name: Set result in separate status
env:
GITHUB_TOKEN: ${{ github.token }}
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.repository }}
id: ${{ github.run_id }}
run: |
gh api "repos/$repo/statuses/$sha" \
--raw-field state="$STATE" \
--raw-field context='Non-admin PR approval' \
--raw-field target_url="https://github.com/$repo/actions/runs/$id"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3714 次 |
| 最近记录: |