Skip to content

Commit

Permalink
Try paginating comments (#14)
Browse files Browse the repository at this point in the history
* Try paginating comments

* Fix range

* Update action to run from branch (undo before merge)

* Update beta release to track v2; add flag to run beta commenter

* Fix pagination url

* Better logging

* Really fix query parameter

* Detect rate limiting(ish)

* Fix deletes during pagination
  • Loading branch information
jcogilvie authored Sep 30, 2022
1 parent 5fe12c2 commit e86dd74
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-beta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Set Beta Git tag
uses: weareyipyip/walking-tag-action@v2
with:
tag-name: v1-beta
tag-name: v2-beta
tag-message: The current beta is based on this commit
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# IDEs
.idea
.vscode
.DS_Store
13 changes: 11 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,21 @@ inputs:
description: 'The version of terraform with which a plan was generated'
required: false
default: "1.0.6"
use_beta_version:
description: 'Whether to use the beta version of the commenter'
required: false
default: 'false'
runs:
using: "composite"
steps:
- name: Build commenter docker image
- name: Build commenter docker image (master)
if: inputs.use_beta_version != 'true'
run: docker build --build-arg TERRAFORM_VERSION=${{ inputs.terraform_version }} -t commenter https://github.com/GetTerminus/terraform-pr-commenter.git#master
shell: bash
- name: Build commenter docker image (beta)
if: inputs.use_beta_version == 'true'
# append branch with a pound (#) if developing. e.g., `commenter.git#my-branch`
run: docker build --build-arg TERRAFORM_VERSION=${{ inputs.terraform_version }} -t commenter https://github.com/GetTerminus/terraform-pr-commenter.git
run: docker build --build-arg TERRAFORM_VERSION=${{ inputs.terraform_version }} -t commenter https://github.com/GetTerminus/terraform-pr-commenter.git#v2-beta
shell: bash
- name: Run commenter image (plan)
env:
Expand Down
54 changes: 52 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ parse_args () {
CONTENT_HEADER="Content-Type: application/json"

PR_COMMENTS_URL=$(echo "$GITHUB_EVENT" | jq -r ".pull_request.comments_url")
PR_COMMENTS_URL+="?per_page=100"

PR_COMMENT_URI=$(echo "$GITHUB_EVENT" | jq -r ".repository.issue_comment_url" | sed "s|{/number}||g")
}

Expand Down Expand Up @@ -159,24 +161,72 @@ substitute_and_colorize () {
echo "$current_plan"
}

get_page_count () {
local link_header
local last_page=1

link_header=$(curl -sSI -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENTS_URL" | grep -i ^link)

# if I find a matching link header...
if grep -Fi 'rel="next"' <<< "$link_header"; then
# we found a next page -> find the last page
IFS=',' read -ra links <<< "$link_header"
for link in "${links[@]}"; do
# process "$i"
local regex
page_regex='^.*page=([0-9]+).*$'

# if this is the 'last' ref...
if grep -Fi 'rel="last"' <<< "$link" ; then
if [[ $link =~ $page_regex ]]; then
last_page="${BASH_REMATCH[1]}"
break
fi
fi
done
fi

eval "$1"="$last_page"
}

delete_existing_comments () {
# Look for an existing PR comment and delete
# debug "Existing comments: $(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L $PR_COMMENTS_URL)"

local type=$1
local regex=$2
local last_page

local jq='.[] | select(.body|test ("'
jq+=$regex
jq+='")) | .id'

# gross, but... bash.
get_page_count PAGE_COUNT
last_page=$PAGE_COUNT
info "Found $last_page page(s) of comments at $PR_COMMENTS_URL."

info "Looking for an existing $type PR comment."
for PR_COMMENT_ID in $(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L $PR_COMMENTS_URL | jq "$jq")
local comment_ids=()
for page in $(seq $last_page)
do
# first, we read *all* of the comment IDs across all pages. saves us from the problem where we read a page, then
# delete some, then read the next page, *after* our page boundary has moved due to the delete.
# CAUTION. this line assumes the PR_COMMENTS_URL already has at least one query parameter. (note the '&')
readarray -t -O "${#comment_ids[@]}" comment_ids < <(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENTS_URL&page=$page" | jq "$jq")
done

for PR_COMMENT_ID in "${comment_ids[@]}"
do
FOUND=true
info "Found existing $type PR comment: $PR_COMMENT_ID. Deleting."
PR_COMMENT_URL="$PR_COMMENT_URI/$PR_COMMENT_ID"
curl -sS -X DELETE -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENT_URL" > /dev/null
STATUS=$(curl -sS -X DELETE -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -o /dev/null -w "%{http_code}" -L "$PR_COMMENT_URL")
if [ "$STATUS" != "204" ]; then
info "Failed to delete: status $STATUS (most likely rate limited)"
fi
done

if [ -z $FOUND ]; then
info "No existing $type PR comment found."
fi
Expand Down
104 changes: 104 additions & 0 deletions testing/paginate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
set -x

ACCEPT_HEADER="Accept: application/vnd.github.v3+json"
AUTH_HEADER="Authorization: token $GH_TOKEN"
CONTENT_HEADER="Content-Type: application/json"

PR_COMMENTS_URL="https://api.github.com/repositories/520589422/issues/7/comments?per_page=100"
#PR_COMMENTS_URL="https://api.github.com/repos/GetTerminus/eks-autoscaling-infra/issues/7/comments"
PR_COMMENT_URI="https://api.github.com/repositories/520589422/issues/comments"

PAGE_COUNT=1

###########
# Logging #
###########
debug () {
if [ -n "${COMMENTER_DEBUG+x}" ]; then
echo -e "\033[33;1mDEBUG:\033[0m $1"
fi
}

info () {
echo -e "\033[34;1mINFO:\033[0m $1"
}

error () {
echo -e "\033[31;1mERROR:\033[0m $1"
}

get_page_count () {
local link_header
local last_page=1

link_header=$(curl -sSI -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENTS_URL" | grep -i ^link)

# if I find a matching link header...
if grep -Fi 'rel="next"' <<< "$link_header"; then
# we found a next page -> find the last page
IFS=',' read -ra links <<< "$link_header"
for link in "${links[@]}"; do
# process "$i"
local regex
page_regex='^.*page=([0-9]+).*$'

# if this is the 'last' ref...
if grep -Fi 'rel="last"' <<< "$link" ; then
if [[ $link =~ $page_regex ]]; then
last_page="${BASH_REMATCH[1]}"
break
fi
fi
done
fi

eval "$1"="$last_page"
}

delete_existing_comments () {
# Look for an existing PR comment and delete
# debug "Existing comments: $(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L $PR_COMMENTS_URL)"

local type=$1
local regex=$2
local last_page

local jq='.[] | select(.body|test ("'
jq+=$regex
jq+='")) | .id'

# gross, but... bash.
get_page_count PAGE_COUNT
last_page=$PAGE_COUNT
info "Found $last_page page(s) of comments at $PR_COMMENTS_URL."

info "Looking for an existing $type PR comment."
local comment_ids=()
for page in $(seq $last_page)
do
# first, we read *all* of the comment IDs across all pages. saves us from the problem where we read a page, then
# delete some, then read the next page, *after* our page boundary has moved due to the delete.
# CAUTION. this line assumes the PR_COMMENTS_URL already has at least one query parameter. (note the '&')
readarray -t -O "${#comment_ids[@]}" comment_ids < <(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENTS_URL&page=$page" | jq "$jq")
done

for PR_COMMENT_ID in "${comment_ids[@]}"
do
FOUND=true
info "Found existing $type PR comment: $PR_COMMENT_ID. Deleting."
PR_COMMENT_URL="$PR_COMMENT_URI/$PR_COMMENT_ID"
# STATUS=$(curl -sS -X DELETE -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -o /dev/null -w "%{http_code}" -L "$PR_COMMENT_URL")
# if [ "$STATUS" != "204" ]; then
# info "Failed to delete: status $STATUS (most likely rate limited)"
# fi
done

if [ -z $FOUND ]; then
info "No existing $type PR comment found."
fi
}

WORKSPACE=prod-east
#delete_existing_comments 'plan' '### Terraform `plan` .* for Workspace: `'$WORKSPACE'`.*'
delete_existing_comments 'outputs' '### Changes to outputs for Workspace: `'$WORKSPACE'`.*'
5 changes: 3 additions & 2 deletions testing/testing.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2403,8 +2403,9 @@ ACCEPT_HEADER="Accept: application/vnd.github.v3+json"
AUTH_HEADER="Authorization: token $GH_TOKEN"
CONTENT_HEADER="Content-Type: application/json"

PR_COMMENTS_URL="https://api.github.com/repos/GetTerminus/web-event-capture-infra/issues/122/comments"
PR_COMMENT_URI="https://api.github.com/repos/GetTerminus/web-event-capture-infra/issues/comments/122"
PR_COMMENTS_URL="https://api.github.com/repos/GetTerminus/eks-observability-infra/issues/4/comments"
PR_COMMENT_URI="https://api.github.com/repos/GetTerminus/eks-observability-infra/issues/comments/4"
# curl -sSi -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L $PR_COMMENTS_URL

WORKSPACE=ninja
POST_PLAN_OUTPUTS=true
Expand Down

0 comments on commit e86dd74

Please sign in to comment.