ci/get-merge-commit.sh: Add documentation

And distinguish exit codes
This commit is contained in:
Silvan Mosberger 2024-10-10 20:40:46 +02:00
parent 048f4aa537
commit e6a8855a14
2 changed files with 59 additions and 5 deletions

View File

@ -41,3 +41,58 @@ Why not just build the tooling right from the PRs Nixpkgs version?
- Because it improves security, since we don't have to build potentially untrusted code from PRs. - Because it improves security, since we don't have to build potentially untrusted code from PRs.
The tool only needs a very minimal Nix evaluation at runtime, which can work with [readonly-mode](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-readonly-mode) and [restrict-eval](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-restrict-eval). The tool only needs a very minimal Nix evaluation at runtime, which can work with [readonly-mode](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-readonly-mode) and [restrict-eval](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-restrict-eval).
## `get-merge-commit.sh GITHUB_REPO PR_NUMBER`
Check whether a PR is mergeable and return the test merge commit as
[computed by GitHub](https://docs.github.com/en/rest/guides/using-the-rest-api-to-interact-with-your-git-database?apiVersion=2022-11-28#checking-mergeability-of-pull-requests).
Arguments:
- `GITHUB_REPO`: The repository of the PR, e.g. `NixOS/nixpkgs`
- `PR_NUMBER`: The PR number, e.g. `1234`
Exit codes:
- 0: The PR can be merged, the test merge commit hash is returned on stdout
- 1: The PR cannot be merged because it's not open anymore
- 2: The PR cannot be merged because it has a merge conflict
- 3: The merge commit isn't being computed, GitHub is likely having internal issues, unknown if the PR is mergeable
### Usage
This script can be used in GitHub Actions workflows as follows:
```yaml
on: pull_request_target
# We need a token to query the API, but it doesn't need any special permissions
permissions: {}
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
# Important: Because of `pull_request_target`, this doesn't check out the PR,
# but rather the base branch of the PR, which is needed so we don't run untrusted code
- uses: actions/checkout@<VERSION>
with:
path: base
sparse-checkout: ci
- name: Resolving the merge commit
env:
GH_TOKEN: ${{ github.token }}
run: |
if mergedSha=$(base/ci/get-merge-commit.sh ${{ github.repository }} ${{ github.event.number }}); then
echo "Checking the merge commit $mergedSha"
echo "mergedSha=$mergedSha" >> "$GITHUB_ENV"
else
# Skipping so that no notifications are sent
echo "Skipping the rest..."
fi
rm -rf base
- uses: actions/checkout@<VERSION>
# Add this to _all_ subsequent steps to skip them
if: env.mergedSha
with:
ref: ${{ env.mergedSha }}
- ...
```

View File

@ -1,6 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# This checks for mergeability of a pull request as recommended in # See ./README.md for docs
# https://docs.github.com/en/rest/guides/using-the-rest-api-to-interact-with-your-git-database?apiVersion=2022-11-28#checking-mergeability-of-pull-requests
set -euo pipefail set -euo pipefail
@ -31,14 +30,14 @@ while true; do
state=$(jq -r .state <<< "$prInfo") state=$(jq -r .state <<< "$prInfo")
if [[ "$state" != open ]]; then if [[ "$state" != open ]]; then
log "PR is not open anymore" log "PR is not open anymore"
exit 2 exit 1
fi fi
mergeable=$(jq -r .mergeable <<< "$prInfo") mergeable=$(jq -r .mergeable <<< "$prInfo")
if [[ "$mergeable" == "null" ]]; then if [[ "$mergeable" == "null" ]]; then
if (( retryCount == 0 )); then if (( retryCount == 0 )); then
log "Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com/" log "Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com/"
exit 1 exit 3
else else
(( retryCount -= 1 )) || true (( retryCount -= 1 )) || true
@ -59,5 +58,5 @@ if [[ "$mergeable" == "true" ]]; then
jq -r .merge_commit_sha <<< "$prInfo" jq -r .merge_commit_sha <<< "$prInfo"
else else
log "The PR has a merge conflict" log "The PR has a merge conflict"
exit 1 exit 2
fi fi