Repository navigation
ci: base 와 충돌한 PR 에 conflict 라벨을 붙인다 (closes 1028) [base: develop] - #1036
Merged
Merged
Conversation
충돌 PR 은 pull_request 워크플로가 트리거조차 되지 않는다 — GitHub 이 base 와 head 를 합친 refs/pull/<N>/merge 를 만들지 못하기 때문이다. 체크가 실패하는 게 아니라 아예 생성되지 않아 no checks reported 로 비고, 저자도 리뷰어도 「아직 안 끝났나」로 읽어 최신 커밋이 미검증인 채 남는다. 머지 자체는 mergeable_state=dirty 와 required check 의 pending 이 막으므로, 고칠 것은 게이트가 아니라 가시성이다. develop push 직후와 매시 주기로 열린 PR 의 mergeable 을 훑어 conflict 라벨을 붙이고 해소되면 뗀다. - pull_request 트리거를 쓰지 않는다. 그것이 바로 «트리거되지 않는» 문제의 원인이다 - UNKNOWN 은 충돌로 단정하지 않는다. 3회 재조회 후에도 UNKNOWN 이면 보류한다 — 멀쩡한 PR 에 라벨이 붙는 오탐이 라벨 없음보다 나쁘다 - 안내 코멘트는 라벨 유무와 마커로 이중 확인해 1회만 남긴다 - 개별 PR 실패를 격리해 나머지를 처리한 뒤 한 번에 드러낸다 검증: 신규 단위 테스트 18개, 전체 스크립트 테스트 80개 통과. actionlint·shellcheck (Repository Quality) 17 workflows 통과. 실서비스 레포 dry-run 으로 충돌 10건을 정확히 검출했고 전부 mergeable=false 로 대조 확인했다.
도입 시점에 이미 충돌 PR 이 10건이라, push·schedule 을 켠 채 머지하면 첫 실행에서 라벨과 안내 코멘트가 한꺼번에 쏟아진다. 먼저 dry_run 으로 실제 러너 환경의 판정을 확인하고, 그 결과를 보고 두 트리거를 여는 후속 PR 을 낸다. 되살릴 트리거는 주석으로 파일에 남긴다. dry_run 기본값은 true 로 둔다 — 자동 트리거가 없는 동안에는 안전한 쪽이 기본이어야 한다.
Collaborator
Author
|
#847 작업(PR #1039)과 겹치는 지점이 하나 있어 알려 둡니다 — 파일 충돌은 없습니다( #1039 가 이 저장소의 외부 둘 다 develop 에 들어가면 나중에 들어간 쪽 이후로 고치는 것은 한 줄입니다. 이 PR 이 먼저 머지될 것 같으면 여기서 미리 바꿔 두셔도 됩니다. uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1( #1039 가 먼저 들어가면 제가 이쪽을 맞추겠습니다. 순서만 알려 주세요. 한 가지 더 — |
Contributor
Collaborator
Author
This was referenced Aug 24, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1028
무엇을 고치나
PR 이 base 와 충돌하면 그 PR 의
pull_request워크플로가 트리거조차 되지 않는다. GitHub 이 base 와 head 를 합친refs/pull/<N>/merge를 만들지 못하기 때문이다. 체크가 실패하는 게 아니라 아예 생성되지 않아no checks reported로 비고, 저자도 리뷰어도 「아직 안 끝났나」로 읽어 최신 커밋이 미검증인 채 남는다.머지 자체는
mergeable_state=dirty와 required check(guard)의pending이 이중으로 막는다. 그래서 이 PR 이 고치는 것은 게이트가 아니라 가시성이다.어떻게
열린 PR 전수의
mergeable을 GraphQL 로 훑어, 충돌이면conflict라벨을 붙이고 해소되면 뗀다.설계에서 의도한 결정 넷:
pull_request트리거를 쓰지 않는다. 그것이 바로 「트리거되지 않는」 문제의 원인이라, 이 워크플로가 같은 함정에 빠지면 안 된다.UNKNOWN은 충돌로 단정하지 않는다. GitHub 이mergeable을 비동기로 계산하고 첫 응답은 대개UNKNOWN이다. 2·4초 간격으로 3회까지 재조회하고, 그래도 미확정이면 라벨을 건드리지 않는다 — 멀쩡한 PR 에 라벨이 붙는 오탐이 라벨 없음보다 나쁘다. 라벨이 이미 붙은UNKNOWN도 성급히 떼지 않는다.<!-- conflict-label -->)로 2차 확인한다. 사람이 라벨을 손으로 뗐다 다시 붙어도 안내가 중복되지 않는다.conflict라벨은 없으면 자동으로 만든다. 스택 PR(base 가feat/*)도 base 가 develop 이 아닐 뿐 메커니즘이 같아 같은 규칙으로 본다.단계적으로 켠다 — 이 PR 은 수동 실행 전용
도입 시점에 이미 충돌 PR 이 10건이라,
push·schedule을 켠 채 머지하면 첫 실행에서 라벨과 안내 코멘트가 한꺼번에 쏟아진다. 그래서 이 PR 은workflow_dispatch만 열어 두고,dry_run기본값을true로 뒀다.순서는 이렇게 본다.
workflow_dispatch는 워크플로 파일이 기본 브랜치에 있어야 실행할 수 있어서, 머지가 선행돼야 한다.gh workflow run conflict-label.yml -f dry_run=true로 실제 러너 환경에서 판정 확인 — 로컬 dry-run 과 결과가 같은지,secrets.GITHUB_TOKEN권한으로 조회가 되는지를 본다.dry_run=false로 한 번 돌려 라벨을 붙이고, 그다음push·schedule트리거를 여는 후속 PR 을 낸다.되살릴 트리거는 워크플로 파일 주석에 그대로 남겨 뒀다.
검증
node --test .github/scripts/*.test.mjs→ 80개 통과실서비스 레포 dry-run — 이 스크립트를 로컬에서
DRY_RUN=true로 돌려 충돌 10건을 검출했고, 전부mergeable=false·mergeable_state=dirty로 대조 확인했다.수동으로 셌을 때는 7건이었는데 3건(#771·#967·#989)이 더 나왔다. 그때
UNKNOWN이라 빠졌던 것들이고, 재조회 로직이 실제로 값을 한다는 증거다.시각 검증 — 해당 없음. CI 스크립트와 워크플로만 바뀌어 Compose 본문·디자인 토큰·리소스 변경이 0건이다. screenshot baseline 사이클과 에뮬레이터 실측 모두 대상이 없다. Kotlin 모듈 변경이 없어
compileDebugKotlin도 해당 없고, 대신 위 node 테스트와 actionlint 로 갈음했다.리뷰어에게 알려둘 점
schedule은 기본 브랜치의 워크플로 파일로만 실행되는데, 이 레포 기본 브랜치가develop이라 3단계에서 트리거를 열면 바로 작동한다(main이었다면 안 돌았다).issues: write(라벨·코멘트) ·pull-requests: write이고secrets.GITHUB_TOKEN으로 충분하다.ci-gate로 묶기)과 역할이 갈린다 — 충돌은 이 워크플로가 라벨로 알리고, 머지 차단은 지금처럼pending이 맡는다. fix(ci): 검증 3종이 base PATCH 전이를 못 잡아 검증 0건으로 머지 — branches 필터 제거 후 required check 지정 #683 이 고친 base 필터 문제와도 원인이 다르다.