From 6d2136c25a98d5dbc2b6ccc85d5b04df9d2efc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=BC=ED=98=81?= Date: Mon, 24 Aug 2026 13:37:52 +0900 Subject: [PATCH] =?UTF-8?q?ci(merge-order-guard):=20base=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99=EC=9D=84=20=EC=8B=A4=ED=8C=A8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B2=BD=EA=B3=A0=EB=A1=9C=20=EA=B0=95=EB=93=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 스택 PR 은 base 가 부모 브랜치인 동안 이 규칙에 걸려 수명 내내 check 가 X 로 남았다. PR 목록의 rollup 은 한 칸이라, 그 X 가 진짜 CI 실패를 덮어 "코드가 깨진 PR"과 "머지 순서를 기다리는 PR"을 구분할 수 없었다. 0824 실측 기준 열린 스택 PR 26건이 전부 이 사유로 X 였고, 그 중 일부는 Ktlint·Android Lint 실패를 함께 달고 있어 목록에서 드러나지 않았다. base 규칙을 떼도 develop 는 그대로 지켜진다. - ruleset 20911039 가 보호하는 건 develop·main 뿐이고, base 가 부모 브랜치인 PR 은 애초에 develop 로 머지되지 않는다. - 부모가 머지되면 GitHub 가 자식 PR 의 base 를 develop 로 자동 이관하고, 그 edited 이벤트로 이 가드가 다시 돌아 blocked_by 를 검사한다. - 스택 PR 은 GitHub 가 closing 이슈를 연결해 주지 않아(기본 브랜치 develop 기준) 애초에 blocked_by 절반이 돌지 않았다. base 규칙만 켜져 있었다. blocked_by 검사는 그대로 두어 실제 머지 순서 위반은 계속 막는다. 실측: 워크플로에서 스크립트를 추출해 실 API 로 4케이스 확인 — 스택 PR #991·#987 exit 0(경고만), blocked 인 #882 exit 1, 정상 #989 exit 0. --- .github/workflows/merge-order-guard.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/merge-order-guard.yml b/.github/workflows/merge-order-guard.yml index 0064a1de3e..caf0c8c2cf 100644 --- a/.github/workflows/merge-order-guard.yml +++ b/.github/workflows/merge-order-guard.yml @@ -1,9 +1,9 @@ # PR 머지 순서 가드 (#660) # # GitHub 는 이슈 Relationships(blocked_by)를 표시만 하고 머지 버튼을 잠그지 않는다. -# 이 워크플로는 PR 의 closing 이슈에 아직 열린 blocked_by 가 있거나, base 가 -# develop/main 이 아니면(스택 PR 미PATCH 상태) check 를 실패시킨다. -# branch protection 에서 required check 로 지정하면 머지 버튼이 실제로 잠긴다. +# 이 워크플로는 PR 의 closing 이슈에 아직 열린 blocked_by 가 있으면 check 를 +# 실패시킨다. branch protection 에서 required check 로 지정하면 머지 버튼이 +# 실제로 잠긴다. base 가 develop/main 이 아닌 스택 PR 은 경고로만 남긴다. name: merge-order-guard on: @@ -21,7 +21,7 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - name: closing 이슈 blocked_by · base 검사 + - name: closing 이슈 blocked_by 검사 env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} @@ -32,12 +32,14 @@ jobs: fail=0 - # 스택 PR 방호 — base 가 feat 브랜치면 그 브랜치로 머지돼 버린다. + # 스택 PR 안내 — base 가 부모 브랜치면 애초에 develop 로 머지되지 않고, + # 부모가 머지되면 GitHub 가 base 를 develop 로 이관하며 이 가드가 다시 + # 돌아 blocked_by 를 검사한다. 실패로 올리면 스택 PR 이 수명 내내 X 로 + # 남아 목록에서 진짜 CI 실패와 구분되지 않으므로 경고로만 남긴다. case "$BASE_REF" in develop|main) ;; *) - echo "::error::base 가 '$BASE_REF' — 스택 PR 은 base 를 develop 로 PATCH 한 뒤 머지할 것" - fail=1 + echo "::warning::base 가 '$BASE_REF' — 스택 PR 은 base 를 develop 로 PATCH 한 뒤 머지할 것" ;; esac