From c58d91ec60083c076b658926da106fb0c87202d7 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:21:04 -0500 Subject: [PATCH 01/21] create pr review bot --- .github/workflows/pr_review_bot.yaml | 37 ++++++++++++++++++++ scripts/review_bot.py | 50 ++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 .github/workflows/pr_review_bot.yaml create mode 100644 scripts/review_bot.py diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml new file mode 100644 index 00000000000000..8ab09b795d9f83 --- /dev/null +++ b/.github/workflows/pr_review_bot.yaml @@ -0,0 +1,37 @@ +name: Bot Review + +on: + pull_request: + types: + - opened +jobs: + bot_review: + runs-on: ubuntu-latest + + steps: + - name: Install GitHub CLI + run: sudo apt-get install gh + + - name: Add bot-review Label + run: gh pr edit ${{ github.event.number }} --add-label bot-review + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Set Up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install Dependencies + run: pip install frontmatter + + - name: Run Bot Review + run: python scripts/review_bot.py "${{ github.event_path }}" + + - name: Remove bot-review Label + if: success() + run: gh pr edit ${{ github.event.number }} --remove-label bot-review + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/review_bot.py b/scripts/review_bot.py new file mode 100644 index 00000000000000..6ed0eb232bcc42 --- /dev/null +++ b/scripts/review_bot.py @@ -0,0 +1,50 @@ + +import sys +import json +import re + +# Read the file passed in as first arg +def get_pr_body(): + with open(sys.argv[1], 'r') as file: + event_payload = json.load(file) + return event_payload["pull_request"]["body"] + +# Read template file +def read_template_file(): + template_file_path = ".github/pull_request_template.md" + with open(template_file_path, 'r') as template_file: + combined_templates = template_file.read() + return combined_templates + +# Separate out each template +template_separator = re.compile(r"", re.DOTALL) +def separate_templates(combined_templates): + matches = template_separator.findall(combined_templates) + for (name,content) in matches: + yield name,content + +# Find fields in a template or pull request. They look like **field name** +field_finder = re.compile(r"\*{2}(.+?)\*{2}") +def find_field_set(content): + return set(field_finder.findall(content)) + +if __name__ == "__main__": + pr_body = get_pr_body() + fields_in_pr_body = find_field_set(pr_body) + combined_templates = read_template_file() + templates = separate_templates(combined_templates) + + # Calculate which templates match + possible_template_matches = [] + for template_name,template_content in templates: + required_fields = find_field_set(template_content) + if fields_in_pr_body.issuperset(required_fields): + possible_template_matches.append(template_name) + + # Return results + if len(possible_template_matches) > 0: + print("PR matches template(s): ",", ".join(possible_template_matches)) + sys.exit(0) # Pass + else: + print("PR does not match any known templates") + sys.exit(1) # Fail From 055a76df093a4b3056e006638972565a516792d3 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:22:06 -0500 Subject: [PATCH 02/21] made executable --- scripts/review_bot.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/review_bot.py diff --git a/scripts/review_bot.py b/scripts/review_bot.py old mode 100644 new mode 100755 From 263ad266cf4ce16d5d8fbd3a5240b61cdc002263 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:23:02 -0500 Subject: [PATCH 03/21] added sleep for testing labels --- scripts/review_bot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 6ed0eb232bcc42..67011468c3bf74 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -2,6 +2,7 @@ import sys import json import re +import time # Read the file passed in as first arg def get_pr_body(): @@ -41,6 +42,7 @@ def find_field_set(content): if fields_in_pr_body.issuperset(required_fields): possible_template_matches.append(template_name) + time.sleep(20) # Return results if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) From d7550082550c13135548f1f6e2190c764de9c633 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:43:19 -0500 Subject: [PATCH 04/21] updated script to handle labels --- .github/workflows/pr_review_bot.yaml | 20 +++++--------------- scripts/review_bot.py | 24 ++++++++++++++++++------ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 8ab09b795d9f83..497a8d8388087c 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -8,15 +8,10 @@ jobs: bot_review: runs-on: ubuntu-latest - steps: - - name: Install GitHub CLI - run: sudo apt-get install gh - - - name: Add bot-review Label - run: gh pr edit ${{ github.event.number }} --add-label bot-review - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: - name: Checkout Repository uses: actions/checkout@v2 @@ -24,14 +19,9 @@ jobs: uses: actions/setup-python@v2 with: python-version: 3.8 + - name: Install Dependencies - run: pip install frontmatter + run: pip install PyGithub - name: Run Bot Review run: python scripts/review_bot.py "${{ github.event_path }}" - - - name: Remove bot-review Label - if: success() - run: gh pr edit ${{ github.event.number }} --remove-label bot-review - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 67011468c3bf74..d33d3a9deb414a 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -2,13 +2,16 @@ import sys import json import re +from github import Github import time -# Read the file passed in as first arg -def get_pr_body(): +BOT_REVIEW_LABEL = "bot-review" + +# Read the pr event file, which is passed in as first arg +def read_pr_event(): with open(sys.argv[1], 'r') as file: event_payload = json.load(file) - return event_payload["pull_request"]["body"] + return event_payload # Read template file def read_template_file(): @@ -30,10 +33,18 @@ def find_field_set(content): return set(field_finder.findall(content)) if __name__ == "__main__": - pr_body = get_pr_body() - fields_in_pr_body = find_field_set(pr_body) + g = Github(os.environ['GITHUB_TOKEN']) + + pr_event = read_pr_event() + repo_name = pr_event['repository']['full_name'] + pr_number = pr_event['pull_request']['number'] + pr_body = pr_event["pull_request"]["body"] + pr = g.get_repo(repo_name).get_pull(pr_number) + pr.add_to_labels(BOT_REVIEW_LABEL) + + fields_in_pr_body = find_field_set(pr_body) combined_templates = read_template_file() - templates = separate_templates(combined_templates) + templates = separate_templates(combined_templates) # Calculate which templates match possible_template_matches = [] @@ -46,6 +57,7 @@ def find_field_set(content): # Return results if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) + pr.remove_from_labels(BOT_REVIEW_LABEL) sys.exit(0) # Pass else: print("PR does not match any known templates") From ecaf94a17ebe97ccb202eda17a1449174023fee1 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:46:12 -0500 Subject: [PATCH 05/21] fixed regex --- scripts/review_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index d33d3a9deb414a..f0d225ee1ac8fe 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -21,7 +21,7 @@ def read_template_file(): return combined_templates # Separate out each template -template_separator = re.compile(r"", re.DOTALL) +template_separator = re.compile(r"", re.DOTALL) def separate_templates(combined_templates): matches = template_separator.findall(combined_templates) for (name,content) in matches: From e1c2e870e03e7c61978ab2067553189e75615026 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 01:59:02 -0500 Subject: [PATCH 06/21] added dep --- scripts/review_bot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index f0d225ee1ac8fe..d94e77eb70b725 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -3,6 +3,7 @@ import json import re from github import Github +import os import time BOT_REVIEW_LABEL = "bot-review" From e31fb80c43860f7c96bf1b4b23131f8069a28597 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 02:11:05 -0500 Subject: [PATCH 07/21] made pr bot run upon edit --- .github/workflows/pr_review_bot.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 497a8d8388087c..bf5a77e03ccf18 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -4,6 +4,7 @@ on: pull_request: types: - opened + - edited jobs: bot_review: runs-on: ubuntu-latest From 8fa8bceb866a5aa63dfbf40b1e623351a2204b28 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 02:14:25 -0500 Subject: [PATCH 08/21] removed sleep --- scripts/review_bot.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index d94e77eb70b725..fb7080fe5da027 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -4,7 +4,6 @@ import re from github import Github import os -import time BOT_REVIEW_LABEL = "bot-review" @@ -54,7 +53,6 @@ def find_field_set(content): if fields_in_pr_body.issuperset(required_fields): possible_template_matches.append(template_name) - time.sleep(20) # Return results if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) From d5a2eeb4c69fdbac0e9a330646621d1b412dcab1 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 02:27:07 -0500 Subject: [PATCH 09/21] set pr to draft during review --- scripts/review_bot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index fb7080fe5da027..0bdf2ccf204c7f 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -41,6 +41,7 @@ def find_field_set(content): pr_body = pr_event["pull_request"]["body"] pr = g.get_repo(repo_name).get_pull(pr_number) pr.add_to_labels(BOT_REVIEW_LABEL) + pr.edit(draft=True) fields_in_pr_body = find_field_set(pr_body) combined_templates = read_template_file() @@ -57,6 +58,7 @@ def find_field_set(content): if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) pr.remove_from_labels(BOT_REVIEW_LABEL) + pr.edit(draft=False) sys.exit(0) # Pass else: print("PR does not match any known templates") From 32e2c8ebec5189c15db7b56555b7880217d7321c Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 02:27:32 -0500 Subject: [PATCH 10/21] test --- scripts/review_bot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 0bdf2ccf204c7f..fd1da6e7a280a1 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -63,3 +63,4 @@ def find_field_set(content): else: print("PR does not match any known templates") sys.exit(1) # Fail + #test From 4c66fafb808d06b85291eacf1acab09cddeb3150 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 02:46:37 -0500 Subject: [PATCH 11/21] moved draft to workflow --- .github/workflows/pr_review_bot.yaml | 23 +++++++++++++++++++++++ scripts/review_bot.py | 2 -- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index bf5a77e03ccf18..69ba6d703bd6d3 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -16,6 +16,17 @@ jobs: - name: Checkout Repository uses: actions/checkout@v2 + - name: Set PR as Draft + run: | + PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) + REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) + REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) + curl -X PATCH \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -d '{"draft": true}' \ + "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}" + - name: Set Up Python uses: actions/setup-python@v2 with: @@ -26,3 +37,15 @@ jobs: - name: Run Bot Review run: python scripts/review_bot.py "${{ github.event_path }}" + + - name: Set PR as Ready + if: success() + run: | + PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) + REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) + REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) + curl -X PATCH \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -d '{"draft": false}' \ + "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}" diff --git a/scripts/review_bot.py b/scripts/review_bot.py index fd1da6e7a280a1..8844a187470d83 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -41,7 +41,6 @@ def find_field_set(content): pr_body = pr_event["pull_request"]["body"] pr = g.get_repo(repo_name).get_pull(pr_number) pr.add_to_labels(BOT_REVIEW_LABEL) - pr.edit(draft=True) fields_in_pr_body = find_field_set(pr_body) combined_templates = read_template_file() @@ -58,7 +57,6 @@ def find_field_set(content): if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) pr.remove_from_labels(BOT_REVIEW_LABEL) - pr.edit(draft=False) sys.exit(0) # Pass else: print("PR does not match any known templates") From 207c4ad3952805061b8a68b125798a333ac2b982 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 03:00:52 -0500 Subject: [PATCH 12/21] updated draft converson to graphql endpoint --- .github/workflows/pr_review_bot.yaml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 69ba6d703bd6d3..4cd7369390ff4b 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -21,11 +21,13 @@ jobs: PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - curl -X PATCH \ - -H "Accept: application/vnd.github.v3+json" \ + graphql_query='mutation ConvertToDraft { convertPullRequestToDraft(input: {pullRequestId: "'$PR_NUMBER'"}) { clientMutationId } }' + curl -X POST \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -d '{"draft": true}' \ - "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}" + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw '{"query": "'"$graphql_query"'"}' \ + "https://api.github.com/graphql" - name: Set Up Python uses: actions/setup-python@v2 @@ -44,8 +46,11 @@ jobs: PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - curl -X PATCH \ - -H "Accept: application/vnd.github.v3+json" \ + graphql_query='mutation ConvertToReady { markPullRequestReadyForReview(input: {pullRequestId: "'$PR_NUMBER'"}) { clientMutationId } }' + curl -X POST \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -d '{"draft": false}' \ - "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}" + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw '{"query": "'"$graphql_query"'"}' \ + "https://api.github.com/graphql" + From 2584c9125c6d09169ac362bc90d191c9fac50a62 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 03:25:30 -0500 Subject: [PATCH 13/21] reformatted curl --- .github/workflows/pr_review_bot.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 4cd7369390ff4b..75de87fe6d4b30 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -21,12 +21,16 @@ jobs: PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - graphql_query='mutation ConvertToDraft { convertPullRequestToDraft(input: {pullRequestId: "'$PR_NUMBER'"}) { clientMutationId } }' + graphql_query='' curl -X POST \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github.v3+json" \ -H "Content-Type: application/json" \ - --data-raw '{"query": "'"$graphql_query"'"}' \ + --data-raw '{ + "query": "mutation { + convertPullRequestToDraft(input: {pullRequestId: "'$PR_NUMBER'"}){} + }" + }' \ "https://api.github.com/graphql" - name: Set Up Python From 2d7518ab0b317f9ee30243cf32de19165a7b7f3f Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 03:33:34 -0500 Subject: [PATCH 14/21] updated draft curl --- .github/workflows/pr_review_bot.yaml | 49 ++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 75de87fe6d4b30..6a41aa2f56c5d5 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -18,20 +18,41 @@ jobs: - name: Set PR as Draft run: | - PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) - REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) - REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - graphql_query='' - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - --data-raw '{ - "query": "mutation { - convertPullRequestToDraft(input: {pullRequestId: "'$PR_NUMBER'"}){} - }" - }' \ - "https://api.github.com/graphql" + PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) + REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) + REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) + + # Query GitHub API v4 to get the base64-encoded ID of the pull request + base64_encoded_id=$(curl -X POST \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw "{ + \"query\": \"query { + repository(owner: \\\"$REPO_OWNER\\\", name: \\\"$REPO_NAME\\\"){ + pullRequest(number: $PR_NUMBER) { + id + } + } + }\" + }" \ + "https://api.github.com/graphql" | jq -r .data.repository.pullRequest.id) + + # Output the base64-encoded ID for reference + echo "Base64 Encoded ID: $base64_encoded_id" + + # If the base64-encoded ID is available, proceed with updating the pull request + # Use the obtained ID to convert the pull request to draft status + curl -X POST \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw "{ + \"query\": \"mutation { + convertPullRequestToDraft(input: {pullRequestId: \\\"$base64_encoded_id\\\"}) {} + }\" + }" \ + "https://api.github.com/graphql" - name: Set Up Python uses: actions/setup-python@v2 From a5471b40579e7108802a1abb903f458ffa407d85 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 03:37:41 -0500 Subject: [PATCH 15/21] update --- .github/workflows/pr_review_bot.yaml | 62 ++++++++++++++-------------- scripts/review_bot.py | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 6a41aa2f56c5d5..66796833379f9d 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -18,41 +18,41 @@ jobs: - name: Set PR as Draft run: | - PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) - REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) - REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) + PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) + REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) + REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - # Query GitHub API v4 to get the base64-encoded ID of the pull request - base64_encoded_id=$(curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - --data-raw "{ - \"query\": \"query { - repository(owner: \\\"$REPO_OWNER\\\", name: \\\"$REPO_NAME\\\"){ - pullRequest(number: $PR_NUMBER) { - id + # Query GitHub API v4 to get the base64-encoded ID of the pull request + base64_encoded_id=$(curl -X POST \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw "{ + \"query\": \"query { + repository(owner: \\\"$REPO_OWNER\\\", name: \\\"$REPO_NAME\\\"){ + pullRequest(number: $PR_NUMBER) { + id + } } - } - }\" - }" \ - "https://api.github.com/graphql" | jq -r .data.repository.pullRequest.id) + }\" + }" \ + "https://api.github.com/graphql" | jq -r .data.repository.pullRequest.id) - # Output the base64-encoded ID for reference - echo "Base64 Encoded ID: $base64_encoded_id" + # Output the base64-encoded ID for reference + echo "Base64 Encoded ID: $base64_encoded_id" - # If the base64-encoded ID is available, proceed with updating the pull request - # Use the obtained ID to convert the pull request to draft status - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - --data-raw "{ - \"query\": \"mutation { - convertPullRequestToDraft(input: {pullRequestId: \\\"$base64_encoded_id\\\"}) {} - }\" - }" \ - "https://api.github.com/graphql" + # If the base64-encoded ID is available, proceed with updating the pull request + # Use the obtained ID to convert the pull request to draft status + curl -X POST \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + --data-raw "{ + \"query\": \"mutation { + convertPullRequestToDraft(input: {pullRequestId: \\\"$base64_encoded_id\\\"}) {} + }\" + }" \ + "https://api.github.com/graphql" - name: Set Up Python uses: actions/setup-python@v2 diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 8844a187470d83..30493618a158f1 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -61,4 +61,4 @@ def find_field_set(content): else: print("PR does not match any known templates") sys.exit(1) # Fail - #test + From 92be7efae4fea8f609c51d318705c6054efcaa26 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 04:27:12 -0500 Subject: [PATCH 16/21] updated curl --- .github/workflows/pr_review_bot.yaml | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index 66796833379f9d..eeee536f8faf21 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -21,22 +21,27 @@ jobs: PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - - # Query GitHub API v4 to get the base64-encoded ID of the pull request + query=' + query ggg($owner: String!, $name: String!, $number: Int!) { + repository(owner: $owner, name: $name) { + pullRequest(number: $number) { + id + } + } + } + ' + variables=' + { + "owner": "'"$REPO_OWNER"'", + "name": "'"$REPO_NAME"'", + "number": '"$PR_NUMBER"' + } + ' base64_encoded_id=$(curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ -H "Content-Type: application/json" \ - --data-raw "{ - \"query\": \"query { - repository(owner: \\\"$REPO_OWNER\\\", name: \\\"$REPO_NAME\\\"){ - pullRequest(number: $PR_NUMBER) { - id - } - } - }\" - }" \ - "https://api.github.com/graphql" | jq -r .data.repository.pullRequest.id) + -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ + --data '{"query":"'"$query"'","variables":'"$variables"'}' \ + https://api.github.com/graphql | jq -r .data.repository.pullRequest.id) # Output the base64-encoded ID for reference echo "Base64 Encoded ID: $base64_encoded_id" From f356975402d5f2ba9a7e8d2f17fd2375c4831b89 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 04:30:34 -0500 Subject: [PATCH 17/21] tweaked curl --- .github/workflows/pr_review_bot.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index eeee536f8faf21..ee62122bd986a3 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -37,9 +37,9 @@ jobs: "number": '"$PR_NUMBER"' } ' - base64_encoded_id=$(curl -X POST \ + base64_encoded_id=$(curl -v -X POST \ -H "Content-Type: application/json" \ - -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ --data '{"query":"'"$query"'","variables":'"$variables"'}' \ https://api.github.com/graphql | jq -r .data.repository.pullRequest.id) From 12665098966bae429bac89b5c69660ab66c48292 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 05:23:21 -0500 Subject: [PATCH 18/21] moved graphql to python --- .github/workflows/pr_review_bot.yaml | 58 +--------------------------- scripts/review_bot.py | 41 +++++++++++++++++++- 2 files changed, 41 insertions(+), 58 deletions(-) diff --git a/.github/workflows/pr_review_bot.yaml b/.github/workflows/pr_review_bot.yaml index ee62122bd986a3..97594f253fbd27 100644 --- a/.github/workflows/pr_review_bot.yaml +++ b/.github/workflows/pr_review_bot.yaml @@ -16,71 +16,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v2 - - name: Set PR as Draft - run: | - PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) - REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) - REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - query=' - query ggg($owner: String!, $name: String!, $number: Int!) { - repository(owner: $owner, name: $name) { - pullRequest(number: $number) { - id - } - } - } - ' - variables=' - { - "owner": "'"$REPO_OWNER"'", - "name": "'"$REPO_NAME"'", - "number": '"$PR_NUMBER"' - } - ' - base64_encoded_id=$(curl -v -X POST \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - --data '{"query":"'"$query"'","variables":'"$variables"'}' \ - https://api.github.com/graphql | jq -r .data.repository.pullRequest.id) - - # Output the base64-encoded ID for reference - echo "Base64 Encoded ID: $base64_encoded_id" - - # If the base64-encoded ID is available, proceed with updating the pull request - # Use the obtained ID to convert the pull request to draft status - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - --data-raw "{ - \"query\": \"mutation { - convertPullRequestToDraft(input: {pullRequestId: \\\"$base64_encoded_id\\\"}) {} - }\" - }" \ - "https://api.github.com/graphql" - - name: Set Up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install Dependencies - run: pip install PyGithub + run: pip install PyGithub requests - name: Run Bot Review run: python scripts/review_bot.py "${{ github.event_path }}" - - name: Set PR as Ready - if: success() - run: | - PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH) - REPO_OWNER=$(jq --raw-output .repository.owner.login $GITHUB_EVENT_PATH) - REPO_NAME=$(jq --raw-output .repository.name $GITHUB_EVENT_PATH) - graphql_query='mutation ConvertToReady { markPullRequestReadyForReview(input: {pullRequestId: "'$PR_NUMBER'"}) { clientMutationId } }' - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - --data-raw '{"query": "'"$graphql_query"'"}' \ - "https://api.github.com/graphql" diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 30493618a158f1..2875cfcf5fdac8 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -32,15 +32,53 @@ def separate_templates(combined_templates): def find_field_set(content): return set(field_finder.findall(content)) +# use GraphQL to get pull request id +def get_pull_request_graphql_id(accessToken,name,number): + owner,name = name.split('/') + query = f"""query {{ + repository(owner:"{owner}", name:"{name}"){{ + pullRequest(number: {number}) {{ + id + }} + }} + }}""" + r = requests.post(endpoint, json={"query": query}, headers=headers) + return r.json()["data"]["repository"]["pullRequest"]["id"] + +# use GraphQL to set pull request as draft +def set_pr_draft(accessToken,id): + query = f"""mutation {{ + convertPullRequestToDraft(input:{{pullRequestId:"{id}"}}){{ + pullRequest {{ + id + }} + }} + }}""" + requests.post(endpoint, json={"query": query}, headers=headers) + +# use GraphQL to set pull request as ready +def set_pr_ready(accessToken,id): + query = f"""mutation {{ + markPullRequestReadyForReview(input:{{pullRequestId:"{id}"}}){{ + pullRequest {{ + id + }} + }} + }}""" + requests.post(endpoint, json={"query": query}, headers=headers) + if __name__ == "__main__": - g = Github(os.environ['GITHUB_TOKEN']) + accessToken = os.environ['GITHUB_TOKEN'] + g = Github(accessToken) pr_event = read_pr_event() repo_name = pr_event['repository']['full_name'] pr_number = pr_event['pull_request']['number'] + pr_id = get_pull_request_graphql_id(accessToken,repo_name,pr_number) pr_body = pr_event["pull_request"]["body"] pr = g.get_repo(repo_name).get_pull(pr_number) pr.add_to_labels(BOT_REVIEW_LABEL) + set_pr_draft(accessToken,pr_id) fields_in_pr_body = find_field_set(pr_body) combined_templates = read_template_file() @@ -57,6 +95,7 @@ def find_field_set(content): if len(possible_template_matches) > 0: print("PR matches template(s): ",", ".join(possible_template_matches)) pr.remove_from_labels(BOT_REVIEW_LABEL) + set_pr_ready(accessToken,pr_id) sys.exit(0) # Pass else: print("PR does not match any known templates") From d45ec6117258af06f445f1b456a6d3bae52273c7 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 05:25:59 -0500 Subject: [PATCH 19/21] added import --- scripts/review_bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index 2875cfcf5fdac8..ec529eac037a02 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -2,8 +2,9 @@ import sys import json import re -from github import Github import os +import requests +from github import Github BOT_REVIEW_LABEL = "bot-review" From 17f5944126d6d9fbe63a8e9eb17fcff9f40fc367 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 05:28:57 -0500 Subject: [PATCH 20/21] added headers to requests --- scripts/review_bot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index ec529eac037a02..f244fe5f7d0ac7 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -35,6 +35,7 @@ def find_field_set(content): # use GraphQL to get pull request id def get_pull_request_graphql_id(accessToken,name,number): + headers = {"Authorization": f"Bearer {accessToken}"} owner,name = name.split('/') query = f"""query {{ repository(owner:"{owner}", name:"{name}"){{ @@ -48,6 +49,7 @@ def get_pull_request_graphql_id(accessToken,name,number): # use GraphQL to set pull request as draft def set_pr_draft(accessToken,id): + headers = {"Authorization": f"Bearer {accessToken}"} query = f"""mutation {{ convertPullRequestToDraft(input:{{pullRequestId:"{id}"}}){{ pullRequest {{ @@ -59,6 +61,7 @@ def set_pr_draft(accessToken,id): # use GraphQL to set pull request as ready def set_pr_ready(accessToken,id): + headers = {"Authorization": f"Bearer {accessToken}"} query = f"""mutation {{ markPullRequestReadyForReview(input:{{pullRequestId:"{id}"}}){{ pullRequest {{ From 6d77dbd63baefcb48c4b70db7f09b33af65f8e4c Mon Sep 17 00:00:00 2001 From: user Date: Wed, 20 Dec 2023 05:43:24 -0500 Subject: [PATCH 21/21] added endpoint --- scripts/review_bot.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/review_bot.py b/scripts/review_bot.py index f244fe5f7d0ac7..6d551d45eb5228 100755 --- a/scripts/review_bot.py +++ b/scripts/review_bot.py @@ -7,6 +7,7 @@ from github import Github BOT_REVIEW_LABEL = "bot-review" +GRAPHQL_ENDPOINT = "https://api.github.com/graphql" # Read the pr event file, which is passed in as first arg def read_pr_event(): @@ -44,7 +45,7 @@ def get_pull_request_graphql_id(accessToken,name,number): }} }} }}""" - r = requests.post(endpoint, json={"query": query}, headers=headers) + r = requests.post(GRAPHQL_ENDPOINT, json={"query": query}, headers=headers) return r.json()["data"]["repository"]["pullRequest"]["id"] # use GraphQL to set pull request as draft @@ -57,7 +58,7 @@ def set_pr_draft(accessToken,id): }} }} }}""" - requests.post(endpoint, json={"query": query}, headers=headers) + requests.post(GRAPHQL_ENDPOINT, json={"query": query}, headers=headers) # use GraphQL to set pull request as ready def set_pr_ready(accessToken,id): @@ -69,7 +70,7 @@ def set_pr_ready(accessToken,id): }} }} }}""" - requests.post(endpoint, json={"query": query}, headers=headers) + requests.post(GRAPHQL_ENDPOINT, json={"query": query}, headers=headers) if __name__ == "__main__": accessToken = os.environ['GITHUB_TOKEN']