Skip to content

배포·승격 알림 Slack에서 Discord 웹훅으로 이관 - #659

Merged
sevineleven merged 4 commits into
devfrom
infra/651-discord-deploy-promote-alerts
Jul 3, 2026
Merged

배포·승격 알림 Slack에서 Discord 웹훅으로 이관#659
sevineleven merged 4 commits into
devfrom
infra/651-discord-deploy-promote-alerts

Conversation

@sevineleven

@sevineleven sevineleven commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Situation

  • 팀 커뮤니케이션 채널을 Slack 에서 Discord 로 옮기기로 했다(Slack → Discord 마이그레이션 #649 epic). 그 첫 조각으로 CI 알림을 옮긴다.
  • 배포·승격의 성공/실패/릴리즈 알림이 GitHub Actions 에서 Slack 봇(chat.postMessage)으로 나가고 있었다.

Task

  • deploy.yml·promote.yml 의 Slack 알림을 Discord 로 이관한다. 지금 UX(배포자 멘션·커밋/로그 링크·환경 브랜딩)는 그대로 유지한다.
  • secret 이 아직 없는 상태로 머지돼도 배포가 깨지지 않게 한다.

Action

  • Slack chat.postMessage(bot token + channel) 를 Discord 웹훅 POST(DISCORD_WEBHOOK_URL)로 교체했다. 배포·승격·릴리즈 알림은 모두 같은 알림 채널로 간다.
  • 배포자 멘션 맵을 SLACK_USER_MAP(워크플로에 하드코딩)에서 DISCORD_USER_MAP(secret)으로 옮겼다. 매핑이 없으면 GitHub 로그인 이름으로 폴백한다(핑은 안 감). 멘션 대상은 현재 활성 멤버 m-a-king·sevineleven 만 둔다.
  • 메시지 포맷을 Discord 마크다운으로 바꿨다: 링크 <url|text>[text](url) 로, 멘션 <@id> 는 유지, allowed_mentions 로 유저 핑을 명시.
  • 웹훅 비면 skip 가드를 넣었다: DISCORD_WEBHOOK_URL 이 비어 있으면 알림 step 을 조용히 건너뛴다. secret 없이 머지돼도 배포 잡이 안 깨진다.
  • admin IP 게이트용 SLACK_ADMIN_SIGNING_SECRET 은 알림과 무관한 별개 마이그레이션(Admin 슬래시커맨드 Discord 이관 (Ed25519 서명검증) #654)이라 건드리지 않았다.

웹훅 vs 봇 (선택)

방식 이관에 맞나
웹훅 (채택) 알림은 단방향(쏘기만) → 봇 불필요, 이름·아바타는 웹훅 설정으로 "허거덩" 유지
봇(Application) 슬래시커맨드처럼 "받아서 응답"할 때만 필요 (admin #654 에서)

Result


연관 이슈


Updates

리뷰어 자동 지정 정리

  • 리뷰 요청이 노이즈가 될 수 있어 auto-reviewer 워크플로의 팀 풀에서 1o18z 를 뺐다. 이제 CodeRabbit 리뷰 후 m-a-king·sevineleven 사이에서만 리뷰어가 지정된다. 필요하면 직접 리뷰 요청한다. (679b10f)

@sevineleven sevineleven added the infra 운영 환경 (IaC·클라우드 리소스·secret·배포 workflow) label Jul 3, 2026
@sevineleven sevineleven self-assigned this Jul 3, 2026
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

Slack 스레드 연동용 메타데이터입니다. slack-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Slack 알림 연동이 끊깁니다.

@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: 15 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: 11ec7200-8a4c-4a1b-85eb-8f0f2dd86272

📥 Commits

Reviewing files that changed from the base of the PR and between 5085a15 and 890362e.

📒 Files selected for processing (3)
  • .github/workflows/auto-reviewer.yml
  • .github/workflows/deploy.yml
  • .github/workflows/promote.yml

Walkthrough

deploy.yml과 promote.yml의 Slack 알림(chat.postMessage)을 Discord 웹훅 전송으로 교체했다. DISCORD_USER_MAP으로 액터 멘션을 매핑하고, 웹훅 미설정 시 알림을 스킵하며, continue-on-error는 유지된다. 배포 성공/실패/릴리즈, 승격 성공/실패 알림 모두 대상이다.

Changes

Slack → Discord 알림 전환

Layer / File(s) Summary
배포 성공 알림
.github/workflows/deploy.yml
웹훅 존재 확인, DISCORD_USER_MAP 멘션 매핑, 커밋 첫 줄/URL/로그 URL을 조합한 메시지를 Discord로 전송한다.
배포 실패 알림
.github/workflows/deploy.yml
동일한 매핑 방식에 실패 원인(CAUSE)을 포함해 Discord로 전송한다.
릴리즈 성공 알림
.github/workflows/deploy.yml
태그와 릴리즈 URL을 포함한 메시지를 Discord 웹훅으로 전송한다.
승격 성공 알림
.github/workflows/promote.yml
웹훅/멘션 매핑을 설정하고, 변경 없음(SHA 동일) 또는 실제 승격 완료 케이스에 따라 메시지를 분기해 Discord로 전송한다.
승격 실패 알림
.github/workflows/promote.yml
실행 경로, 커밋 대상, 워크플로 로그 링크를 포함한 실패 메시지를 Discord로 전송한다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
배포 성공/실패/릴리즈 알림 Discord 전송 (#651)
SLACK_USER_MAP → DISCORD_USER_MAP 멘션 매핑 (#651, #652)
continue-on-error 유지 (#651)
승격 성공/실패 알림 Discord 전송 (#652)

CI 워크플로만 손보는 깔끔한 작업이네요, YAML 인덴트 지옥 속에서도 길을 잃지 않으셨군요. 👏 다만 DISCORD_WEBHOOK_URL이 비어있을 때 스킵하는 로직이 각 step마다 반복되는데, 재사용 가능한 composite action으로 뽑아두면 향후 채널이 또 바뀔 때(있어서는 안 되겠지만) 유지보수가 훨씬 편해질 것 같습니다. GitHub Actions의 Composite actions 문서를 참고해보세요.

🚥 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/651-discord-deploy-promote-alerts

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.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/deploy.yml (1)

619-654: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Discord 알림 3곳 모두 run: 스크립트에 GitHub 컨텍스트 값을 직접 템플릿 보간 — 스크립트 인젝션 경고 (zizmor)

github.actor(628, 665, 768번 줄, error 등급)와 needs.resolve.outputs.branch/domain/ref(634, 636, 650, 671, 673, 712, 772번 줄, info 등급) 값이 ${{ }} 문법으로 run: 셸 스크립트 안에 직접 삽입되고 있습니다. GitHub Actions는 이 값을 셸 실행 전에 문자열로 치환하기 때문에, 값에 백틱·따옴표·세미콜론 등이 포함되면 임의 명령 실행으로 이어질 수 있습니다.

브랜치명(needs.resolve.outputs.branchworkflow_run.head_branch 기반)이나 GitHub 로그인명은 일반적으로 제약이 있지만, GitHub Actions 공식 보안 하드닝 가이드에서도 이런 값은 env:로 전달 후 셸 변수로 참조하도록 권장합니다. 이미 DISCORD_WEBHOOK_URL/DISCORD_USER_MAPenv:로 안전하게 넘기고 있으니, 나머지 값도 동일하게 처리하면 됩니다.

🛡️ 성공 알림 step 기준 예시 (실패/릴리즈 알림도 동일 패턴 적용)
       - name: Notify Discord on success
         if: success()
         continue-on-error: true
         shell: bash
         env:
           DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
           DISCORD_USER_MAP: ${{ secrets.DISCORD_USER_MAP }}
+          GH_ACTOR: ${{ github.actor }}
+          DEPLOY_REF: ${{ needs.resolve.outputs.ref }}
+          DEPLOY_BRANCH: ${{ needs.resolve.outputs.branch }}
+          DEPLOY_DOMAIN: ${{ needs.resolve.outputs.domain }}
         run: |
           [ -z "$DISCORD_WEBHOOK_URL" ] && { echo "DISCORD_WEBHOOK_URL 미설정 — 알림 생략"; exit 0; }
-          ACTOR="${{ github.actor }}"
+          ACTOR="$GH_ACTOR"
           DISCORD_ID=$(echo "${DISCORD_USER_MAP:-{}}" | jq -r --arg login "$ACTOR" '.[$login] // empty')
           ACTOR_MENTION="${DISCORD_ID:+<@$DISCORD_ID>}"
           ACTOR_MENTION="${ACTOR_MENTION:-$ACTOR}"

-          SHORT_SHA="${{ needs.resolve.outputs.ref }}"
+          SHORT_SHA="$DEPLOY_REF"
           SHORT_SHA="${SHORT_SHA:0:7}"
-          COMMIT_URL="https://github.com/${{ github.repository }}/commit/${{ needs.resolve.outputs.ref }}"
+          COMMIT_URL="https://github.com/${{ github.repository }}/commit/$DEPLOY_REF"
           ...
           TEXT=$(printf '✅ `%s` 배포 성공!\n• 경로: `%s` 브랜치 → %s (%s)\n• 배포자: %s\n• 커밋: [%s](%s)  %s\n• [워크플로우 로그](%s)' \
-            "$TARGET" "${{ needs.resolve.outputs.branch }}" "$TARGET" "${{ needs.resolve.outputs.domain }}" "$ACTOR_MENTION" "$SHORT_SHA" "$COMMIT_URL" "$COMMIT_MSG" "$RUN_URL")
+            "$TARGET" "$DEPLOY_BRANCH" "$TARGET" "$DEPLOY_DOMAIN" "$ACTOR_MENTION" "$SHORT_SHA" "$COMMIT_URL" "$COMMIT_MSG" "$RUN_URL")

${{ github.repository }}는 리포지토리 슬러그 형식이 고정돼 있어 상대적으로 안전하지만, 일관성을 위해 필요 시 GITHUB_REPOSITORY 기본 환경변수를 활용해도 됩니다. zizmorerror/info 등급으로 총 12곳을 짚었으니, 이번 기회에 세 알림 step 모두 같은 방식으로 정리하는 걸 추천드려요. 관련 개념은 GitHub 공식 문서의 "Security hardening for GitHub Actions – Understanding the risk of script injections"를 참고하시면 좋습니다.

Also applies to: 656-717, 756-775

🤖 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/deploy.yml around lines 619 - 654, The Discord
notification steps are vulnerable because GitHub context values are being
interpolated directly into the shell script in the Notify Discord steps. Move
all dynamic values used in the success/failure/release notifications, especially
github.actor and needs.resolve.outputs.branch/domain/ref, into env: variables
and reference only shell variables inside the run script. Apply the same pattern
consistently in the Discord notify blocks so the send logic in the bash snippets
stays safe and uses the existing jq/curl flow without direct ${{ }} templating.

Source: Linters/SAST tools

🧹 Nitpick comments (2)
.github/workflows/deploy.yml (1)

652-654: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Discord webhook 응답 코드 미확인 — 전송 실패가 조용히 묻힐 수 있어요

curl -s만 사용하고 -f/--fail나 HTTP 상태 코드 체크가 없어서, Discord가 4xx/5xx를 반환해도 step은 그대로 성공 처리됩니다. continue-on-error: true와 맞물려 배포 자체엔 영향 없지만, 알림이 실제로 안 갔는지 로그로 확인할 방법이 없어요.

♻️ 개선 예시
-          curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-            -H "Content-Type: application/json; charset=utf-8" \
-            --data "$(jq -n --arg content "$TEXT" '{content:$content, allowed_mentions:{parse:["users"]}}')"
+          HTTP_CODE=$(curl -s -o /tmp/discord_resp.json -w '%{http_code}' -X POST "$DISCORD_WEBHOOK_URL" \
+            -H "Content-Type: application/json; charset=utf-8" \
+            --data "$(jq -n --arg content "$TEXT" '{content:$content, allowed_mentions:{parse:["users"]}}')")
+          [ "$HTTP_CODE" -lt 300 ] || echo "::warning::Discord 알림 전송 실패 (HTTP $HTTP_CODE) $(cat /tmp/discord_resp.json)"

급한 이슈는 아니라서 여유 될 때 반영해도 좋습니다.

Also applies to: 714-716, 773-775

🤖 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/deploy.yml around lines 652 - 654, The Discord webhook
notification step currently ignores HTTP failures, so a 4xx/5xx response can
look successful. Update the curl invocation used for the Discord POST in the
workflow to fail on non-2xx responses or explicitly check the HTTP status code,
and keep the logging clear when the request is rejected. Apply the same fix to
each duplicated webhook block in the workflow so all notification steps behave
consistently.
.github/workflows/promote.yml (1)

197-199: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Discord 웹훅 curl 호출에 타임아웃 미설정

외부 API(Discord) 응답이 지연되면 이 스텝이 예상보다 오래 걸릴 수 있습니다. continue-on-error: true로 job 실패는 막아주지만, hang 상태로 러너 시간을 소모하는 건 막지 못합니다. --max-time(또는 --connect-timeout) 옵션을 추가하면 좋겠습니다.

⏱️ 제안 수정
-          curl -s -X POST "$DISCORD_WEBHOOK_URL" \
+          curl -s --max-time 10 -X POST "$DISCORD_WEBHOOK_URL" \
             -H "Content-Type: application/json; charset=utf-8" \
             --data "$(jq -n --arg content "$TEXT" '{content:$content, allowed_mentions:{parse:["users"]}}')"

deploy.yml에도 같은 패턴이 있어 함께 적용하면 좋겠습니다.

Also applies to: 220-222

🤖 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/promote.yml around lines 197 - 199, The Discord webhook
curl call in the promotion workflow can hang indefinitely because it has no
timeout. Update the curl invocation in the webhook notification step to include
a timeout option such as --max-time (and optionally --connect-timeout) so the
job fails fast on slow Discord responses; apply the same change to the matching
webhook call in the deploy workflow if it uses the same curl pattern.
🤖 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/promote.yml:
- Line 181: The workflow step is directly interpolating github.actor inside the
shell script, which should be moved to an env mapping instead. Update the
relevant job step to pass ACTOR via env from github.actor, and remove the inline
ACTOR assignment in the run block so the shell only reads the environment
variable. Use the existing promotion/notification step around the ACTOR usage as
the place to make this change.

---

Outside diff comments:
In @.github/workflows/deploy.yml:
- Around line 619-654: The Discord notification steps are vulnerable because
GitHub context values are being interpolated directly into the shell script in
the Notify Discord steps. Move all dynamic values used in the
success/failure/release notifications, especially github.actor and
needs.resolve.outputs.branch/domain/ref, into env: variables and reference only
shell variables inside the run script. Apply the same pattern consistently in
the Discord notify blocks so the send logic in the bash snippets stays safe and
uses the existing jq/curl flow without direct ${{ }} templating.

---

Nitpick comments:
In @.github/workflows/deploy.yml:
- Around line 652-654: The Discord webhook notification step currently ignores
HTTP failures, so a 4xx/5xx response can look successful. Update the curl
invocation used for the Discord POST in the workflow to fail on non-2xx
responses or explicitly check the HTTP status code, and keep the logging clear
when the request is rejected. Apply the same fix to each duplicated webhook
block in the workflow so all notification steps behave consistently.

In @.github/workflows/promote.yml:
- Around line 197-199: The Discord webhook curl call in the promotion workflow
can hang indefinitely because it has no timeout. Update the curl invocation in
the webhook notification step to include a timeout option such as --max-time
(and optionally --connect-timeout) so the job fails fast on slow Discord
responses; apply the same change to the matching webhook call in the deploy
workflow if it uses the same curl pattern.
🪄 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: e4769801-6a27-4d90-bc66-708c07b5efc0

📥 Commits

Reviewing files that changed from the base of the PR and between 9e00e3e and 5085a15.

📒 Files selected for processing (2)
  • .github/workflows/deploy.yml
  • .github/workflows/promote.yml

Comment thread .github/workflows/promote.yml Outdated
@github-actions
github-actions Bot requested a review from m-a-king July 3, 2026 00:49
- deploy.yml(배포 성공/실패/릴리즈)·promote.yml(승격 성공/실패)의 Slack chat.postMessage 를 Discord 웹훅 POST(DISCORD_WEBHOOK_URL)로 교체
- 배포자 멘션 맵을 SLACK_USER_MAP(하드코딩)에서 DISCORD_USER_MAP(secret)으로. 매핑 없으면 GitHub 로그인 이름으로 폴백(핑은 안 감). 멘션 대상은 현재 활성 멤버 m-a-king·sevineleven 만
- 메시지 포맷을 Discord 마크다운으로: 링크 <url|text> 를 [text](url) 로, 멘션 <@id> 유지, allowed_mentions 로 유저 핑 명시
- DISCORD_WEBHOOK_URL 비면 skip 하는 가드 추가 — secret 미설정 상태로 머지돼도 배포가 안 깨진다
- admin IP 게이트용 SLACK_ADMIN_SIGNING_SECRET 은 알림과 무관한 별개 마이그레이션(#654)이라 그대로 둠
- 리뷰 요청이 노이즈가 될 수 있어 auto-reviewer 워크플로의 팀 풀에서 1o18z 를 뺀다 — 필요하면 직접 리뷰 요청한다. 이제 m-a-king·sevineleven 사이에서만 자동 지정된다
@sevineleven
sevineleven force-pushed the infra/651-discord-deploy-promote-alerts branch from 299dc43 to 679b10f Compare July 3, 2026 00:51
- CodeRabbit(zizmor template-injection) 지적 반영: run 블록에 ${{ github.actor }} 를 직접 보간하던 것을 env: ACTOR 로 옮기고 셸은 $ACTOR 만 읽게 함
- deploy.yml 3개(성공·실패·릴리즈)·promote.yml 2개(성공·실패) 알림 스텝 전부 동일 패턴으로 통일
- 값 자체는 GitHub 로그인명이라 위험이 크진 않으나, 표현식과 셸을 분리하는 Actions script injection 권장 패턴에 맞춤
- CodeRabbit review body 반영 (deploy.yml·promote.yml 알림 스텝)
- env 분리 확장: needs.resolve.outputs.ref/branch/domain 도 run 직접 보간에서 env 로 옮김 (브랜치명은 백틱·$ 등 셸 메타문자를 허용해 인젝션 벡터 - zizmor Major)
- curl 타임아웃: --max-time 10 추가로 Discord 지연 시 러너 hang 방지
- 전송 실패 감지: HTTP 응답코드 확인해 2xx 아니면 ::warning:: 로그 (continue-on-error 라 배포엔 무영향, 알림 유실을 로그로 드러냄)
- promote.yml 은 동적값이 이미 env 라 A 해당 없음, B/C(curl)만 적용
@sevineleven

sevineleven commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review body 지적 3건을 890362e 에서 반영했습니다.

A. 스크립트 인젝션 (🟠 Major)run: 에 직접 보간하던 needs.resolve.outputs.ref/branch/domain 을 전부 env: 로 옮기고 셸은 변수만 읽게 했습니다. 특히 branch(= workflow_run.head_branch)는 git 브랜치명이 백틱·$·; 를 허용해 악의적 브랜치명 push 로 인젝션이 될 수 있는 실질 벡터라 우선 대상이었습니다. deploy.yml 성공·실패·릴리즈 3개 스텝 모두 적용. ref(SHA)·github.repository·github.run_id 는 값 형식이 고정돼 안전해 그대로 뒀습니다. promote.yml 은 동적값이 이미 steps.*.outputs env 로 넘어와 해당 없음.

B. curl 타임아웃 (🔵 nitpick) — 5개 알림 curl 에 --max-time 10 추가. Discord 지연 시 러너가 매달리는 것을 방지합니다.

C. HTTP 응답코드 확인 (🔵 nitpick) — 응답이 2xx 가 아니면 ::warning:: 로 남깁니다. continue-on-error: true 라 배포엔 영향 없지만 알림 유실이 로그로 드러나게 했습니다.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
git fetch origin 890362e --depth=1 2>&1 | tail -5
git show 890362e --stat 2>&1 | head -20
echo "---deploy.yml---"
git show 890362e -- .github/workflows/deploy.yml 2>&1 | head -300
echo "---promote.yml---"
git show 890362e -- .github/workflows/promote.yml 2>&1 | head -300

Length of output: 11338


🏁 Script executed:

#!/bin/bash
git show 890362e:.github/workflows/deploy.yml | grep -n 'needs.resolve.outputs\|github.repository\|github.run_id\|TAG\b\|CAUSE\b' | head -60
echo "---promote full context for TARGET_INPUT SRC DST---"
git show 890362e:.github/workflows/promote.yml | sed -n '150,230p'

Length of output: 9996


@sevineleven 890362e 확인했습니다. 세 가지 모두 정확히 반영되어 있습니다.

A. 인젝션 수정deploy.yml의 성공/실패/릴리즈 3개 스텝 모두 REF/BRANCH/DOMAINenv:로 옮기고 run:에서는 $REF/$BRANCH/$DOMAIN만 참조하도록 바뀐 것 확인했습니다. head_branch처럼 사용자가 push 시 임의로 지정 가능한 값을 셸 컨텍스트에 직접 보간하지 않게 된 게 핵심입니다. 남아있는 github.repository, github.run_id, needs.resolve.outputs.ref(SHA), .environment(case 문으로 제한) 등은 형식이 고정돼 있어 그대로 둔 판단도 적절합니다. promote.yml은 원래부터 steps.*.outputs가 env로 넘어와 있어 해당 사항 없다는 설명도 코드와 일치합니다.

B. curl 타임아웃 — 5곳 모두 --max-time 10 적용 확인했습니다.

C. HTTP 응답코드 확인-o /tmp/discord_resp.json -w '%{http_code}'로 코드를 캡처하고, curl 자체가 실패해도 HTTP_CODE="000"으로 폴백해 이후 비교식이 깨지지 않게 처리한 부분도 견고합니다. 2xx 판정 실패 시 ::warning::에 응답 바디까지 남기는 것도 디버깅에 유용합니다. continue-on-error: true가 모든 관련 스텝에 유지되어 배포/승격 흐름에 영향 없는 것도 확인했습니다.

수고하셨습니다. 인젝션 벡터를 브랜치명까지 확장해서 짚어낸 판단이 좋았습니다 — GitHub Actions 워크플로에서 run: 블록에 ${{ }} 표현식을 직접 보간하는 대신 env:로 전달하는 패턴은 공식적으로도 권장되는 방식입니다(참고: GitHub Docs - Security hardening for GitHub Actions).

(๑•̀ㅂ•́)و✧

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sevineleven
sevineleven merged commit 161a6dc into dev Jul 3, 2026
6 checks passed
@sevineleven
sevineleven deleted the infra/651-discord-deploy-promote-alerts branch July 3, 2026 01:29
sevineleven added a commit that referenced this pull request Jul 3, 2026
- ${DISCORD_USER_MAP:-{}} 는 secret 이 설정돼 있으면 bash 가 뒤에 } 를 덧붙여(...}}) jq 가 파싱 실패(exit 5) → set -eo pipefail 로 curl 전에 step 이 죽어 알림이 전송되지 않음
- 역설적으로 secret 미설정일 때만 우연히 동작(빈 {})해, #659 머지 후 매 배포·승격 알림이 조용히 실패
- guard 로 분리: DISCORD_MAP 에 담고 비었으면 {} 로 채운 뒤 jq 에 넘김
- deploy.yml 3블록(성공·실패·릴리즈) + promote.yml 2블록(성공·실패) 전부 적용
- PR #659 검증이 로컬에 jq 없어 python 으로 렌더링만 확인하느라 이 라인을 실제로 안 돌린 사각
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.

승격 알림 Discord 이관 (promote.yml) 배포 알림 Discord 이관 (deploy.yml)

1 participant