Repository navigation
chore(ci): merge queue 를 도입해 develop 전진마다의 전 PR 일괄 전파를 없앤다 #1477
Description
작업 유형
maintenance — CI·빌드·의존성·저장소 운영 유지보수
주 담당 모듈
platform — Android 앱·CI·빌드·릴리스·저장소 운영
개요
#1333 이 병합 최신성 게이트를 도입하면서 strict required status checks 와 merge queue 두 선택지를 열어 두었고, 적용 단계에서 strict 만 켠 채 닫혔다. 그 결과 develop 이 한 칸 전진할 때마다 열린 PR 전부가 stale 이 되어, 머지하려면 매번 전량 update-branch 로 전파해야 한다. merge queue 를 켜서 이 전파 노동을 없앤다.
1. 지금 구조가 러너를 더 태운다
develop push 하나에 열린 PR 전부가 재판정된다(8/29 실측 29건 일제 red). 그런데 그중 실제로 그날 머지되는 것은 일부다.
| 방식 | 한 번의 develop 전진에 검증하는 대상 | job 수 |
|---|---|---|
| 현행(전파) | 열린 PR 전량 30건 | 30 × 15 = 450 |
| merge queue | 큐에 든 항목만 4건 | 4 × 15 = 60 |
게다가 PR 머지 자체가 develop push 라, 일괄 갱신 직후 한 건만 머지되면 나머지가 즉시 다시 red 가 된다(8/29 #1354 로 실측).
2. 코드는 이미 merge queue 를 받도록 절반 만들어져 있다
base-freshness-probe.yml 에 merge_group: [checks_requested] 트리거와 전용 job 이, evaluate-base-freshness.mjs 에 evaluateMergeGroupFreshness() 가 정책 테스트까지 갖춘 채 들어 있다. codeql.yml 도 merge_group 을 받는다.
문제는 나머지 required context 가 merge group 에서 아예 생성되지 않는다는 것이다. 이 상태로 큐를 켜면 항목이 영구 pending 후 방출된다.
| required context | 워크플로 | merge_group |
|---|---|---|
| Base Freshness | base-freshness-probe | ✅ |
| Analyze (java-kotlin) · Analyze (actions) | codeql | ✅ |
| Repository Quality / Repository Quality | pr-validation | ❌ |
| Static Analysis / Check Code Quality (Ktlint) | pr-validation | ❌ |
| Static Analysis / Check Project Issues (Android Lint) | pr-validation | ❌ |
| Unit Test / Run Unit Tests | pr-validation | ❌ |
| Screenshot / Validate Compose Preview Screenshots | pr-validation | ❌ |
| Pixel 2 API 30 androidTest | android-managed-device | ❌ |
| Pixel 2 API 34 accessibility smoke | android-managed-device | ❌ |
| guard | merge-order-guard | ❌ |
3. 처리량은 충분하다
최근 40 run 실측 — pr-validation p50 8.2분 / p90 9.8분, android-managed-device p50 7.5분 / p90 13.1분, codeql p50 6.7분 / p90 8.2분. 병렬이므로 merge group 하나의 critical path 는 약 13분, 소비 job 은 15개다. 동시 빌드를 4 로 두면 60 job 으로 러너 한도에 맞고, 13분마다 4건 = 시간당 약 18건이다. 머지 실적 피크(8/26 57건, 8/28 47건)를 3시간 안에 소화한다.
범위
pr-validation.yml에merge_group트리거를 추가한다. merge group 에는 PR 번호가 없으므로pull_request_number를0으로 떨어뜨려,developpush 가 이미 쓰고 있는 전량 검증 경로를 그대로 탄다. CI Test Plan·linked Issue 게이트는inputs.pull_request_number > 0조건이라 자동으로 비활성된다.android-managed-device.yml의managed-devicejob 조건에 merge group 절을 추가한다. required 인 API 30·34 lane 만 대상이고scheduled_onlylane 은 그대로 둔다.merge-order-guard.yml의guardjob 이 merge group 에서도guardcontext 를 만들도록 한다. 큐 ref(gh-readonly-queue/<base>/pr-<N>-<sha>)에서 PR 번호를 파싱해 기존 blocked_by 검사를 그대로 수행한다.- 위 세 워크플로의 정책 테스트(
pr-gate-policy.test.mjs,merge-order-guard-policy.test.mjs)에 merge group 계약을 고정한다.
참고
ruleset 의 merge_queue 룰 추가와 strict_required_status_checks_policy 해제는 PR 파일이 아니므로, #1333 과 같이 코드 병합 뒤 별도 저장소 설정 단계에서 적용·재조회한다. 순서는 (1) 이 PR 병합 → (2) merge_queue 룰 추가(동시 빌드 4) → (3) 큐가 정상 동작하는 것을 확인한 뒤 strict 해제다. 3단계까지 가야 전파 노동이 사라지며, 1·2 만 하고 strict 를 남기면 전파는 그대로다.
문제가 생기면 merge_queue 룰만 제거하면 즉시 현행 동작으로 돌아온다.
완료 조건
- 위 세 워크플로가 merge group 에서 required context 10건을 모두 생성한다.
- 정책 테스트와 actionlint 가 통과한다.
- 설정 단계 적용 후
develop전진 시 열린 PR 일괄update-branch가 더 이상 필요 없다.
Activity
Merge pull request #1478 from Afternote/chore/1477
OnlyReadOneBook commentedon Aug 29, 2026
PR #1478 병합 후 저장소 설정 단계를 적용·재조회했다.
merge-queue (develop)21795084 신설 —MERGE·ALLGREEN· 동시 빌드 4 · check timeout 60분required-checks (develop)(20911039) 의strict_required_status_checks_policy를 false 로Base Freshness제거 (11건 → 10건)allow_auto_merge활성화문서에 없던 전제가 두 개 나왔다. 큐 진입은
enablePullRequestAutoMerge를 쓰므로 auto-merge 가 꺼져 있으면gh pr merge가 거절당하고,Base Freshness가 required 에 남아 있으면 stale 한 PR 은 그 체크가 red 라 큐에 진입조차 못 해 strict 만 꺼서는 전파가 없어지지 않는다.실전 검증 — #1460 이 큐를 통과해 머지됐다(
51ec4bb7e). merge group 에서 required 4개 워크플로 전부 success.1차 시도는 큐에서 방출됐는데, 원인은 이 PR 의 코드가 아니라
API rate limit exceeded for installation403 이었다. 진범은 develop 전진마다 열린 PR 전량을 재판정하던 Base Freshness Publisher 였고, 해당 정리는 #1483 에서 완료했다.develop 전진마다의 일괄
update-branch가 더 이상 필요 없으므로 완료 조건을 충족한다. 닫는다.