ci: add workflow to trigger refresh of dependants when a blocking pr is merged

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2025-03-11 20:19:03 -07:00
parent a65ced1598
commit be1ce8dd9d
No known key found for this signature in database
GPG Key ID: E10E321EB160949B
2 changed files with 104 additions and 16 deletions

View File

@ -13,12 +13,19 @@ on:
type: number type: number
jobs: jobs:
block_status: blocked_status:
name: Check Blocked Status name: Check Blocked Status
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
statuses: write
checks: write
steps: steps:
- name: Setup From Pull Request Vent - name: Setup From Pull Request Vent
if: ${{ github.event_name != 'workflow_dispatch' }} if: github.event_name != 'workflow_dispatch'
id: pr_event_setup id: pr_event_setup
env: env:
REPO_L: ${{ github.event.pull_request.base.repo.name }} REPO_L: ${{ github.event.pull_request.base.repo.name }}
@ -43,7 +50,7 @@ jobs:
} >> "$GITHUB_ENV" } >> "$GITHUB_ENV"
- name: Setup From Dispatch Event - name: Setup From Dispatch Event
if: ${{ github.event_name == 'workflow_dispatch' }} if: github.event_name == 'workflow_dispatch'
id: dispatch_event_setup id: dispatch_event_setup
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -57,13 +64,13 @@ jobs:
REPO_L="${OWNER_REPO_L#"$owner_prefix"}" REPO_L="${OWNER_REPO_L#"$owner_prefix"}"
PR_L=$( PR_L=$(
gh api \ gh api \
-H "Accept: application/vnd.github.raw+json" \ -H "Accept: application/vnd.github.text+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \ -H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER_L/$REPO_L/pulls/$PR_NUMBER_L" "/repos/$OWNER_L/$REPO_L/pulls/$PR_NUMBER_L"
) )
PR_HEAD_SHA_L=$(jq -r '.head.sha' <<< "$PR_L") PR_HEAD_SHA_L=$(jq -r '.head.sha' <<< "$PR_L")
PR_HEAD_LABEL_L=$(jq -r '.head.label' <<< "$PR_L") PR_HEAD_LABEL_L=$(jq -r '.head.label' <<< "$PR_L")
PR_BODY_L=$(jq -r '.body' <<< "$PR_L") PR_BODY_L=$(jq -r '.body_text' <<< "$PR_L")
PR_LABELS_L=$(jq '.labels' <<< "$PR_L") PR_LABELS_L=$(jq '.labels' <<< "$PR_L")
{ {
echo "REPO=$REPO_L" echo "REPO=$REPO_L"
@ -84,7 +91,7 @@ jobs:
jq ' jq '
. as $body . as $body
| ( | (
$body | scan("blocked (?by)|(?on):? #(?<num>[0-9]+)") $body | scan("blocked (?(?by)|(?on)):? #(?<num>[0-9]+)")
| map({ | map({
"type": "Blocked on", "type": "Blocked on",
"number": ( . | tonumber ) "number": ( . | tonumber )
@ -104,18 +111,18 @@ jobs:
} }
' <<< "$PR_BODY" ' <<< "$PR_BODY"
) )
echo "prs=$PRS" >> "$GITHUB_OUPUT" echo "prs=$PRS" >> "$GITHUB_OUTPUT"
- name: Collect Blocked PR Data - name: Collect Blocked PR Data
id: blocked_data id: blocked_data
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
BLOCKED_PR_DATA=$( BLOCKED_PR_DATA=$(
while read -r PR ; do while read -r PR ; do
gh api \ gh api \
-H "Accept: application/vnd.github.raw+json" \ -H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \ -H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/pulls/$(jq -r '.number' <<< "$PR")" \ "/repos/$OWNER/$REPO/pulls/$(jq -r '.number' <<< "$PR")" \
| jq --arg type "$(jq -r '.type' <<< "$PR")" \ | jq --arg type "$(jq -r '.type' <<< "$PR")" \
@ -135,12 +142,12 @@ jobs:
' '
done < <(jq -c '.blocking[]' <<< "${{steps.pr_ids.outputs.prs}}") | jq -s done < <(jq -c '.blocking[]' <<< "${{steps.pr_ids.outputs.prs}}") | jq -s
) )
echo "state=$BLOCKED_PR_DATA" >> "$GITHUB_OUPUT" echo "state=$BLOCKED_PR_DATA" >> "$GITHUB_OUTPUT"
echo "all_merged=$(jq 'all(.[].merged; .)' <<< "$BLOCKED_PR_DATA")" echo "all_merged=$(jq 'all(.[].merged; .)' <<< "$BLOCKED_PR_DATA")"
- name: Apply Blocked Label if Missing - name: Apply Blocked Label if Missing
id: label_blocked 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) }} 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 continue-on-error: true
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -154,7 +161,7 @@ jobs:
- name: Remove 'blocked' Label if All Dependencies Are Merged - name: Remove 'blocked' Label if All Dependencies Are Merged
id: unlabel_blocked id: unlabel_blocked
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && fromJSON(steps.blocked_data.outputs.all_merged) }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && fromJSON(steps.blocked_data.outputs.all_merged)
continue-on-error: true continue-on-error: true
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -167,7 +174,7 @@ jobs:
- name: Apply 'blocking' Label to Dependencies if Missing - name: Apply 'blocking' Label to Dependencies if Missing
id: label_blocking id: label_blocking
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true continue-on-error: true
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -187,7 +194,7 @@ jobs:
- name: Apply Blocking PR Status Check - name: Apply Blocking PR Status Check
id: blocked_check id: blocked_check
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true continue-on-error: true
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -210,7 +217,7 @@ jobs:
- name: Context Comment - name: Context Comment
id: blocked_comment id: blocked_comment
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true continue-on-error: true
run: | run: |
COMMENT_PATH="$(pwd)/temp_comment_file.txt" COMMENT_PATH="$(pwd)/temp_comment_file.txt"
@ -227,10 +234,11 @@ jobs:
echo "file_path=${COMMENT_PATH}" >> "$GITHUB_OUTPUT" echo "file_path=${COMMENT_PATH}" >> "$GITHUB_OUTPUT"
- name: 💬 PR Comment - name: 💬 PR Comment
if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0
continue-on-error: true continue-on-error: true
uses: spicyparrot/pr-comment-action@v1.0.0 uses: spicyparrot/pr-comment-action@v1.0.0
with: with:
comment: "### PR Dependencies :pushpin:" comment: "### PR Dependencies :pushpin:"
comment_path: ${{ steps.blocked_comment.outputs.file_path }} comment_path: ${{ steps.blocked_comment.outputs.file_path }}
comment_id: "block_pr_dependencies" comment_id: "block_pr_dependencies"

80
.github/workflows/merge_blocking_pr.yml vendored Normal file
View File

@ -0,0 +1,80 @@
name: Merged Blocking Pull Request Automation
on:
pull_request:
types:
- closed
jobs:
update_blocked_status:
name: Update Blocked Status
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
permissions:
issues: write
pull-requests: write
statuses: write
checks: write
steps:
- name: Gather Dependent PRs
id: gather_deps
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
owner="${{ github.repository_owner }}"
owner_repo="${{ github.repository }}"
repo="${owner_repo#"${owner}/"}"
blocked_prs=$(
gh api graphql \
-f repo="$repo" \
-f owner="$owner" \
-f query='
query($repo: String!, $owner: String!, $endCursor: String) {
repository(name: $repo, owner: $owner) {
pullRequests(first: 100, after: $endCursor, states: [OPEN], labels: ["blocked"]) {
nodes {
number
bodyText
merged
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
' \
--paginate \
--slurp \
| jq --argjson pr "${{ github.event.pull_request.number }}" '
[.[].data.repository.pullRequests.nodes[]] | .[] | select(
.bodyText |
scan("(?:blocked (?:by|on)|stacked on):? #(?<num>[0-9]+)") |
map(tonumber) |
any(.[]; . == $pr)
)
'
)
echo "deps=$blocked_prs" >> "$GITHUB_OUTPUT"
echo "numdeps='$(jq -r '. | length' <<< "$blocked_prs")"
- name: Trigger Blocked PP Workflows for Dependants
if: fromJSON(steps.gather_deps.outputs.numdeps) > 0
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
while read -r pr ; do
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${{ github.repository }}/actions/workflows/blocked_prs.yml/dispatches" \
-f "ref=${{ github.ref_name }}" \
-f "inputs[pr_id]=$pr"
done < <(jq -c '.[].number' <<< "${{steps.gather_deps.outputs.deps}}")