From 5d16dd5c639a1e06730e5b98d18df795a3c704f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=BC=ED=98=81?= Date: Wed, 26 Aug 2026 00:45:15 +0900 Subject: [PATCH] =?UTF-8?q?ci(merge-order-guard):=20=EC=8A=A4=ED=83=9D=20P?= =?UTF-8?q?R=20=EC=9D=98=20=EB=A8=B8=EC=A7=80=20=EC=88=9C=EC=84=9C=20?= =?UTF-8?q?=EC=9C=84=EB=B0=98=EC=9D=80=20=EC=A3=BC=EC=84=9D=EB=8C=80?= =?UTF-8?q?=EB=A1=9C=20=EA=B2=BD=EA=B3=A0=EB=A1=9C=EB=A7=8C=20=EB=82=A8?= =?UTF-8?q?=EA=B8=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 가드 주석은 「base 가 develop/main 이 아닌 스택 PR 은 경고로만 남긴다」 고 이미 명시하고 있었다. 그런데 코드는 base 를 보고 경고 한 줄을 찍은 뒤, blocked_by 검사는 base 와 무관하게 그대로 돌려 `fail=1` 을 만들었다. 주석이 서술한 의도가 구현되지 않은 채로 남아 있었다. 그 결과가 #863 이다. base 가 `feat/735` 인 스택 PR 인데, 부모 이슈 #735 가 열려 있다는 이유로 required check 인 `guard` 가 수명 내내 red 다. 주석이 막으려던 바로 그 상태 — 「목록에서 진짜 CI 실패와 구분되지 않는다」 — 가 실제로 벌어졌다. 스택 PR 은 develop 로 직접 머지되지 않는다. base 가 develop 로 이관되는 순간 이 가드가 다시 돌아 error 로 막으므로, 경고로 낮춰도 순서 강제력은 그대로다. 실측 (가드 스크립트를 떼어내 `gh` 스텁으로 분기별 실행): base=feat/735 → exit 0, warning 2건 base=develop → exit 1, error 1건 base=main → exit 1, error 1건 --- .github/workflows/merge-order-guard.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge-order-guard.yml b/.github/workflows/merge-order-guard.yml index caf0c8c2cf..1fdfbe16da 100644 --- a/.github/workflows/merge-order-guard.yml +++ b/.github/workflows/merge-order-guard.yml @@ -36,9 +36,11 @@ jobs: # 부모가 머지되면 GitHub 가 base 를 develop 로 이관하며 이 가드가 다시 # 돌아 blocked_by 를 검사한다. 실패로 올리면 스택 PR 이 수명 내내 X 로 # 남아 목록에서 진짜 CI 실패와 구분되지 않으므로 경고로만 남긴다. + stacked=0 case "$BASE_REF" in develop|main) ;; *) + stacked=1 echo "::warning::base 가 '$BASE_REF' — 스택 PR 은 base 를 develop 로 PATCH 한 뒤 머지할 것" ;; esac @@ -54,8 +56,15 @@ jobs: open_blockers=$(gh api "repos/$GITHUB_REPOSITORY/issues/$n/dependencies/blocked_by" \ --jq '.[] | select(.state == "open") | .number') for b in $open_blockers; do - echo "::error::#$n 이 아직 열린 #$b 에 blocked — 머지 순서 위반. 선행 PR 부터 머지할 것" - fail=1 + if [ "$stacked" -eq 1 ]; then + # 스택 PR 은 develop 로 직접 머지되지 않는다. base 가 develop 로 + # 이관되는 순간 이 가드가 다시 돌아 error 로 막으므로, 그전까지는 + # 경고로만 남겨 진짜 CI 실패와 구분되게 한다. + echo "::warning::#$n 이 아직 열린 #$b 에 blocked — base 를 develop 로 이관하기 전에 선행 PR 부터 머지할 것" + else + echo "::error::#$n 이 아직 열린 #$b 에 blocked — 머지 순서 위반. 선행 PR 부터 머지할 것" + fail=1 + fi done done