PR review binaries link #19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR review binaries link | |
| # Posts one-click download links for the review binaries CI just built, so a | |
| # PR can be tried end-to-end before merge without a local Go toolchain. | |
| # | |
| # Why workflow_run and not a step inside CI: contributor PRs come from forks, | |
| # and fork PRs get a read-only GITHUB_TOKEN, so a comment step inside CI can't | |
| # post. workflow_run runs in the base-repo context with a writable token. | |
| # It deliberately does NOT check out or execute any PR code — it only reads | |
| # the run's metadata and comments — so the writable token never touches | |
| # untrusted input. | |
| # | |
| # Why nightly.link: GitHub has no permanent public download URL for an | |
| # artifact. The /actions/runs/<id>/artifacts/<id> endpoint needs browser | |
| # session cookies (a token gets a 404), so a plain link only works for signed-in | |
| # users, and even then only after finding the right row on the run page. | |
| # nightly.link is a third-party redirector that resolves an artifact to an | |
| # anonymous, no-login download. Public repos need no app install. | |
| on: | |
| workflow_run: | |
| workflows: [CI] | |
| types: [completed] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| comment: | |
| if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: find the PR and comment | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REPO: ${{ github.repository }} | |
| RUN_ID: ${{ github.event.workflow_run.id }} | |
| HEAD_SHA: ${{ github.event.workflow_run.head_sha }} | |
| run: | | |
| set -euo pipefail | |
| # workflow_run.pull_requests is empty for fork PRs, so resolve the | |
| # PR from the head SHA instead. | |
| pr=$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" \ | |
| --jq '[.[] | select(.state == "open")][0].number // empty') | |
| if [ -z "$pr" ]; then | |
| echo "no open PR for $HEAD_SHA; nothing to comment on" | |
| exit 0 | |
| fi | |
| # nightly.link addresses artifacts by check-suite, not run. | |
| suite=$(gh api "repos/$REPO/actions/runs/$RUN_ID" --jq '.check_suite_id') | |
| label() { | |
| case "$1" in | |
| *darwin-arm64*) echo "macOS (Apple silicon)" ;; | |
| *darwin-amd64*) echo "macOS (Intel)" ;; | |
| *linux-amd64*) echo "Linux x86_64" ;; | |
| *linux-arm64*) echo "Linux arm64" ;; | |
| *windows-amd64*) echo "Windows x86_64" ;; | |
| *) echo "$1" ;; | |
| esac | |
| } | |
| rows="" | |
| while IFS=$'\t' read -r name id; do | |
| [ -n "$name" ] || continue | |
| url="https://nightly.link/$REPO/suites/$suite/artifacts/$id" | |
| rows="${rows}| $(label "$name") | [\`${name}.zip\`]($url) |"$'\n' | |
| done < <(gh api "repos/$REPO/actions/runs/$RUN_ID/artifacts" \ | |
| --jq '.artifacts[] | [.name, .id] | @tsv' | sort) | |
| if [ -z "$rows" ]; then | |
| echo "run $RUN_ID produced no artifacts; nothing to link" | |
| exit 0 | |
| fi | |
| run_url="https://github.com/$REPO/actions/runs/$RUN_ID" | |
| body=$(cat <<EOF | |
| ### Try this PR without building it | |
| Review binaries for commit \`${HEAD_SHA:0:7}\` — direct download, no login required: | |
| | Platform | Download | | |
| |---|---| | |
| ${rows} | |
| Unzip, then on macOS/Linux \`chmod +x\` the binary before running. macOS Gatekeeper blocks unsigned binaries on first run — right-click → Open, or \`xattr -d com.apple.quarantine <file>\`. | |
| <sub>Links are resolved by [nightly.link](https://nightly.link/), a third-party redirector for GitHub Actions artifacts, because GitHub has no anonymous artifact URL of its own. Signed-in users can also [browse the run directly]($run_url#artifacts). Artifacts expire 14 days after the run. Updated on each push to this PR.</sub> | |
| EOF | |
| ) | |
| body=$(printf '%s\n' "$body" | sed 's/^ //') | |
| # Sticky: edit our previous comment rather than stacking one per push. | |
| # --edit-last fails when there's nothing to edit, so fall back to new. | |
| gh pr comment "$pr" --repo "$REPO" --edit-last --body "$body" \ | |
| || gh pr comment "$pr" --repo "$REPO" --body "$body" |