Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/close-invalid-pr-writer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Close invalid PR writer

on:
workflow_run:
workflows: [Close issue/PR on adding invalid label]
types: [completed]
# pull_request does not run for conflicted PRs, so reconcile from the trusted default branch.
schedule:
- cron: '*/5 * * * *'
workflow_dispatch:

permissions: {}

jobs:
close-invalid-pr-from-workflow-run:
if: >
github.repository == 'github/copilot-cli' &&
github.event_name == 'workflow_run' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.repository.full_name == github.repository
Comment thread
Copilot marked this conversation as resolved.
runs-on: ubuntu-latest
permissions:
actions: read
pull-requests: write
concurrency:
group: close-invalid-pr-${{ github.event.workflow_run.pull_requests[0].number || github.run_id }}
cancel-in-progress: false
steps:
- name: Close invalid PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
run: |
set -euo pipefail

trusted_workflow_id="$(gh api "repos/$GH_REPO/actions/workflows/close-invalid.yml" --jq .id)"
workflow_run="$(gh api "repos/$GH_REPO/actions/runs/$WORKFLOW_RUN_ID")"

if [ "$(jq -r .workflow_id <<<"$workflow_run")" != "$trusted_workflow_id" ] ||
[ "$(jq -r .event <<<"$workflow_run")" != "pull_request" ] ||
[ "$(jq -r .repository.full_name <<<"$workflow_run")" != "$GH_REPO" ]; then
echo "Workflow run is not a trusted pull_request run from $GH_REPO; skipping."
exit 0
fi

if [ "$(jq '.pull_requests | length' <<<"$workflow_run")" -ne 1 ]; then
echo "Workflow run is not associated with exactly one PR; skipping."
exit 0
fi

pr_number="$(jq -r .pull_requests[0].number <<<"$workflow_run")"
run_head_sha="$(jq -r .head_sha <<<"$workflow_run")"
run_head_repo="$(jq -r '.head_repository.full_name // empty' <<<"$workflow_run")"
pr="$(gh api "repos/$GH_REPO/pulls/$pr_number")"

if [ -z "$run_head_repo" ] ||
[ "$(jq -r .base.repo.full_name <<<"$pr")" != "$GH_REPO" ] ||
[ "$(jq -r '.head.repo.full_name // empty' <<<"$pr")" != "$run_head_repo" ] ||
[ "$(jq -r .head.sha <<<"$pr")" != "$run_head_sha" ]; then
echo "PR #$pr_number no longer matches the workflow run head; skipping."
exit 0
fi

if [ "$(jq -r .state <<<"$pr")" != "open" ] ||
! jq -e 'any(.labels[]?; .name == "invalid")' >/dev/null <<<"$pr"; then
echo "PR #$pr_number is not open with the invalid label; skipping."
exit 0
fi

gh api -X PATCH "repos/$GH_REPO/pulls/$pr_number" -f state=closed

reconcile-invalid-prs:
if: >
github.repository == 'github/copilot-cli' &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
permissions:
pull-requests: write
concurrency:
group: close-invalid-pr-reconciliation
cancel-in-progress: false
steps:
- name: Close open PRs with the invalid label
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail

gh api --paginate "repos/$GH_REPO/pulls?state=open&per_page=100" \
--jq '.[] | select(any(.labels[]?; .name == "invalid")) | .number' |
while read -r pr_number; do
pr="$(gh api "repos/$GH_REPO/pulls/$pr_number")"

if [ "$(jq -r .state <<<"$pr")" = "open" ] &&
jq -e 'any(.labels[]?; .name == "invalid")' >/dev/null <<<"$pr"; then
gh api -X PATCH "repos/$GH_REPO/pulls/$pr_number" -f state=closed
fi
done
46 changes: 26 additions & 20 deletions .github/workflows/close-invalid.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
name: Close issue/PR on adding invalid label

# **What it does**: This action closes issues that are labeled as invalid in the repo.
# **What it does**: This action closes invalid issues and signals invalid PRs to a trusted writer.

on:
issues:
types: [labeled]
pull_request_target:
pull_request:
Comment thread
mrecachinas marked this conversation as resolved.
types: [labeled]

permissions:
contents: read
issues: write
pull-requests: write
permissions: {}

jobs:
close-on-adding-invalid-label:
if:
github.repository == 'github/copilot-cli' && github.event.label.name ==
'invalid'
close-issue-on-adding-invalid-label:
if: >
github.repository == 'github/copilot-cli' &&
github.event_name == 'issues' &&
github.event.label.name == 'invalid'
runs-on: ubuntu-latest

permissions:
issues: write
steps:
- name: Close issue
if: ${{ github.event_name == 'issues' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
URL: ${{ github.event.issue.html_url }}
run: gh issue close $URL
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPOSITORY: ${{ github.repository }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: gh api -X PATCH "repos/$GH_REPOSITORY/issues/$ISSUE_NUMBER" -f state=closed

- name: Close PR
if: ${{ github.event_name == 'pull_request_target' }}
signal-invalid-pr-label:
if: >
github.repository == 'github/copilot-cli' &&
github.event_name == 'pull_request' &&
github.event.label.name == 'invalid'
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Record invalid PR label signal
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
URL: ${{ github.event.pull_request.html_url }}
run: gh pr close $URL
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo "Invalid label signal for PR #$PR_NUMBER"