release 병합마다 반복하던 full CI를 최종 승격 후보에 집중 — #1491 (2026-09-10)
- 기간: 2026-09-10, main 설치 02:32:58 KST. 오너 지시: “음 좋아 그렇게 변경좀 해줄래?” — 개별 precheck 후 release 통합, staging 최종 후보에서 full 실행 제안을 승인.
- 랜딩: 앱 이슈 #1491, 작업 PR #1492·구현
9e268ae7·release 병합260eddad, staging PR #1493·d7862b46, main PR #1494·6afe58ec. 문서 PR #20. main 설치 완료, 정상 큐의 새 실행·운영 배포 성공은 확인 전. DB migration·Edge·제품 동작 변경 없음. - 설계서: 별도 artifact 없음. 아래 승인 정책·예상 효과를 적용 기준으로 사용.
- 정본: 릴리스 프로세스, 릴리스 큐, 로컬 CI, 앱
scripts/migrations/release-landing-service.mjs·scripts/check-promotion.mjs·.github/workflows/release-merge-request.yml. - 도구: 기존 precheck·merge 요청·GitHub 승격 workflow. 추가 사전검증 장부·승인 게이트 없음.
- 게이트: 관련 큐·승격 회귀 테스트 118개 통과·실패 0·skip 0, 234.3초(앱 담당 실행 결과). 이번 정책 적용은 오너의 관리자 예외 승인으로 별도 precheck·앱
npm run check전체 반복·원격 full CI를 생략한다. 이 결과를 앱 전체 검사나 full CI 성공으로 표시하지 않는다. 문서npm run check는 약관 4개 버전·로컬 경로 308개 통과. 제품 테스트·DB migration·pgTAP·브라우저 테스트 내용은 변경하지 않는다. - 버그리포트: 없음(오너가 승인한 실행 정책 변경).
- 계약: 작업→release와 두 승격의 검사 실행 시점.
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 1 | 큐·승격 실행 분리, 회귀 검증과 공통 지침 변경 | 완료 — 앱 9e268ae7, 관련 테스트 118개 통과; 병합·활성화는 별도 확인 |
1. 배경
작업 세션은 PR 전 precheck를 수행하고 release 큐는 최신 base와 작업 head를 합칠 때마다 full CI를 실행했다. 같은 tree의 유효한 기록을 재사용할 수 있어도 새 작업을 합치면 대부분 새로운 tree가 되므로 full 반복과 대기가 남았다. 오너는 release가 여러 작업을 모으는 통합 브랜치라는 점을 기준으로 최종 후보에서 full을 한 번 수행하는 절차를 승인했다.
2. 문제 제기
개별 병합마다 새 후보의 전체 검사를 반복했다
작업 4개가 차례로 병합되면 일반적으로 새 tree가 4개 생긴다. 각 작업의 사전검증 이후에도 release 큐에서 full을 반복했고 최종 승격 검증과 역할이 겹쳤다. 과거 한 번의 full 7분 32초 기록은 보장 시간이 아니며, 이 정책 변경으로 한 번의 full 자체가 빨라진다고 주장하지 않는다.
3. 해결 방안
원칙
- D1 (2026-09-10): 오너의 “음 좋아 그렇게 변경좀 해줄래?”로 개별 precheck → release 순차 통합 → 최종 release→staging full → 동일 tree의 staging→main 재사용을 승인했다.
- D2 (2026-09-10): 오너의 “이거 그냥 관리자 권한으로 최대한 빠르게 처리해줘”로 이번 #1491 정책 적용의
release/v0.17.8 → staging → main관리자 예외 병합을 승인했다. 관련 테스트 118개 성공을 근거로 별도 precheck·앱npm run check전체 반복·원격 full CI를 생략한다. 일반 작업·후속 승격의 새 기본 정책이나 데이터 보호·배포 smoke를 폐지하는 승인은 아니다. - 사전검증의 정적·단위·빌드와 서버 변경 시 DB 검사, migration 순서/위험·데이터 보호·조건부 push는 유지한다.
- 일반 release 병합은 full 실행·기록 발급을 하지 않는다. 미실행 검사를 성공으로 기록하지 않는다.
접근
| 방안 | 결정·이유 |
|---|---|
| 최종 release→staging 후보에서 full 실행 | 채택. 통합된 결과를 배포 전에 검사하면서 개별 병합의 반복을 줄임 |
| 모든 release 병합에 full 유지 | 변경. 새 tree마다 반복되는 대기가 남음 |
| 큐를 제거하고 직접 병합 | 기각. 최신 base·migration 순서·병합 중 변경 보호를 유지해야 함 |
| precheck 증명 장부나 추가 승인 단계 도입 | 범위 밖. 기존 사전검증 책임과 보고를 유지 |
4. 적용한 내용
Phase 1 — 실행 경계와 공통 지침
일반 큐는 최신 base 병합·충돌·이력 불변성·migration 순서/위험·head/base/tree·조건부 push와 병합 확인을 담당한다. full CI와 full 성공 기록 조회·재사용·발급은 하지 않는다. release→staging은 최종 병합 후보의 full을 실행한다. staging→main은 동일 tree의 유효한 원 full 기록과 현재 staging 배포·smoke를 확인하며 기록 없음·무효·조회 오류 때 full로 돌아간다.
명시적 merge:request --dry-run은 진단용 full 후 병합하지 않는 동작을 유지한다. ci:full-local -- --only <단계> 부분 재현도 유지한다. 공통 AGENTS·CI·릴리스·migration 지침과 탐색 인덱스를 갱신하며 과거 실행 기록은 재작성하지 않는다.
주요 결정과 그 근거
최종 full 이전의 release는 통합 문제를 포함할 수 있다. 각 작업이 사전검증에 통과해도 조합에서 생긴 문제는 release→staging에서 발견될 수 있으며, 실패하면 관련 작업의 조합을 조사·수정하고 최종 후보를 재검증한다. full의 검사 항목이나 배포 후 smoke를 줄이는 변경은 아니다.
작업 중 드러난 것
기존 지침에는 초기 큐 설치·저장소 분리 당시 설명과 현재 규칙이 섞여 있었다. 현재 명령·절차를 바꾸고 역사 표·당시 실행 링크는 보존했다. CPU 부하 수리·샌드박스 정리·CI 제목 선택 수리는 이번 범위에 넣지 않았다.
이번 정책 자체를 활성화하는 병합은 D2의 관리자 예외를 적용했다. 관련 회귀 테스트 성공과 전체 CI 미실행을 구분하며, 이번 예외를 후속 release→staging의 full 생략 근거로 사용하지 않는다. 승격 CI 34383542607·34383566105는 관리자 즉시 병합 뒤 scope의 Promotion PR must be open and ready for review 조건에서 failure로 종료됐다. 두 실행 모두 full 잡 전체가 skipped였으며, 취소 완료나 full 성공이 아니라 이미 병합된 PR의 scope 종료·full 미실행으로 기록한다.
오너는 release-queue-only ruleset에 관리자 역할(RepositoryRole 5, bypass mode always)을 직접 추가했다고 알렸고 원격 설정에서도 확인했다. 이번 병합을 위해 임시로 추가했던 release/v0.17.8 제외 설정은 제거했으며 오너가 추가한 관리자 권한은 보존했다. 권한의 존재와 이번 한정적 사용 승인을 구분하며 후속 일반 통합은 새 큐 정책을 따른다.
작업 head·release·staging·main의 tree는 모두 7d86a8a1d39ea27e38c84bc74a73a432f46e71f5로 일치했다. 기존 main 937042d7 대비 CI 관련 9개 파일만 바뀌었으며, 최신 base 기준 migration 장부 꼬리 20260914000000·새 migration 0개 검사가 통과했다. staging 배포 34383562943와 Production 배포 34383585159는 기록 시점에 진행 중이다. main 설치를 운영 배포·smoke 성공으로 보고하지 않는다.
5. 적용 결과
| 항목 | 전 → 후 / 확인 상태 |
|---|---|
| 작업 PR 전 검사 | precheck → 동일하게 유지 |
| 일반 작업→release full | 새 후보마다 실행 → 실행·full 기록 발급 없음. 구현·관련 회귀 검증·main 설치 완료, 정상 큐의 새 요청 실측은 확인 전 |
| release→staging | 유효한 기록이면 재사용 가능 → 최종 후보 full 실행 |
| staging→main | 동일 tree 기록 재사용 → 현재 staging 배포·smoke와 함께 계속 확인 |
| 작업 4개 통합의 full 반복 | 개별 병합 최대 4회 → 개별 병합 0회, 최종 승격 후보 1회 예상. 실패·수정·후보 변경은 추가 검증 필요 |
| 실제 절약 시간 | 미측정. 개별 full 속도·CPU 개선으로 보고하지 않음 |
| 관련 큐·승격 회귀 검증 | 118개 통과·실패 0·skip 0, 234.3초. 앱 9e268ae7·PR #1492 |
| 이번 적용의 검사 생략 | 오너 D2 승인으로 별도 precheck·앱 npm run check 전체 반복·원격 full CI 생략. 관련 테스트 통과를 full 성공으로 제출하지 않음 |
| 문서 검사 | npm run check 통과: 약관 4개 버전·로컬 경로 308개. git diff --check 통과. 앱 full·문서 빌드 중복 실행 없음 |
| release / staging / main 반영 | #1492 260eddad → #1493 d7862b46 → #1494 6afe58ec, 동일 tree 7d86a8a1 확인 |
| 실제 main 설치 | 2026-09-10 02:32:58 KST, 6afe58ec66d063f7331bd27b360f39fb2d8fee72. 이후 새로 시작하는 main controller 요청부터 새 코드 사용 |
| 최신 base·migration 확인 | 기존 main 대비 CI 관련 9파일만 변경. migration 꼬리 20260914000000, 새 migration 0개 통과 |
| 정상 큐 시간·운영 배포 성공 | 아직 미확인. staging·Production Deploy는 기록 시점 진행 중 |
6. 이번 개선으로 향상된 것
개별 작업은 필요한 사전검증을 유지하면서 release 통합의 full 대기를 줄인다. 여러 작업이 합쳐진 후보의 전체 검증은 staging 승격 전에 수행하고, 운영 승격은 같은 내용의 유효한 성공 기록과 실제 staging 배포·smoke를 확인한다. 병합 성공과 full 성공을 구분해 미실행 검사를 통과로 오인하지 않게 한다.
남은 것
문서 PR #20의 병합과 정상 큐의 새 실행·배포 결과는 확인 시 이 기록에 갱신한다. 승인된 범위 밖의 추가 수리나 오너 결정 항목은 없다.