Skip to content

PR 봇 Slack에서 Discord로 이관 (봇 토큰·스레드 재설계) - #661

Merged
sevineleven merged 7 commits into
devfrom
infra/653-discord-pr-bot
Jul 3, 2026
Merged

PR 봇 Slack에서 Discord로 이관 (봇 토큰·스레드 재설계)#661
sevineleven merged 7 commits into
devfrom
infra/653-discord-pr-bot

Conversation

@sevineleven

@sevineleven sevineleven commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Situation

Task

  • slack-pr-bot.yml 전체를 Discord 로 재설계한다. Slack 의 ts(메시지 타임스탬프 = 메시지 ID이자 스레드 앵커) 메커니즘이 Discord 와 근본적으로 다르다. Discord 스레드는 암묵적이 아니라 명시적으로 만들어야 하고, 그래서 webhook 만으론 부족해 봇 토큰이 필요하다.

Action

메커니즘 재설계

  • 부모 메시지: Slack chat.postMessage(→ts)를 Discord POST /channels/{ch}/messages(→message.id)로. 그 메시지에서 POST .../messages/{id}/threads 로 스레드를 명시 생성해 thread.id 를 얻는다.
  • 상태 지속: 기존엔 {channel, ts} 를 PR 코멘트 메타로 저장했다. 이제 {channel_id, message_id, thread_id} 를 저장한다. 마커도 slack-pr-bot 에서 discord-pr-bot 으로.
  • 부모 수정(리뷰어·머지상태 변경)은 PATCH .../messages/{message_id}, 스레드 답글(리뷰요청/해제·새커밋·머지)은 POST /channels/{thread_id}/messages.

마크다운·멘션 변환

Slack Discord
<url|text> [text](url)
*bold* **bold**
<!channel> @here (allowed_mentions everyone)
<@slackid> <@discordid>

봇 vs webhook (선택)

방식 PR 봇에 맞나
webhook 발행·수정·기존 스레드 전송은 되나 스레드 생성 불가 → 부적합
봇 토큰 (채택) 스레드 생성·수정 전부 가능. text 채널 + 스레드 UX 실현

