Make build-approved release pending PR workflows
This commit is contained in:
1 parent
cce11a6917
commit
3628915c5d
7 files changed
+405
-8
No files matched your search
@@ -0,0 +1,46 @@
|
||||
name: Approve PR workflows
|
||||
|
||||
# A pull_request workflow cannot approve itself: GitHub can hold it before
|
||||
# any job starts. This workflow only runs trusted default-branch code and
|
||||
# releases the ordinary, unprivileged PR workflows after build approval.
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
actions: write
|
||||
|
||||
concurrency:
|
||||
group: approve-pr-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
approve:
|
||||
# Match build-pr.yml's events, including other labels applied while this
|
||||
# PR still carries build-approved: each labeled event creates a build.
|
||||
if: contains(github.event.pull_request.labels.*.name, 'build-approved')
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
# Never check out the PR head or its merge ref with this write token.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.repository.default_branch }}
|
||||
persist-credentials: false
|
||||
- id: vouch
|
||||
uses: mitchellh/vouch/action/check-user@f23dbb5e745334f97414ec70463ce7301071a661 # v1
|
||||
with:
|
||||
user: ${{ github.event.pull_request.user.login }}
|
||||
allow-fail: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Approve this PR's pending build and test runs
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
VOUCH_STATUS: ${{ steps.vouch.outputs.status }}
|
||||
with:
|
||||
script: |
|
||||
const approve = require('./.github/scripts/approve-pr-workflows.cjs');
|
||||
await approve({ github, context, core, vouchStatus: process.env.VOUCH_STATUS });
|
||||
@@ -28,8 +28,7 @@ jobs:
|
||||
# collaborators, anyone in .github/VOUCHED.td (read from the default
|
||||
# branch, so a PR cannot vouch for itself), or a PR a maintainer has
|
||||
# labelled "build-approved". Everyone else gets this job's plan output
|
||||
# and a passing `result`, which is enough for a maintainer to review
|
||||
# before deciding to spend the compute.
|
||||
# and a failing `result` until a maintainer approves the build.
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
@@ -64,6 +63,19 @@ jobs:
|
||||
allow-fail: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- id: approval
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { data: pr } = await github.rest.pulls.get({
|
||||
...context.repo, pull_number: context.payload.pull_request.number,
|
||||
});
|
||||
// Approving or rerunning a held run keeps its original event,
|
||||
// which may predate the label. Read the current approval instead.
|
||||
core.setOutput('approved', pr.state === 'open' &&
|
||||
pr.head.sha === context.payload.pull_request.head.sha &&
|
||||
pr.labels.some(label => label.name === 'build-approved'));
|
||||
# One matrix entry per package per architecture. Every package builds
|
||||
# once, against edge; the channels it ships to on merge are carried
|
||||
# along for information. A filename means one set of bytes.
|
||||
@@ -92,16 +104,17 @@ jobs:
|
||||
fi
|
||||
- id: gate
|
||||
env:
|
||||
STATUS: ${{ steps.vouch.outputs.status || 'dispatch' }}
|
||||
STATUS: ${{ github.event_name == 'workflow_dispatch' && 'dispatch' || steps.vouch.outputs.status }}
|
||||
AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
APPROVED: ${{ contains(github.event.pull_request.labels.*.name, 'build-approved') }}
|
||||
APPROVED: ${{ steps.approval.outputs.approved || 'false' }}
|
||||
PLANNED: ${{ steps.list.outputs.planned }}
|
||||
run: |
|
||||
case "$STATUS" in
|
||||
bot|collaborator|vouched|dispatch) trusted=true ;;
|
||||
# A denouncement is absolute: the label cannot override it.
|
||||
denounced) trusted=false ;;
|
||||
*) trusted=$APPROVED ;;
|
||||
unknown) trusted=$APPROVED ;;
|
||||
*) trusted=false ;;
|
||||
esac
|
||||
echo "trusted=$trusted" >> "$GITHUB_OUTPUT"
|
||||
if [[ $trusted == true ]]; then
|
||||
@@ -176,8 +189,7 @@ jobs:
|
||||
steps:
|
||||
- run: |
|
||||
echo "trusted=${{ needs.changes.outputs.trusted }} build=${{ needs.build.result }}"
|
||||
# An untrusted author's PR is held, not failed: the required check
|
||||
# stays pending until a maintainer vouches or labels it.
|
||||
# An untrusted author's PR fails until a maintainer vouches or labels it.
|
||||
if [[ "${{ needs.changes.outputs.trusted }}" != "true" ]]; then
|
||||
echo "::error::Builds were not run: author is not vouched. Add to .github/VOUCHED.td or apply the 'build-approved' label."
|
||||
exit 1
|
||||
|
||||
@@ -32,6 +32,9 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Test PR workflow approval
|
||||
run: node --test tests/pr-workflow-approval.cjs
|
||||
|
||||
# An Arch container for vercmp: version ordering has to be decided by
|
||||
# the same comparator pacman uses on users' machines.
|
||||
- name: Run self-tests
|
||||
|
||||
Reference in new issue
Block a user