diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
| commit | 31b9a8949ed0a288143e23bf739f2eb64fdc63be (patch) | |
| tree | 8a984fa143c38fccad461a77792d6864f3e82cd3 /meshmc/.github/workflows/blocked-prs.yml | |
| parent | 934382c8a1ce738589dee9ee0f14e1cec812770e (diff) | |
| parent | fad6a1066616b69d7f5fef01178efdf014c59537 (diff) | |
| download | Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.tar.gz Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.zip | |
Add 'meshmc/' from commit 'fad6a1066616b69d7f5fef01178efdf014c59537'
git-subtree-dir: meshmc
git-subtree-mainline: 934382c8a1ce738589dee9ee0f14e1cec812770e
git-subtree-split: fad6a1066616b69d7f5fef01178efdf014c59537
Diffstat (limited to 'meshmc/.github/workflows/blocked-prs.yml')
| -rw-r--r-- | meshmc/.github/workflows/blocked-prs.yml | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/meshmc/.github/workflows/blocked-prs.yml b/meshmc/.github/workflows/blocked-prs.yml new file mode 100644 index 0000000000..0010801540 --- /dev/null +++ b/meshmc/.github/workflows/blocked-prs.yml @@ -0,0 +1,257 @@ +name: Blocked/Stacked Pull Requests Automation + +on: + pull_request_target: + types: + - opened + - reopened + - edited + - synchronize + workflow_dispatch: + inputs: + pr_id: + description: Local Pull Request number to work on + required: true + type: number + +permissions: {} + +jobs: + blocked_status: + name: Check Blocked Status + runs-on: ubuntu-slim + + steps: + - name: Generate token + id: generate-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ vars.PULL_REQUEST_APP_ID }} + private-key: ${{ secrets.PULL_REQUEST_APP_PRIVATE_KEY }} + + - name: Setup From Dispatch Event + if: github.event_name == 'workflow_dispatch' + id: dispatch_event_setup + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + PR_NUMBER: ${{ inputs.pr_id }} + run: | + # setup env for the rest of the workflow + OWNER=$(dirname "${{ github.repository }}") + REPO=$(basename "${{ github.repository }}") + PR_JSON=$( + gh api \ + -H "Accept: application/vnd.github.raw+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/$OWNER/$REPO/pulls/$PR_NUMBER" + ) + echo "PR_JSON=$PR_JSON" >> "$GITHUB_ENV" + + - name: Setup Environment + id: env_setup + env: + EVENT_PR_JSON: ${{ toJSON(github.event.pull_request) }} + run: | + # setup env for the rest of the workflow + PR_JSON=${PR_JSON:-"$EVENT_PR_JSON"} + { + echo "REPO=$(jq -r '.base.repo.name' <<< "$PR_JSON")" + echo "OWNER=$(jq -r '.base.repo.owner.login' <<< "$PR_JSON")" + echo "PR_NUMBER=$(jq -r '.number' <<< "$PR_JSON")" + echo "JOB_DATA=$(jq -c ' + { + "repo": .base.repo.name, + "owner": .base.repo.owner.login, + "repoUrl": .base.repo.html_url, + "prNumber": .number, + "prHeadSha": .head.sha, + "prHeadLabel": .head.label, + "prBody": (.body // ""), + "prLabels": (reduce .labels[].name as $l ([]; . + [$l])) + } + ' <<< "$PR_JSON")" + } >> "$GITHUB_ENV" + + + - name: Find Blocked/Stacked PRs in body + id: pr_ids + run: | + prs=$( + jq -c ' + .prBody as $body + | ( + $body | + reduce ( + . | scan("[Bb]locked (?:[Bb]y|[Oo]n):? #([0-9]+)") + | map({ + "type": "Blocked on", + "number": ( . | tonumber ) + }) + ) as $i ([]; . + [$i[]]) + ) as $bprs + | ( + $body | + reduce ( + . | scan("[Ss]tacked [Oo]n:? #([0-9]+)") + | map({ + "type": "Stacked on", + "number": ( . | tonumber ) + }) + ) as $i ([]; . + [$i[]]) + ) as $sprs + | ($bprs + $sprs) as $prs + | { + "blocking": $prs, + "numBlocking": ( $prs | length), + } + ' <<< "$JOB_DATA" + ) + echo "prs=$prs" >> "$GITHUB_OUTPUT" + + - name: Collect Blocked PR Data + id: blocking_data + if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + BLOCKING_PRS: ${{ steps.pr_ids.outputs.prs }} + run: | + blocked_pr_data=$( + while read -r pr_data ; 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_data")" \ + | jq -c --arg type "$(jq -r '.type' <<< "$pr_data")" \ + ' + . | { + "type": $type, + "number": .number, + "merged": .merged, + "state": (if .state == "open" then "Open" elif .merged then "Merged" else "Closed" end), + "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[]' <<< "$BLOCKING_PRS") | jq -c -s + ) + { + echo "data=$blocked_pr_data"; + echo "all_merged=$(jq -r 'all(.[] | (.type == "Stacked on" and .merged) or (.type == "Blocked on" and (.state != "Open")); .)' <<< "$blocked_pr_data")"; + echo "current_blocking=$(jq -c 'map( + select( + (.type == "Stacked on" and (.merged | not)) or + (.type == "Blocked on" and (.state == "Open")) + ) | .number + )' <<< "$blocked_pr_data" )"; + } >> "$GITHUB_OUTPUT" + + - name: Add 'blocked' Label if Missing + id: label_blocked + if: "(fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0) && !contains(fromJSON(env.JOB_DATA).prLabels, 'status: blocked') && !fromJSON(steps.blocking_data.outputs.all_merged)" + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + gh -R ${{ github.repository }} issue edit --add-label 'status: blocked' "$PR_NUMBER" + + - name: Remove 'blocked' Label if All Dependencies Are Merged + id: unlabel_blocked + if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 && fromJSON(steps.blocking_data.outputs.all_merged) + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + gh -R ${{ github.repository }} issue edit --remove-label 'status: blocked' "$PR_NUMBER" + + - name: Apply 'blocking' Label to Unmerged Dependencies + id: label_blocking + if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + BLOCKING_ISSUES: ${{ steps.blocking_data.outputs.current_blocking }} + run: | + while read -r pr ; do + gh -R ${{ github.repository }} issue edit --add-label 'status: blocking' "$pr" || true + done < <(jq -c '.[]' <<< "$BLOCKING_ISSUES") + + - 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: ${{ steps.generate-token.outputs.token }} + BLOCKING_DATA: ${{ steps.blocking_data.outputs.data }} + run: | + pr_head_sha=$(jq -r '.prHeadSha' <<< "$JOB_DATA") + # create commit Status, overwrites previous identical context + while read -r pr_data ; do + DESC=$( + jq -r 'if .type == "Stacked on" then + "Stacked PR #" + (.number | tostring) + " is " + (if .merged then "" else "not yet " end) + "merged" + else + "Blocking PR #" + (.number | tostring) + " is " + (if .state == "Open" then "" else "not yet " end) + "merged or closed" + end ' <<< "$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 (.type == "Stacked on" and .merged) or (.type == "Blocked on" and (.state != "Open")) then "success" else "failure" end' <<< "$pr_data")" \ + -f "target_url=$(jq -r '.basePrUrl' <<< "$pr_data" )" \ + -f "description=$DESC" \ + -f "context=ci/blocking-pr-check:$(jq '.number' <<< "$pr_data")" + done < <(jq -c '.[]' <<< "$BLOCKING_DATA") + + - name: Context Comment + id: generate-comment + if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 + continue-on-error: true + env: + BLOCKING_DATA: ${{ steps.blocking_data.outputs.data }} + run: | + COMMENT_PATH="$(pwd)/temp_comment_file.txt" + echo '<h3>PR Dependencies :pushpin:</h3>' > "$COMMENT_PATH" + echo >> "$COMMENT_PATH" + pr_head_label=$(jq -r '.prHeadLabel' <<< "$JOB_DATA") + while read -r pr_data ; do + base_pr=$(jq -r '.number' <<< "$pr_data") + base_ref_name=$(jq -r '.baseRefName' <<< "$pr_data") + base_repo_owner=$(jq -r '.baseRepoOwner' <<< "$pr_data") + base_repo_name=$(jq -r '.baseRepoName' <<< "$pr_data") + compare_url="https://github.com/$base_repo_owner/$base_repo_name/compare/$base_ref_name...$pr_head_label" + status=$(jq -r ' + if .type == "Stacked on" then + if .merged then ":heavy_check_mark: Merged" else ":x: Not Merged (" + .state + ")" end + else + if .state != "Open" then ":white_check_mark: " + .state else ":x: Open" end + end + ' <<< "$pr_data") + type=$(jq -r '.type' <<< "$pr_data") + echo " - $type #$base_pr $status [(compare)]($compare_url)" >> "$COMMENT_PATH" + done < <(jq -c '.[]' <<< "$BLOCKING_DATA") + + { + echo 'body<<EOF'; + cat "${COMMENT_PATH}"; + echo 'EOF'; + } >> "$GITHUB_OUTPUT" + + - name: 💬 PR Comment + if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + COMMENT_BODY: ${{ steps.generate-comment.outputs.body }} + run: | + gh -R ${{ github.repository }} issue comment "$PR_NUMBER" \ + --body "$COMMENT_BODY" \ + --create-if-none \ + --edit-last + |
