diff --git a/.github/actions/create-comment/action.yml b/.github/actions/create-comment/action.yml new file mode 100644 index 000000000..5ba4bc5c9 --- /dev/null +++ b/.github/actions/create-comment/action.yml @@ -0,0 +1,152 @@ +name: Create Issue Comment +description: Create or updste an issue comment +inputs: + comment: + description: Comment Text + required: true + comment_path: + description: "Path to txt file to be parsed" + required: false + comment_id: + description: "Unique identifier for deduplicating comments" + default: "Create Issue Action" + required: false + issue_number: + description: Local Pull Request/Issue number to work on + required: true + gh_token: + description: gh api access token to use + required: true + repository: + description: the OWNER/REPOSITORY to operate on + required: true + +runs: + using: "composite" + steps: + - name: Generate Comment Text + shell: bash + env: + COMMENT_ID: ${{ inputs.comment_id }} + COMMENT_TEXT: ${{ inputs.comment }} + COMMENT_FILE: ${{ inputs.comment_path }} + run: | + comment_body="${COMMENT_TEXT}" + if [ -f "$COMMENT_FILE" ] ; then + echo "Reading comment file from ${COMMENT_FILE}" + comment_body="${comment_body}$(cat "$COMMENT_FILE")" + fi + echo "COMMENT_BODY=$comment_body" >> "$GITHUB_ENV" + + - name: Get Existing Comment Id + shell: bash + env: + GH_TOKEN: ${{ inputs.gh_token }} + ISSUE_NUMBER: ${{ inputs.issue_number }} + REPOSITORY: ${{ inputs.repository }} + COMMENT_ID: ${{ inputs.comment_id }} + run: | + owner=$(echo "$REPOSITORY" | cut -d '/' -f 1) + repo=$(echo "$REPOSITORY" | cut -d '/' -f 2) + data=$( + gh api graphql \ + --paginate \ + -f owner="$owner" \ + -f repo="$repo" \ + -F issue="$ISSUE_NUMBER" \ + -f query=' + query($repo: String!, $owner: String!, $issue: Int!, $endCursor: String) { + repository(name: $repo, owner: $owner) { + issueOrPullRequest(number: $issue) { + ... on Issue { + id + number + comments(first: 100, after: $endCursor) { + nodes { + id + body + } + pageInfo { + hasNextPage + endCursor + } + } + } + ... on PullRequest { + id + number + comments(first: 100, after: $endCursor) { + nodes { + id + body + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + } + } + ' \ + --jq '' | jq -c --arg comment_id "" ' + .[0].data.repository.issueOrPullRequest.id as $id | + [ .[].data.repository.issueOrPullRequest.comments.nodes[] ] as $data | + [ $data.[] | select(.body | startswith($comment_id)) ] as $id_comments | + if ($id_comments | length) > 0 then + { "issueId": $id, "commentId": $id_comments[0].id } + else + { "issueId": $id, "commentId": "" } + end + ' + ) + echo "ISSUE_NODE_ID=$(jq -r '.issueId' <<< "$data")" >> "$GITHUB_ENV" + echo "COMMENT_NODE_ID=$(jq -r '.commentId' <<< "$data")" >> "$GITHUB_ENV" + + - name: Edit Existing Comment + if: env.COMMENT_NODE_ID != '' + shell: bash + env: + GH_TOKEN: ${{ inputs.gh_token }} + run: | + gh api graphql \ + -f comment_id="$COMMENT_NODE_ID" \ + -f comment_body="$COMMENT_BODY" \ + -f query=' + mutation($comment_id: ID!, $comment_body: String!) { + updateIssueComment(input: { + id: $comment_id, + body: $comment_body, + }) { + issueComment { + lastEditedAt + } + } + } + ' + + - name: Create Comment + if: env.COMMENT_NODE_ID == '' + shell: bash + env: + GH_TOKEN: ${{ inputs.gh_token }} + run: | + gh api graphql \ + -f issue_id="$ISSUE_NODE_ID" \ + -f comment_body="$COMMENT_BODY" \ + -f query=' + mutation ($issue_id: ID!, $comment_body: String!) { + addComment(input: { subjectId: $issue_id, body: $comment_body }) { + commentEdge { + node { + id + } + } + } + } + ' + + + + diff --git a/.github/workflows/blocked_prs.yml b/.github/workflows/blocked_prs.yml index 6afe6e485..d12f139bc 100644 --- a/.github/workflows/blocked_prs.yml +++ b/.github/workflows/blocked_prs.yml @@ -55,13 +55,12 @@ jobs: id: dispatch_event_setup env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OWNER_REPO: ${{ github.repository }} - OWNER: ${{ github.repository_owner }} + REPOSITORY: ${{ github.repository }} PR_NUMBER: ${{ inputs.pr_id }} run: | # setup env for the rest of the workflow - owner_prefix="$OWNER/" - REPO="${OWNER_REPO#"$owner_prefix"}" + OWNER=$(echo "$REPOSITORY" | cut -d '/' -f 1) + REPO=$(echo "$REPOSITORY" | cut -d '/' -f 2) PR_JSON=$( gh api \ -H "Accept: application/vnd.github.raw+json" \ @@ -124,10 +123,11 @@ jobs: echo "prs=$PRS" >> "$GITHUB_OUTPUT" - name: Collect Blocked PR Data - id: blocked_data + id: blocking_data if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BLOCKING_PRS: ${{ steps.pr_ids.outputs.prs }} run: | BLOCKED_PR_DATA=$( while read -r pr_data ; do @@ -150,14 +150,14 @@ jobs: "baseRefName": .head.ref, } ' - done < <(jq -c '.blocking[]' <<< "${{steps.pr_ids.outputs.prs}}") | jq -c -s + done < <(jq -c '.blocking[]' <<< "$BLOCKING_PRS") | jq -c -s ) - echo "state=$BLOCKED_PR_DATA" >> "$GITHUB_OUTPUT" - echo "all_merged=$(jq 'all(.[].merged; .)' <<< "$BLOCKED_PR_DATA")" + echo "data=$BLOCKED_PR_DATA" >> "$GITHUB_OUTPUT" + echo "all_merged=$(jq -r '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.blocking_data.outputs.all_merged) continue-on-error: true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -171,7 +171,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.blocking_data.outputs.all_merged) continue-on-error: true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -188,6 +188,7 @@ jobs: continue-on-error: true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BLOCKING_DATA: ${{ steps.blocking_data.outputs.state }} run: | # label pr dependencies with 'blocking' if not already while read -r pr_data ; do @@ -200,7 +201,7 @@ jobs: "/repos/$OWNER/$REPO/issues/$pr/labels" \ -f "labels[]=blocking" fi - done < <(jq -c '.[]' <<< "${{steps.blocked_data.outputs.state}}") + done < <(jq -c '.[]' <<< "$BLOCKING_DATA") - name: Apply Blocking PR Status Check id: blocked_check @@ -208,6 +209,7 @@ jobs: continue-on-error: true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BLOCKING_DATA: ${{ steps.blocking_data.outputs.state }} run: | pr_head_sha=$(jq -r '.prHeadSha' <<< "$JOB_DATA") # create commit Status, overwrites previous identical context @@ -224,7 +226,7 @@ jobs: -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}}") + done < <(jq -c '.[]' <<< "$BLOCKING_DATA") - name: Context Comment id: blocked_comment @@ -250,9 +252,12 @@ jobs: - name: 💬 PR Comment if: fromJSON(steps.pr_ids.outputs.prs).numBlocking > 0 continue-on-error: true - uses: spicyparrot/pr-comment-action@v1.0.0 + uses: ./.github/actions/create-comment with: comment: "### PR Dependencies :pushpin:" comment_path: ${{ steps.blocked_comment.outputs.file_path }} comment_id: "block_pr_dependencies" + issue_number: ${{ env.PR_NUMBER }} + repository: ${{ github.repository }} + gh_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/merge_blocking_pr.yml b/.github/workflows/merge_blocking_pr.yml index 3123c83b3..8707dd95b 100644 --- a/.github/workflows/merge_blocking_pr.yml +++ b/.github/workflows/merge_blocking_pr.yml @@ -67,6 +67,7 @@ jobs: if: fromJSON(steps.gather_deps.outputs.numdeps) > 0 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEPS: ${{ steps.gather_deps.outputs.deps }} run: | while read -r pr ; do gh api \ @@ -76,5 +77,5 @@ jobs: "/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}}") + done < <(jq -c '.[].number' <<< "$DEPS")