chore: CI 도입 및 Docker 빌드 레이어 캐시 최적화 [#SEOUL-151] - #2
Open
kdy4049067 wants to merge 1 commit into
Open
Conversation
이 저장소에는 워크플로가 하나도 없었다. PR과 main push에서 테스트 32개를 자동 실행하고, main에서는 이미지를 GHCR에 올린다. EC2 배포에서 이 저장소의 이미지가 반드시 레지스트리를 거쳐야 한다. compose의 context가 ../seoulection-admin(형제 저장소)이라, EC2에 seoulection-server만 클론하면 그 경로가 없어 빌드가 불가능하기 때문이다. Dockerfile은 api-server와 같은 문제를 갖고 있었다. COPY src가 의존성 다운로드보다 위에 있어 소스를 한 줄만 고쳐도 Gradle 배포판부터 전부 다시 받았다. 실측(소스 한 줄만 수정 후 재빌드): 48s -> 7s. PR에서는 이미지 빌드까지만 하고 push는 main에서만 한다. 머지 후에야 처음 도는 job이면 깨졌을 때 main이 빨간불이 된다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
작업 내용
.github/workflows/ci.yml— 신규. 이 저장소에는 워크플로가 하나도 없었다testjob: PR·main push에서 테스트 32개 실행imagejob: 이미지 빌드. PR에서는 빌드만, main에서만 GHCR pushDockerfile— builder 스테이지 레이어 재배치 (의존성 다운로드를COPY src위로)build.gradle.kts—resolveDependencies태스크 추가변경 이유
① EC2 배포에서 이 저장소의 이미지는 반드시 레지스트리를 거쳐야 한다.
docker-compose-local.yml의 어드민 서비스는context: ../seoulection-admin으로 형제 저장소를 가리킨다. EC2에seoulection-server만 클론하면 그 경로가 없어서 compose가 실패한다. 그래서 어드민은 GHCR에 올라가 있어야 하고, 운영 compose는build:대신image:로 참조한다.② Dockerfile에 api-server와 같은 문제가 있었다.
COPY src가 의존성 다운로드보다 위에 있어, 소스를 한 줄만 고쳐도 그 아래 레이어가 전부 무효화됐다. Gradle 배포판(151MB)부터 의존성 전체를 매번 다시 받는다.Gradle에는 "의존성만 받기"에 해당하는 명령이 없다(해석이 lazy라⚠️
compileJava가 클래스패스를 요구하는 시점에야 받는다). 그래서 configuration을 직접 resolve하는 태스크를 추가했다.gradlew dependencies로 대체하면 안 된다 — 그건 의존성 그래프만 렌더링해서 POM 메타데이터만 받고 jar는 받지 않는다.테스트 방법
로컬 실측 (소스 한 줄만 수정한 뒤 재빌드):
--no-cache로 캐시를 비워 채운 뒤 측정 (2회차라 빨랐던 것이 아님을 확인)RUN ./gradlew resolveDependencies레이어가CACHED로 뜨는 것 확인./gradlew test32개 전부 통과리뷰어가 알아둘 것
seoulection-server의 같은 이름 워크플로와 짝이지만, 의도적으로 다른 부분이 있다:api-server/**(모노레포)working-directoryapi-servergradlew가 루트seoulection-api-serverseoulection-admin경로 필터가 없어서 부수 효과가 하나 있다 — 브랜치 보호에서 이 CI를 "필수 체크"로 지정해도 안전하다.
seoulection-server쪽은 경로 필터 때문에 job이 스킵되면 PR이 영원히 대기 상태가 되는 함정이 있는데, 여기엔 그게 구조적으로 없다.main실행에서 처음으로 GHCR push가 일어난다. 조직 설정이 Actions의 패키지 쓰기를 막고 있으면 여기서 403이 날 수 있다(seoulection-server에서는 통과했으므로 문제없을 가능성이 높다).