Files
prismlauncher-crack/.github/workflows/blocked_prs.yml
2025-03-12 20:44:03 -07:00

245 lines
9.5 KiB
YAML

name: Blocked/Stacked Pull Requests Automation
on:
pull_request_target:
types:
- opened
- edited
workflow_dispatch:
inputs:
pr_id:
description: Local Pull Request number to work on
required: true
type: number
jobs:
blocked_status:
name: Check Blocked Status
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
statuses: write
checks: write
steps:
- name: Setup From Pull Request Event
if: github.event_name != 'workflow_dispatch'
id: pr_event_setup
env:
REPO_L: ${{ github.event.pull_request.base.repo.name }}
OWNER_L: ${{ github.event.pull_request.base.repo.owner.login }}
REPO_URL_L: $ {{ github.event.pull_request.base.repo.html_url }}
PR_HEAD_SHA_L: ${{ github.event.pull_request.head.sha }}
PR_NUMBER_L: ${{ github.event.pull_request.number }}
PR_HEAD_LABEL_L: ${{ github.event.pull_request.head.label }}
PR_BODY_L: ${{ github.event.pull_request.body }}
PR_LABLES_L: "${{ github.event.pull_request.labels }}"
run: |
# setup env for the rest of the workflow
{
echo "REPO=$REPO_L"
echo "OWNER=$OWNER_L"
echo "REPO_URL=$REPO_URL_L"
echo "PR_NUMBER=$PR_NUMBER_L"
echo "PR_HEAD_SHA=$PR_HEAD_SHA_L"
echo "PR_HEAD_LABEL=$PR_HEAD_LABEL_L"
echo "PR_BODY=$PR_BODY_L"
echo "PR_LABELS=$(jq 'reduce .[].name as $l ([]; . + [$l])' <<< "$PR_LABELS_L" )"
} >> "$GITHUB_ENV"
- name: Setup From Dispatch Event
if: github.event_name == 'workflow_dispatch'
id: dispatch_event_setup
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER_REPO_L: ${{ github.repository }}
OWNER_L: ${{ github.repository_owner }}
REPO_URL_L: $ {{ github.repositoryUrl }}
PR_NUMBER_L: ${{ inputs.pr_id }}
run: |
# setup env for the rest of the workflow
owner_prefix="$OWNER_L/"
REPO_L="${OWNER_REPO_L#"$owner_prefix"}"
PR_L=$(
gh api \
-H "Accept: application/vnd.github.text+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER_L/$REPO_L/pulls/$PR_NUMBER_L"
)
PR_HEAD_SHA_L=$(jq -r '.head.sha' <<< "$PR_L")
PR_HEAD_LABEL_L=$(jq -r '.head.label' <<< "$PR_L")
PR_BODY_L=$(jq -r '.body_text' <<< "$PR_L")
PR_LABELS_L=$(jq '.labels' <<< "$PR_L")
{
echo "REPO=$REPO_L"
echo "OWNER=$OWNER_L"
echo "REPO_URL=$REPO_URL_L"
echo "PR_NUMBER=$PR_NUMBER_L"
echo "PR_HEAD_SHA=$PR_HEAD_SHA_L"
echo "PR_HEAD_LABEL=$PR_HEAD_LABEL_L"
echo "PR_BODY=$PR_BODY_L"
echo "PR_LABELS=$(jq 'reduce .[].name as $l ([]; . + [$l])' <<< "$PR_LABELS_L" )"
} >> "$GITHUB_ENV"
- name: Find Blocked/Stacked PRs in body
id: pr_ids
run: |
PRS=$(
jq '
. as $body
| (
$body | scan("blocked (?(?by)|(?on)):? #(?<num>[0-9]+)")
| map({
"type": "Blocked on",
"number": ( . | tonumber )
})
) as $bprs
| (
$body | scan("stacked on:? #(?<num>[0-9]+)")
| map({
"type": "Stacked on",
"number": ( . | tonumber )
})
) as $sprs
| ($bprs + $sprs) as $prs
| {
"blocking": $prs,
"numBlocking": ( $prs | length),
}
' <<< "$PR_BODY"
)
echo "prs=$PRS" >> "$GITHUB_OUTPUT"
- name: Collect Blocked PR Data
id: blocked_data
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BLOCKED_PR_DATA=$(
while read -r PR ; do
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/pulls/$(jq -r '.number' <<< "$PR")" \
| jq --arg type "$(jq -r '.type' <<< "$PR")" \
'
. | {
"type": $type,
"number": .number,
"merged": .merged,
"labels": (reduce .labels[].name as $l ([]; . + [$l])),
"basePrUrl": .html_url,
"baseRepoName": .head.repo.name,
"baseRepoOwner": .head.repo.owner.login,
"baseRepoUrl": .head.repo.html_url,
"baseSha": .head.sha,
"baseRefName": .head.ref,
}
'
done < <(jq -c '.blocking[]' <<< "${{steps.pr_ids.outputs.prs}}") | jq -s
)
echo "state=$BLOCKED_PR_DATA" >> "$GITHUB_OUTPUT"
echo "all_merged=$(jq 'all(.[].merged; .)' <<< "$BLOCKED_PR_DATA")"
- name: Apply Blocked Label if Missing
id: label_blocked
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && !contains(fromJSON(env.PR_LABELS), 'blocked') && !fromJSON(steps.blocked_data.outputs.all_merged)
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/issues/$PR_NUMBER/labels" \
-f "labels[]=blocked"
- name: Remove 'blocked' Label if All Dependencies Are Merged
id: unlabel_blocked
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && fromJSON(steps.blocked_data.outputs.all_merged)
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/issues/$PR_NUMBER/labels/blocked"
- name: Apply 'blocking' Label to Dependencies if Missing
id: label_blocking
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# label pr dependencies with 'blocking' if not already
while read -r PR_DATA ; do
if jq -e 'all(.labels[]; . != "blocking")' <<< "$PR_DATA" > /dev/null ; then
PR=$(jq -r '.number' <<< "$PR_DATA")
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/issues/$PR/labels" \
-f "labels[]=blocking"
fi
done < <(jq -c '.[]' <<< "${{steps.blocked_data.outputs.state}}")
- name: Apply Blocking PR Status Check
id: blocked_check
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# create commit Status, overwrites previous identical context
while read -r PR_DATA ; do
DESC=$(
jq -r ' "Blocking PR #" + (.number | tostring) + " is " + (if .merged then "" else "not yet " end) + "merged"' <<< "$PR_DATA"
)
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${OWNER}/${REPO}/statuses/${PR_HEAD_SHA}" \
-f "state=$(jq -r 'if .merged then "success" else "failure" end' <<< "$PR_DATA")" \
-f "target_url=$(jq -r '.basePrUrl' <<< "$PR_DATA" )" \
-f "description=$DESC" \
-f "context=continuous-integration/blocked-pr-check:$(jq '.number' <<< "$PR_DATA")"
done < <(jq -c '.[]' <<< "${{steps.blocked_data.outputs.state}}")
- name: Context Comment
id: blocked_comment
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true
run: |
COMMENT_PATH="$(pwd)/temp_comment_file.txt"
touch "$COMMENT_PATH"
echo "" > "$COMMENT_PATH"
while read -r PR_DATA ; do
BASE_PR=$(jq '.number' <<< "$PR_DATA")
BASE_REF_NAME=$(jq '.baseRefName' <<< "$PR_DATA")
COMPARE_URL="$REPO_URL/compare/$BASE_REF_NAME...$PR_HEAD_LABEL"
STATUS=$(jq 'if .merged then ":heavy_check_mark: Merged" else ":x: Not Merged" end' <<< "$PR_DATA")
TYPE=$(jq -r '.type' <<< "$PR_DATA")
echo " - $TYPE #$BASE_PR $STATUS [(compare)]($COMPARE_URL)" >> "$COMMENT_PATH"
done < <(jq -c '.[]' <<< "${{steps.blocked_data.outputs.state}}")
echo "file_path=${COMMENT_PATH}" >> "$GITHUB_OUTPUT"
- name: 💬 PR Comment
if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true
uses: spicyparrot/pr-comment-action@v1.0.0
with:
comment: "### PR Dependencies :pushpin:"
comment_path: ${{ steps.blocked_comment.outputs.file_path }}
comment_id: "block_pr_dependencies"