diff --git a/.github/workflows/pr-notification.yml b/.github/workflows/pr-notification.yml index 62993eaf..ced8f26d 100644 --- a/.github/workflows/pr-notification.yml +++ b/.github/workflows/pr-notification.yml @@ -2,10 +2,8 @@ name: PR Slack Notification on: pull_request: types: [opened, reopened] - permissions: pull-requests: read - jobs: notify_reviewers: runs-on: ubuntu-latest @@ -20,38 +18,48 @@ jobs: echo "Error: SLACK_IDS is not set" exit 1 fi - - name: Set environment variables run: | echo "SLACK_WEBHOOK_URL=${{ secrets.SLACK_PR_CREATE_WEBHOOK_URL }}" >> $GITHUB_ENV - echo "SLACK_IDS=${{ secrets.SLACK_IDS }}" >> $GITHUB_ENV - + echo 'SLACK_IDS=${{ toJson(secrets.SLACK_IDS) }}' >> $GITHUB_ENV + shell: bash - name: Send Slack notification for new PR + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + set -e PR_TITLE="${{ github.event.pull_request.title }}" PR_URL="${{ github.event.pull_request.html_url }}" - REVIEWERS='${{ toJson(github.event.pull_request.requested_reviewers.*.login) }}' + PR_AUTHOR="${{ github.event.pull_request.user.login }}" + REVIEWERS='${{ toJson(github.event.pull_request.requested_reviewers) }}' - if [ -z "$REVIEWERS" ] || [ "$REVIEWERS" == "null" ]; then + if [ "$REVIEWERS" == "null" ] || [ "$REVIEWERS" == "[]" ]; then echo "No reviewers requested for this PR" exit 0 fi - echo "Reviewers: $REVIEWERS" - - parse_slack_ids() { - if ! echo "$SLACK_IDS" | jq empty; then - echo "Error: Invalid JSON in SLACK_IDS" >&2 + # Parse SLACK_IDS as JSON + SLACK_IDS_JSON=$(echo "$SLACK_IDS" | jq -r '.' 2>/dev/null || echo "{}") + if [ "$SLACK_IDS_JSON" == "{}" ]; then + echo "Warning: SLACK_IDS is not a valid JSON. Attempting to parse as a string." + SLACK_IDS_JSON=$(echo "$SLACK_IDS" | sed 's/^"//; s/"$//' | jq -R 'split(",") | map(split(":")) | from_entries' 2>/dev/null || echo "{}") + if [ "$SLACK_IDS_JSON" == "{}" ]; then + echo "Error: Failed to parse SLACK_IDS as JSON or string. Please check the format." exit 1 fi - echo "$SLACK_IDS" | jq -r 'to_entries | map("\(.key):\(.value)") | .[]' + fi + + get_slack_id() { + local github_username="$1" + echo "$SLACK_IDS_JSON" | jq -r --arg user "$github_username" '.[$user] // empty' } - reviewers=$(echo "$REVIEWERS" | jq -r '.[]') + reviewers=$(echo "$REVIEWERS" | jq -r '.[].login // empty') mentions="" for reviewer in $reviewers; do - slack_id=$(parse_slack_ids | grep "^$reviewer:" | cut -d':' -f2) + slack_id=$(get_slack_id "$reviewer") if [ -n "$slack_id" ]; then mentions="$mentions <@$slack_id>" @@ -61,10 +69,16 @@ jobs: fi done - echo "Mentions: $mentions" + author_slack_id=$(get_slack_id "$PR_AUTHOR") + if [ -n "$author_slack_id" ]; then + author_mention="<@$author_slack_id>" + else + author_mention="$PR_AUTHOR" + echo "Warning: No Slack ID found for PR author $PR_AUTHOR" >&2 + fi if [ -n "$mentions" ]; then - message="$mentions 님, 새로운 PR이 생성되었습니다: <$PR_URL|$PR_TITLE>" + message="$mentions 님, $author_mention 님이 새로운 PR을 생성하였습니다: <$PR_URL|$PR_TITLE>" response=$(curl -s -o /dev/null -w "%{http_code}" -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"$message\"}" \ "$SLACK_WEBHOOK_URL") @@ -78,5 +92,3 @@ jobs: else echo "No reviewers to notify" fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-review-notification.yml b/.github/workflows/pr-review-notification.yml new file mode 100644 index 00000000..2b575684 --- /dev/null +++ b/.github/workflows/pr-review-notification.yml @@ -0,0 +1,79 @@ +name: PR Review Slack Notification +on: + pull_request_review: + types: [submitted] +jobs: + notify_pr_author: + runs-on: ubuntu-latest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PR_REVIEW_WEBHOOK_URL }} + SLACK_IDS: ${{ secrets.SLACK_IDS }} + steps: + - name: PR 리뷰 시 Slack 알림 보내기 + run: | + set -e + PR_TITLE="${{ github.event.pull_request.title }}" + PR_URL="${{ github.event.pull_request.html_url }}" + PR_AUTHOR="${{ github.event.pull_request.user.login }}" + REVIEW_STATE="${{ github.event.review.state }}" + REVIEWER="${{ github.event.review.user.login }}" + + # Parse SLACK_IDS as JSON + SLACK_IDS_JSON=$(echo "$SLACK_IDS" | jq -r '.' 2>/dev/null || echo "{}") + if [ "$SLACK_IDS_JSON" == "{}" ]; then + echo "Warning: SLACK_IDS is not a valid JSON. Attempting to parse as a string." + SLACK_IDS_JSON=$(echo "$SLACK_IDS" | sed 's/^"//; s/"$//' | jq -R 'split(",") | map(split(":")) | from_entries' 2>/dev/null || echo "{}") + if [ "$SLACK_IDS_JSON" == "{}" ]; then + echo "Error: Failed to parse SLACK_IDS as JSON or string. Please check the format." + exit 1 + fi + fi + + get_slack_id() { + local github_username="$1" + echo "$SLACK_IDS_JSON" | jq -r --arg user "$github_username" '.[$user] // empty' + } + + author_slack_id=$(get_slack_id "$PR_AUTHOR") + reviewer_slack_id=$(get_slack_id "$REVIEWER") + + if [ -n "$author_slack_id" ]; then + author_mention="<@$author_slack_id>" + else + author_mention="$PR_AUTHOR" + echo "Warning: No Slack ID found for PR author $PR_AUTHOR" >&2 + fi + + if [ -n "$reviewer_slack_id" ]; then + reviewer_mention="<@$reviewer_slack_id>" + else + reviewer_mention="$REVIEWER" + echo "Warning: No Slack ID found for reviewer $REVIEWER" >&2 + fi + + case "$REVIEW_STATE" in + "changes_requested") + message="$author_mention님, $reviewer_mention님이 PR에 변경을 요청했습니다: <$PR_URL|$PR_TITLE>" + ;; + "commented") + message="$author_mention님, $reviewer_mention님이 PR에 댓글을 달았습니다: <$PR_URL|$PR_TITLE>" + ;; + "approved") + message="$author_mention님, 축하합니다! $reviewer_mention님이 PR을 승인했습니다: <$PR_URL|$PR_TITLE>" + ;; + esac + + if [ -n "$message" ]; then + response=$(curl -s -o /dev/null -w "%{http_code}" -X POST -H 'Content-type: application/json' \ + --data "{\"text\":\"$message\"}" \ + "$SLACK_WEBHOOK_URL") + + if [ "$response" = "200" ]; then + echo "Successfully sent Slack notification" + else + echo "Error: Failed to send Slack notification. HTTP status code: $response" >&2 + exit 1 + fi + else + echo "No notification to send" + fi