From be1ce8dd9d0612559560a03c4e70f667430de939 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 11 Mar 2025 20:19:03 -0700 Subject: [PATCH] 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> --- .github/workflows/blocked_prs.yml | 40 ++++++++----- .github/workflows/merge_blocking_pr.yml | 80 +++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/merge_blocking_pr.yml diff --git a/.github/workflows/blocked_prs.yml b/.github/workflows/blocked_prs.yml index 8f060dbb6..ecafc65a8 100644 --- a/.github/workflows/blocked_prs.yml +++ b/.github/workflows/blocked_prs.yml @@ -13,12 +13,19 @@ on: type: number jobs: - block_status: + 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 Vent - if: ${{ github.event_name != 'workflow_dispatch' }} + if: github.event_name != 'workflow_dispatch' id: pr_event_setup env: REPO_L: ${{ github.event.pull_request.base.repo.name }} @@ -43,7 +50,7 @@ jobs: } >> "$GITHUB_ENV" - name: Setup From Dispatch Event - if: ${{ github.event_name == 'workflow_dispatch' }} + if: github.event_name == 'workflow_dispatch' id: dispatch_event_setup env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -57,13 +64,13 @@ jobs: REPO_L="${OWNER_REPO_L#"$owner_prefix"}" PR_L=$( gh api \ - -H "Accept: application/vnd.github.raw+json" \ + -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' <<< "$PR_L") + PR_BODY_L=$(jq -r '.body_text' <<< "$PR_L") PR_LABELS_L=$(jq '.labels' <<< "$PR_L") { echo "REPO=$REPO_L" @@ -84,7 +91,7 @@ jobs: jq ' . as $body | ( - $body | scan("blocked (?by)|(?on):? #(?[0-9]+)") + $body | scan("blocked (?(?by)|(?on)):? #(?[0-9]+)") | map({ "type": "Blocked on", "number": ( . | tonumber ) @@ -104,18 +111,18 @@ jobs: } ' <<< "$PR_BODY" ) - echo "prs=$PRS" >> "$GITHUB_OUPUT" + echo "prs=$PRS" >> "$GITHUB_OUTPUT" - name: Collect Blocked PR Data id: blocked_data - if: ${{ fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 }} + 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.raw+json" \ + -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")" \ @@ -135,12 +142,12 @@ jobs: ' 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")" - 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) }} + 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 }} @@ -154,7 +161,7 @@ jobs: - 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) }} + 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 }} @@ -167,7 +174,7 @@ jobs: - name: Apply 'blocking' Label to Dependencies if Missing 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 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -187,7 +194,7 @@ jobs: - name: Apply Blocking PR Status 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 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -210,7 +217,7 @@ jobs: - name: Context 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 run: | COMMENT_PATH="$(pwd)/temp_comment_file.txt" @@ -227,10 +234,11 @@ jobs: echo "file_path=${COMMENT_PATH}" >> "$GITHUB_OUTPUT" - 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 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" + diff --git a/.github/workflows/merge_blocking_pr.yml b/.github/workflows/merge_blocking_pr.yml new file mode 100644 index 000000000..fd52da295 --- /dev/null +++ b/.github/workflows/merge_blocking_pr.yml @@ -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):? #(?[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}}") +