부수 정리

  • SLACK_USER_MAP(워크플로에 하드코딩, 1o18z 포함) → DISCORD_USER_MAP 시크릿. SLACK_CHANNEL_IDDISCORD_PR_CHANNEL_ID.
  • 시크릿은 레포 레벨로 둔다(기존 DISCORD_* 와 동일). 현 slack 봇도 실제론 레포 레벨을 읽고 있었고, PR 봇은 환경 보호규칙에 막히면 안 되므로 환경 격리를 쓰지 않는다.
  • main 직접푸시 긴급알림 job 도 Discord(@here)로 이관.
  • DISCORD_USER_MAP${VAR:-{}} 의 bash stray brace 버그(#660과 같은 함정)를 피해 guard 로 방어.

Result

  • 검증(드라이푸딩): 이 PR 을 여는 것 자체가 pull_request: opened 로 새 워크플로(head 브랜치 버전)를 돌려 #be-pr 에 부모 메시지 + 스레드를 만든다. slack-pr-bot.yml 은 head 에서 삭제돼 안 돈다.
  • 클린 컷오버: 진행 중이던 기존 PR 은 옛 Slack 메타(slack-pr-bot)라 새 봇이 못 찾는다. 신규 PR 부터 Discord 로 붙는다.
  • 후속(별개):
    • 아직 파리티 버전 - PR title·branch 를 셸에 직접 보간하는 스크립트 인젝션 지점이 남아 있어, env 분리 하드닝을 머지 전(또는 CodeRabbit 대응)에 얹는다.
    • 봇 권한으로 열어둔 리액션·스레드 자동정리·부모 고정 등 편의 기능은 에픽 Slack → Discord 마이그레이션 #649 의 후속 이슈로 분리한다.

연관 이슈

Summary by CodeRabbit

  • New Features

    • PR 이벤트와 main으로의 직접 push에 대해 Discord 알림을 전송하도록 변경되었습니다.
    • PR 상태/리뷰 요청·취소/커밋 동기화/종료 여부에 따라 Discord 부모 메시지와 스레드 답글이 자동으로 갱신됩니다.
    • 관련 Discord 메시지·스레드 메타데이터를 PR 코멘트에 저장해 후속 알림을 연동합니다.
  • Chores

    • 기존 Slack 기반 PR 알림 워크플로우는 제거되어 더 이상 동작하지 않습니다.

- slack-pr-bot.yml → discord-pr-bot.yml 재작성. Slack ts(부모+암묵 스레드) 메커니즘을 Discord message_id + 명시적 스레드로 재설계
- 부모 메시지 발행 후 그 메시지에서 스레드 생성(봇 토큰), message_id·thread_id 를 PR 코멘트 메타로 저장. 리뷰요청/해제·새커밋·머지는 스레드 답글, 리뷰어·머지상태 변경은 부모 메시지 PATCH 수정
- SLACK_USER_MAP(1o18z 포함) → DISCORD_USER_MAP 시크릿, SLACK_CHANNEL_ID → DISCORD_PR_CHANNEL_ID
- <url|text>→[text](url), *x*→**x**, <!channel>→@here 로 Discord 마크다운 변환
- main 직접푸시 긴급알림도 Discord(@here, DISCORD_PR_CHANNEL_ID)로
- DISCORD_USER_MAP 은 ${VAR:-{}} stray brace 버그 회피 위해 guard 로 방어
- 직전 커밋(0218928)이 slack-pr-bot.yml 삭제만 담고 신규 워크플로를 누락해 보정
- PR 봇 Discord 이관 본체: 부모 메시지+스레드 생성, 리뷰요청/해제·새커밋·머지 스레드 답글, 부모 메시지 수정, main 직접푸시 @here 알림
@sevineleven sevineleven added the infra 운영 환경 (IaC·클라우드 리소스·secret·배포 workflow) label Jul 3, 2026
@sevineleven sevineleven linked an issue Jul 3, 2026 that may be closed by this pull request
5 tasks
@sevineleven sevineleven self-assigned this Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@sevineleven, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 2ef2888f-a402-4e13-ae14-843dabdd5d2d

📥 Commits

Reviewing files that changed from the base of the PR and between 007ce4a and 3d142e5.

📒 Files selected for processing (1)
  • .github/workflows/discord-pr-bot.yml

Walkthrough

discord-pr-bot.yml 워크플로우가 추가되어 PR 열림·리뷰 요청·리뷰 요청 해제·동기화·닫힘 이벤트와 main 직접 push를 Discord 알림으로 처리한다. PR 코멘트에는 Discord 메시지와 스레드 메타데이터를 숨겨진 주석으로 저장한다.

Changes

Discord PR 봇 워크플로우

Layer / File(s) Summary
트리거, 권한 및 PR 데이터/메타 복원
.github/workflows/discord-pr-bot.yml
pull_request/push 트리거, concurrency, job 권한을 정의하고 PR 핵심 데이터와 기존 Discord 메타를 PR 코멘트에서 복원한다.
부모 메시지와 스레드 생성
.github/workflows/discord-pr-bot.yml
opened 또는 ready_for_review 시점에 Discord 부모 메시지를 생성하고 스레드를 만들어 식별자를 확보한다.
PR 코멘트 메타 저장
.github/workflows/discord-pr-bot.yml
생성된 Discord 식별자와 초기 리뷰어 목록을 숨겨진 HTML 주석으로 PR 코멘트에 저장한다.
부모 메시지 갱신
.github/workflows/discord-pr-bot.yml
기존 메타가 있으면 PR 상태 변경에 맞춰 부모 메시지를 PATCH로 갱신한다.
스레드 답글과 direct push 경고
.github/workflows/discord-pr-bot.yml
이벤트별로 스레드 답글을 보내고, main 직접 push는 연결 PR이 없을 때만 Discord 경고를 전송한다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHub as GitHub PR Event
  participant Workflow as discord-pr-bot.yml
  participant PRComments as PR Comments
  participant Discord as Discord API

  GitHub->>Workflow: pull_request(opened/review_requested/edited/synchronize/closed)
  Workflow->>PRComments: 기존 discord-pr-bot 메타 조회
  PRComments-->>Workflow: message_id/thread_id/channel_id/initial_reviewers
  alt opened && 메타 없음
    Workflow->>Discord: 부모 메시지 POST
    Discord-->>Workflow: message_id
    Workflow->>Discord: 스레드 생성
    Discord-->>Workflow: thread_id
    Workflow->>PRComments: 메타데이터 저장
  else 메타 존재 && opened 아님
    Workflow->>Discord: 부모 메시지 PATCH
    Workflow->>Discord: 스레드 reply POST
  end

  GitHub->>Workflow: push(main)
  Workflow->>GitHub: commits/{sha}/pulls 조회
  alt 연결 PR 없음
    Workflow->>Discord: `@here` direct push 경고 POST
  end
Loading

Assessment against linked issues

Objective Addressed Explanation
PR opened 알림 + 메시지 ID 저장 [#653]
리뷰어 멘션 [#653]
review_requested/removed 반영 [#653]
merged 알림(스레드 갱신) [#653]
PR 코멘트 메타데이터 방식 이전 [#653]

Poem

Slack의 ts는 퇴장,
Discord의 message_id가 입장.
리뷰와 머지, direct push까지,
주석 속 메타로 잘 붙잡았네요.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch infra/653-discord-pr-bot

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

- 메타 주석이 없는 신규 PR 은 grep -oP 가 매칭 0건→exit 1, set -eo pipefail 이 스텝을 실패시킴
- grep 에 || true 방어 + META_JSON 이 있을 때만 jq 파싱(빈 입력 jq 파싱 에러 회피)
- 전수조사 반영. "정상 입력이 크래시하던/할 수 있던" 지점 방어
- 스크립트 인젝션: PR 제목·브랜치명을 run 에 ${{ }} 직접 보간하던 것을 env 로 분리($PR_TITLE·$HEAD_REF·$BASE_REF). 제목의 백틱·$()·따옴표가 실행/크래시되던 문제 (git 브랜치명도 셸 메타문자 허용)
- GitHub API 에러객체 방어: comments·commits·pulls 파싱 jq 를 objects 필터·type 가드로 감싸 배열 아닌 응답(rate limit·5xx)에도 안 죽게

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
.github/workflows/discord-pr-bot.yml (1)

265-342: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

mention_discord_user·build_reviewer_text·build_issue_text·build_summary 4개 함수가 post_parent 스텝(Line 126-197)과 거의 그대로 중복됩니다.

두 벌이 손으로 동기화되어야 해서, 실제로 이미 미묘하게 갈라져 있습니다. 예를 들어 매핑 미존재 시 fallback이 post_parent는 @$github_id(Line 133), update는 $github_id(Line 280)로 다릅니다 — 의도된 차이가 아니라면 스레드/부모 표기가 엇갈립니다.

공용 로직을 .github/scripts/discord-pr.sh 같은 파일로 추출해 두 스텝에서 source 하거나, composite action으로 묶는 것을 권합니다. 100+ 줄 중복이 사라지고 표기 불일치도 근본적으로 예방됩니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/discord-pr-bot.yml around lines 265 - 342, The helper
logic for Discord message formatting is duplicated between the parent update
step and the post_parent step, and the two copies have already drifted (for
example, the fallback mention format differs). Extract mention_discord_user,
build_reviewer_text, build_issue_text, and build_summary into a shared script or
composite action and have both steps source/use that single implementation to
keep behavior consistent and remove the duplicated block.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/discord-pr-bot.yml:
- Around line 5-11: The workflow in discord-pr-bot.yml skips creating the parent
Discord message for draft PRs because it only runs on opened and checks
github.event.pull_request.draft == false in the parent-message path. Add
ready_for_review to the pull_request event types and update the parent message
creation condition in the Discord bot flow so draft PRs create the thread when
they are marked ready; use the existing trigger block and the parent-message
logic around github.event.pull_request.draft to locate the change.
- Around line 206-232: Discord message content can exceed the 2000-character
limit during both creation and updates, causing the POST/PATCH calls in the
Discord bot workflow to fail and leave MESSAGE_ID/OK empty. Add truncation or
safe clipping before building/sending TEXT in the message construction flow, and
apply the same limit handling to the update path as well. Use the existing
message assembly around TITLE_LINK, ISSUE_TEXT, SUMMARY, and the curl/jq send
logic to ensure the final content stays around 1900 characters.
- Around line 471-476: PR 매칭이 closed PR 목록을 20개로만 제한하는 `PR_LIST`/`PR_COUNT` 로직
때문에 최신 정상 머지 PR이 목록 밖으로 밀려 오탐이 발생할 수 있습니다.
`.github/workflows/discord-pr-bot.yml`의 해당 curl/jq 조회를 수정해 `per_page=100`으로 범위를
넓히거나, `github.sha` 기준으로 `/commits/{sha}/pulls`를 사용해 직접 매칭하도록 `PR_LIST` 계산 방식을
바꾸세요. `PR_COUNT`가 실제 머지된 PR을 안정적으로 잡는지 `jq` 필터와 함께 확인해 주세요.
- Around line 16-19: The top-level permissions in this workflow are too broad
and should be moved to job scope. Update the discord-pr-bot workflow so the
global permissions block is empty, then set notify-discord to use only issues:
write and alert-direct-push to use only pull-requests: read, keeping permission
names aligned with those job responsibilities.

---

Nitpick comments:
In @.github/workflows/discord-pr-bot.yml:
- Around line 265-342: The helper logic for Discord message formatting is
duplicated between the parent update step and the post_parent step, and the two
copies have already drifted (for example, the fallback mention format differs).
Extract mention_discord_user, build_reviewer_text, build_issue_text, and
build_summary into a shared script or composite action and have both steps
source/use that single implementation to keep behavior consistent and remove the
duplicated block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 0e528144-7f5a-450e-bf19-f4b613ed803e

📥 Commits

Reviewing files that changed from the base of the PR and between 4cb0aae and 3b5886e.

📒 Files selected for processing (2)
  • .github/workflows/discord-pr-bot.yml
  • .github/workflows/slack-pr-bot.yml
💤 Files with no reviewable changes (1)
  • .github/workflows/slack-pr-bot.yml

Comment thread .github/workflows/discord-pr-bot.yml
Comment thread .github/workflows/discord-pr-bot.yml Outdated
Comment thread .github/workflows/discord-pr-bot.yml
Comment thread .github/workflows/discord-pr-bot.yml Outdated
@github-actions
github-actions Bot requested a review from m-a-king July 3, 2026 03:20
- ready_for_review 트리거 추가 + 부모 생성 조건에 포함 → draft 로 연 PR 이 ready 전환 시 알림 생성 (기존엔 영영 안 옴)
- 최소권한: 상단 permissions 를 {} 로 비우고 job 단위로만 부여 (notify-discord=issues:write, alert-direct-push=pull-requests:read) — zizmor excessive-permissions
- Discord 2000자 제한 방어: 부모·수정 content 를 1900자로 자름 (긴 PR 요약이 400 내던 것)
- @here 오탐 제거: closed 20건 윈도우 스캔 → commits/{sha}/pulls 로 그 커밋 PR 직접 조회
- 멘션 fallback drift 정렬: update 스텝만 @없이 login 표기하던 것을 @login 으로 통일

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/discord-pr-bot.yml:
- Around line 479-485: The commit-to-PR lookup in the Discord PR bot workflow is
treating GitHub API failures as a zero-result scan, which can misclassify errors
as direct pushes. Update the `PR_LIST`/`PR_COUNT` step to check the HTTP
response from the `commits/{sha}/pulls` request in
`.github/workflows/discord-pr-bot.yml` (for example via `curl -f` or explicit
status handling), and ensure non-2xx responses do not fall through to `jq` as
`pr_count=0`; instead, stop the notification path or skip the alert when the
lookup fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 3983fbf2-db4c-4950-8d8f-b3e45393631c

📥 Commits

Reviewing files that changed from the base of the PR and between 3b5886e and 007ce4a.

📒 Files selected for processing (1)
  • .github/workflows/discord-pr-bot.yml

Comment thread .github/workflows/discord-pr-bot.yml Outdated
@sevineleven

Copy link
Copy Markdown
Collaborator Author

CodeRabbit nitpick(헬퍼 함수 4개 중복) 관련:

  • 지적하신 fallback drift(update 스텝만 @ 없이 login 표기)는 007ce4a 에서 @login 으로 정렬해 post_parent·reply 와 통일했습니다.
  • 공용 스크립트 추출은 이번엔 보류(declined) 합니다 — 스텝 간 셸 격리상 source 하려면 repo checkout + contents: read 권한이 필요해져 방금 적용한 최소권한(permissions: {} + job 단위)과 충돌합니다. composite action 으로 묶는 편이 맞는데 이는 별도 리팩터입니다. 중복 자체는 에픽 Slack → Discord 마이그레이션 #649 후속(편의 패치)에서 composite action 검토 시 함께 정리하겠습니다.

@sevineleven
sevineleven marked this pull request as draft July 3, 2026 04:55
@sevineleven
sevineleven marked this pull request as ready for review July 3, 2026 04:55
- issues:write 만으론 PR(=issue) 코멘트 생성이 403 (대상이 PR 이라 pull-requests write 필요)
- CodeRabbit 최소권한 제안이 이 케이스엔 과했음. metadata 코멘트 저장이 실패해 스레드 후속 연동이 끊기던 것 정정
- 연관 이슈 상태 조회용 issues:read 유지
@sevineleven

Copy link
Copy Markdown
Collaborator Author

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다. (수동 링크 - 최초 저장이 권한 403 으로 실패했던 것 보정)

- commits/{sha}/pulls 가 에러 JSON(401/403/rate limit)을 주면 jq 가 배열 아님→0 으로 봐 정상 머지를 직접푸시로 오인, @here 오탐 발송
- HTTP 200 아니면 pr_count=skip 후 exit → 알림 스텝 '== 0' 조건에 안 걸려 생략(fail-safe)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infra 운영 환경 (IaC·클라우드 리소스·secret·배포 workflow)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PR 봇 Discord 이관 (slack-pr-bot.yml)

2 participants