Skip to content

Instantly share code, notes, and snippets.

@Hogeyama
Last active August 22, 2024 13:04
Show Gist options
  • Select an option

  • Save Hogeyama/5cef7b82689f5f06ad30083048cda797 to your computer and use it in GitHub Desktop.

Select an option

Save Hogeyama/5cef7b82689f5f06ad30083048cda797 to your computer and use it in GitHub Desktop.
# GitHubのUIではrebaseすると未解決スレッドを参照するのがとても難しくなるので、コメントに一覧を表示しておく
on:
pull_request:
types:
- opened
- synchronize
pull_request_review_comment:
types:
# TODO コメント追加の度に走るのはまずいかな?2秒で終わっても課金上は1分で計算されるらしい
- created
# editedはResolveを検知してくれないので有効にしてもほとんど意味がない。
#- edited
jobs:
list-unresolved-conversations:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: List unresolved conversations
run: |
OWNER=${REPO%/*}
REPO_NAME=${REPO#*/}
unresolved_threads() {
# Based on https://stackoverflow.com/a/66072198
# shellcheck disable=SC2016
query='
query FetchReviewComments($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
edges {
node {
isResolved
comments(first: 1) {
nodes {
body
url
}
}
}
}
}
}
}
}
'
gh api graphql -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" -f query="$query" |
jq -c '.
| .data.repository.pullRequest.reviewThreads.edges[]
| select(.node.isResolved == false)
| .node.comments.nodes[0]
'
}
get_my_comment() {
# shellcheck disable=SC2016
query='
query FetchComments($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
comments(first: 100) {
edges {
node {
author {
login
}
body
id
}
}
}
}
}
}
'
gh api graphql -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" -f query="$query" |
jq -r '.
| .data.repository.pullRequest.comments.edges
| map(select(.node.author.login == "github-actions" and
(.node.body|startswith("Unresolved conversations:"))))[0]
| .node.id
'
}
create_comment() {
PR_ID=$(gh api "repos/$OWNER/$REPO_NAME/pulls/$PR_NUMBER" | jq -r .node_id)
# shellcheck disable=SC2016
query='
mutation addComment($subjectId: ID!, $body: String!) {
addComment(input: {subjectId: $subjectId, body: $body}) {
clientMutationId
}
}
'
gh api graphql -f subjectId="$PR_ID" -f body="$(cat -)" -f query="$query"
}
update_comment() {
COMMENT_ID=$1
# shellcheck disable=SC2016
query='
mutation updateIssueComment($id: ID!, $body: String!) {
updateIssueComment(input: {id: $id, body: $body}) {
clientMutationId
}
}
'
gh api graphql -f id="$COMMENT_ID" -f body="$(cat -)" -f query="$query"
}
gen_comment_body() {
ITEMS=()
while read -r json; do
body=$(jq -r '.body' <<<"$json" | head -n1)
url=$(jq -r '.url' <<<"$json")
ITEMS+=("* [ ] [$body]($url)")
done < <(unresolved_threads)
echo "Unresolved conversations:"
if [[ ${#ITEMS[@]} -gt 0 ]]; then
for item in "${ITEMS[@]}"; do
echo "$item"
done
else
echo "* なし"
fi
echo
echo "> [!TIP]"
echo "> プッシュとレビューコメント追加(リプライ含む)の度に更新されます。"
echo "> スレッドをResolveするだけでは更新されないので、必要に応じてチェックボックスを使って手動で管理してください。"
}
main() {
my_comment_id=$(get_my_comment)
if [[ $my_comment_id == null ]]; then
gen_comment_body | create_comment
else
gen_comment_body | update_comment "$my_comment_id"
fi
}
set -x
main
env:
REPO: ${{ github.repository }}
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GH_TOKEN: ${{ github.token }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment