Init : global style 및 디자인 토큰 추가 #26
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Automated Discord Notification | |
| on: | |
| pull_request: | |
| types: [opened, reopened, closed, ready_for_review] | |
| pull_request_review: | |
| types: [submitted] | |
| issues: | |
| types: [opened] | |
| schedule: | |
| - cron: "0 1 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| issues: read | |
| jobs: | |
| notify: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Send Discord notification | |
| shell: bash | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| ISSUE_BODY: ${{ github.event.issue.body }} | |
| REVIEW_BODY: ${{ github.event.review.body }} | |
| run: | | |
| if [ -z "$DISCORD_WEBHOOK_URL" ]; then | |
| echo "DISCORD_WEBHOOK_URL is not set." | |
| exit 1 | |
| fi | |
| EVENT_NAME="${{ github.event_name }}" | |
| ACTION="${{ github.event.action }}" | |
| REPOSITORY="${{ github.repository }}" | |
| REPO_API_URL="https://api.github.com/repos/$REPOSITORY" | |
| get_discord_mention() { | |
| if [ -z "$1" ] || [ "$1" = "없음" ] || [ "$1" = "리뷰어 정보 없음" ]; then | |
| echo "없음" | |
| return | |
| fi | |
| case "$1" in | |
| jyeon03) echo "<@1219518046163435544>" ;; | |
| chungyo) echo "<@340668628867219456>" ;; | |
| nyewon) echo "<@1016558289296830484>" ;; | |
| gyeongbibin) echo "<@1502269805011406960>" ;; | |
| seojin15) echo "<@952484462141259816>" ;; | |
| *) echo "@$1" ;; | |
| esac | |
| } | |
| build_user_list() { | |
| local users="$1" | |
| if [ -z "$users" ] || [ "$users" = "없음" ]; then | |
| echo "없음" | |
| return | |
| fi | |
| local result="" | |
| IFS=',' read -ra USER_ARRAY <<< "$users" | |
| for user in "${USER_ARRAY[@]}"; do | |
| trimmed_user=$(echo "$user" | xargs) | |
| mention=$(get_discord_mention "$trimmed_user") | |
| if [ -z "$result" ]; then | |
| result="$mention" | |
| else | |
| result="$result, $mention" | |
| fi | |
| done | |
| echo "$result" | |
| } | |
| send_discord_message() { | |
| jq -n \ | |
| --arg title "$TITLE" \ | |
| --arg url "$URL" \ | |
| --arg desc "$DESC" \ | |
| --arg author "$AUTHOR" \ | |
| --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ | |
| --argjson color "$COLOR" \ | |
| '{ | |
| embeds: [ | |
| { | |
| title: $title, | |
| url: $url, | |
| description: $desc, | |
| color: $color, | |
| author: { | |
| name: $author, | |
| icon_url: ("https://github.com/" + $author + ".png") | |
| }, | |
| footer: { | |
| text: "SnapDeck GitHub Automation" | |
| }, | |
| timestamp: $timestamp | |
| } | |
| ] | |
| }' > payload.json | |
| curl -f \ | |
| -H "Content-Type: application/json" \ | |
| -X POST \ | |
| -d @payload.json \ | |
| "$DISCORD_WEBHOOK_URL" | |
| } | |
| if [ "$EVENT_NAME" = "schedule" ] || [ "$EVENT_NAME" = "workflow_dispatch" ]; then | |
| OPEN_PRS=$(curl -s \ | |
| -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "$REPO_API_URL/pulls?state=open&per_page=100") | |
| STALE_PRS=$(echo "$OPEN_PRS" | jq -c ' | |
| [ | |
| .[] | |
| | select(.draft == false) | |
| | select(((now - (.updated_at | fromdateiso8601)) / 3600) >= 24) | |
| ] | |
| ') | |
| STALE_COUNT=$(echo "$STALE_PRS" | jq 'length') | |
| if [ "$STALE_COUNT" -eq 0 ]; then | |
| echo "No stale PRs found." | |
| exit 0 | |
| fi | |
| PR_LIST="" | |
| while IFS= read -r pr; do | |
| PR_NUMBER=$(echo "$pr" | jq -r '.number') | |
| PR_TITLE=$(echo "$pr" | jq -r '.title') | |
| PR_AUTHOR=$(echo "$pr" | jq -r '.user.login') | |
| PR_AUTHOR_MENTION=$(get_discord_mention "$PR_AUTHOR") | |
| PR_UPDATED_AT=$(echo "$pr" | jq -r '.updated_at') | |
| PR_URL=$(echo "$pr" | jq -r '.html_url') | |
| PR_LIST+="#${PR_NUMBER} ${PR_TITLE}"$'\n' | |
| PR_LIST+="작성자: ${PR_AUTHOR_MENTION}"$'\n' | |
| PR_LIST+="마지막 업데이트: ${PR_UPDATED_AT}"$'\n' | |
| PR_LIST+="링크: ${PR_URL}"$'\n\n' | |
| done < <(echo "$STALE_PRS" | jq -c '.[]') | |
| PR_LIST=$(echo "$PR_LIST" | head -c 900) | |
| TITLE="⏰ 24시간 이상 업데이트되지 않은 PR이 있어요" | |
| URL="https://github.com/$REPOSITORY/pulls" | |
| DESC=$'리뷰가 지연되었거나 작업이 멈춘 PR이 있는지 확인해주세요. Draft PR은 제외했습니다.\n\n'"$PR_LIST" | |
| AUTHOR="github-actions" | |
| COLOR=15844367 | |
| send_discord_message | |
| exit 0 | |
| fi | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| if [ "$ACTION" = "opened" ]; then | |
| sleep 10 | |
| fi | |
| PR_TITLE="${{ github.event.pull_request.title }}" | |
| IS_MERGED="${{ github.event.pull_request.merged }}" | |
| PR_NUMBER="${{ github.event.pull_request.number }}" | |
| IS_DRAFT="${{ github.event.pull_request.draft }}" | |
| BASE_BRANCH="${{ github.event.pull_request.base.ref }}" | |
| HEAD_BRANCH="${{ github.event.pull_request.head.ref }}" | |
| AUTHOR="${{ github.event.pull_request.user.login }}" | |
| AUTHOR_MENTION=$(get_discord_mention "$AUTHOR") | |
| if [ "$IS_DRAFT" = "true" ] && [ "$ACTION" != "ready_for_review" ]; then | |
| echo "Draft PR notification is skipped." | |
| exit 0 | |
| fi | |
| REQUESTED_REVIEWERS=$(jq -r ' | |
| [.pull_request.requested_reviewers[].login] | |
| | if length > 0 then join(", ") else "없음" end | |
| ' "$GITHUB_EVENT_PATH") | |
| REQUESTED_REVIEWER_MENTIONS=$(build_user_list "$REQUESTED_REVIEWERS") | |
| case "$ACTION" in | |
| opened) | |
| TITLE="🚀 새로운 PR이 생성되었어요" | |
| DESC=$'새로운 작업이 리뷰 대기 목록에 올라왔습니다. 리뷰어는 변경 범위와 요청 내용을 확인해주세요.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION"$'\n'"**리뷰어:** $REQUESTED_REVIEWER_MENTIONS" | |
| COLOR=3066993 | |
| ;; | |
| reopened) | |
| TITLE="🔄 PR이 다시 열렸어요" | |
| DESC=$'닫혔던 PR이 다시 열렸습니다. 이전 논의 내용과 현재 변경사항을 함께 확인해주세요.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION"$'\n'"**리뷰어:** $REQUESTED_REVIEWER_MENTIONS" | |
| COLOR=3447003 | |
| ;; | |
| ready_for_review) | |
| TITLE="👀 Draft PR이 리뷰 가능한 상태가 되었어요" | |
| DESC=$'이제 본격적인 리뷰가 가능한 상태입니다. 리뷰어는 구현 내용과 체크 포인트를 확인해주세요.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION"$'\n'"**리뷰어:** $REQUESTED_REVIEWER_MENTIONS" | |
| COLOR=3447003 | |
| ;; | |
| closed) | |
| if [ "$IS_MERGED" = "true" ]; then | |
| TITLE="🎉 PR이 머지되었어요" | |
| DESC=$'작업이 성공적으로 반영되었습니다. 관련 이슈나 후속 작업이 있다면 함께 확인해주세요.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION"$'\n'"**브랜치:** $HEAD_BRANCH → $BASE_BRANCH" | |
| COLOR=5763719 | |
| else | |
| TITLE="🗑️ PR이 닫혔어요" | |
| DESC=$'PR이 머지되지 않고 닫혔습니다. 작업 중단, 중복 PR, 방향 변경 등의 이유가 있는지 확인해주세요.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION" | |
| COLOR=15158332 | |
| fi | |
| ;; | |
| *) | |
| TITLE="📣 PR 이벤트가 발생했어요" | |
| DESC=$'PR 상태가 변경되었습니다.\n\n'"**PR:** #$PR_NUMBER $PR_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION" | |
| COLOR=9807270 | |
| ;; | |
| esac | |
| URL="${{ github.event.pull_request.html_url }}" | |
| elif [ "$EVENT_NAME" = "pull_request_review" ]; then | |
| REVIEW_STATE="${{ github.event.review.state }}" | |
| PR_TITLE="${{ github.event.pull_request.title }}" | |
| PR_NUMBER="${{ github.event.pull_request.number }}" | |
| PR_AUTHOR="${{ github.event.pull_request.user.login }}" | |
| REVIEWER="${{ github.event.review.user.login }}" | |
| IS_DRAFT="${{ github.event.pull_request.draft }}" | |
| REVIEWER_MENTION=$(get_discord_mention "$REVIEWER") | |
| PR_AUTHOR_MENTION=$(get_discord_mention "$PR_AUTHOR") | |
| if [ "$IS_DRAFT" = "true" ]; then | |
| echo "Draft PR review notification is skipped." | |
| exit 0 | |
| fi | |
| case "$REVIEW_STATE" in | |
| approved) | |
| REVIEWS=$(curl -s \ | |
| -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "$REPO_API_URL/pulls/$PR_NUMBER/reviews?per_page=100") | |
| APPROVED_REVIEW_COUNT=$(echo "$REVIEWS" | jq ' | |
| group_by(.user.login) | |
| | map(max_by(.submitted_at)) | |
| | map(select(.state == "APPROVED")) | |
| | length | |
| ') | |
| if [ "$APPROVED_REVIEW_COUNT" -ne 2 ]; then | |
| echo "Current approved review count is $APPROVED_REVIEW_COUNT. Notification is skipped." | |
| exit 0 | |
| fi | |
| TITLE="✅ PR 머지 가능 상태가 되었어요" | |
| DESC="**#$PR_NUMBER $PR_TITLE** PR이 2명 이상의 Approve를 받아 머지 가능 상태가 되었습니다."$'\n\n'"**PR 작성자:** $PR_AUTHOR_MENTION" | |
| COLOR=5763719 | |
| ;; | |
| changes_requested) | |
| TITLE="🛠️ 수정 요청이 남겨졌어요" | |
| DESC="$REVIEWER_MENTION 님이 **#$PR_NUMBER $PR_TITLE** PR에 변경 요청을 남겼습니다."$'\n\n'"**PR 작성자:** $PR_AUTHOR_MENTION" | |
| COLOR=15158332 | |
| ;; | |
| commented) | |
| TITLE="💬 PR 리뷰 코멘트가 등록되었어요" | |
| DESC="$REVIEWER_MENTION 님이 **#$PR_NUMBER $PR_TITLE** PR에 리뷰 코멘트를 남겼습니다."$'\n\n'"**PR 작성자:** $PR_AUTHOR_MENTION" | |
| COLOR=3447003 | |
| ;; | |
| *) | |
| TITLE="📣 PR 리뷰 이벤트가 발생했어요" | |
| DESC="$REVIEWER_MENTION 님이 **#$PR_NUMBER $PR_TITLE** PR에 리뷰를 제출했습니다."$'\n\n'"**PR 작성자:** $PR_AUTHOR_MENTION" | |
| COLOR=9807270 | |
| ;; | |
| esac | |
| URL="${{ github.event.pull_request.html_url }}" | |
| AUTHOR="$REVIEWER" | |
| elif [ "$EVENT_NAME" = "issues" ]; then | |
| ISSUE_TITLE="${{ github.event.issue.title }}" | |
| ISSUE_NUMBER="${{ github.event.issue.number }}" | |
| AUTHOR="${{ github.event.issue.user.login }}" | |
| AUTHOR_MENTION=$(get_discord_mention "$AUTHOR") | |
| case "$ACTION" in | |
| opened) | |
| TITLE="📌 새로운 이슈가 등록되었어요" | |
| DESC=$'새로운 작업이 등록되었습니다. 라벨을 확인하고 작업 범위를 정리해주세요.\n\n'"**Issue:** #$ISSUE_NUMBER $ISSUE_TITLE"$'\n'"**작성자:** $AUTHOR_MENTION" | |
| COLOR=15105570 | |
| ;; | |
| esac | |
| URL="${{ github.event.issue.html_url }}" | |
| fi | |
| send_discord_message |