들어가며
이미 Git으로 관리 중인 프로젝트에 서브모듈을 적용한 과정을 정리합니다.
개념 설명은 생략하고, 로컬 테스트부터 GitHub Actions 자동화까지 실제로 진행한 순서대로 기록했습니다.
1. 기존 프로젝트에서 서브모듈로 분리하기
테스트 환경은 아래와 같은 폴더 구조로 구성했습니다.
D:\dev\submodule_test
├── test1/
├── test2/ # 이 디렉터리를 서브모듈로 분리할 예정
└── test3/먼저 submodule_test 전체를 Git으로 초기화하고 커밋했습니다.
cd D:\dev\submodule_test
git init
git add .
git commit -m "Initial commit"2. 서브모듈용 저장소 생성 및 푸시
test2 폴더를 별도 저장소로 관리하기 위해 먼저 해당 폴더만 브랜치로 분리했습니다.
git subtree split --prefix=test2 -b split-test2이어서 bare 저장소를 만들고 분리한 브랜치를 푸시했습니다.
mkdir D:\dev\subrepo
cd D:\dev\subrepo
git init --bare
cd D:\dev\submodule_test
git push D:\dev\subrepo split-test2:main그다음 GitHub에 test2 전용 원격 저장소를 새로 만들고, bare 저장소의 내용을 그대로 옮겼습니다.
cd D:\dev\subrepo
git remote add origin https://github.com/2nan22/test2.git
git push origin --mirror3. 메인 프로젝트에 서브모듈로 추가
기존 test2 폴더를 제거하고, 방금 만든 GitHub 저장소를 서브모듈로 등록했습니다.
cd D:\dev\submodule_test
git rm -r test2
git commit -m "Remove test2 folder for submodule replacement"
git submodule add https://github.com/2nan22/test2.git test2
git commit -m "Add test2 as submodule"등록하면 .gitmodules 파일이 생성되며, 내용은 다음과 같습니다.
[submodule "test2"]
path = test2
url = https://github.com/2nan22/test2.git4. GitHub Actions로 자동 반영하기
서브모듈의 main 브랜치가 바뀌면 메인 프로젝트(submodule_test)의 서브모듈 참조도 자동으로 갱신되도록 GitHub Actions을 구성했습니다.
(1) 메인 레포: .github/workflows/update_submodule.yml
name: Auto Update Submodule
on:
repository_dispatch:
types: [update_submodule]
push:
branches:
- main
jobs:
update-submodule:
runs-on: ubuntu-latest
steps:
- name: Checkout main repo
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Update submodule reference
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git submodule update --remote --merge
git add test2
git diff --cached --quiet || git commit -m "Auto-update submodule test2"
git push(2) 서브모듈 레포: .github/workflows/notify_main.yml
name: Notify main repo on push
on:
push:
branches:
- main
jobs:
trigger-main-update:
runs-on: ubuntu-latest
steps:
- name: Trigger update on main repo
run: |
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
https://api.github.com/repos/2nan22/submodule_test/dispatches \
-d '{"event_type":"update_submodule"}'
PAT_TOKEN은 메인 레포(submodule_test)에repository_dispatch이벤트를 보낼 수 있는 Personal Access Token이어야 합니다. 클래식 토큰은repo권한, 세분화된 토큰은 해당 저장소의 Contents 쓰기 권한이 필요합니다.
5. Docker Compose에 반영하기
test2는 FastAPI 기반 모델 서비스이며, docker-compose.yml에서 볼륨으로 연결해 두었습니다.
services:
model_service:
build: ./test2
volumes:
- ./test2:/app/model_service
command: uvicorn model_service.main:app --host 0.0.0.0 --port 8001볼륨으로 연결되어 있어서, 실행 서버에서 메인 레포를 pull 하고 git submodule update --init으로 서브모듈을 갱신한 뒤 컨테이너만 재시작하면 코드 변경이 반영됩니다. GitHub Actions은 GitHub에 있는 메인 레포의 서브모듈 참조만 갱신하므로, 서버의 작업 폴더까지 자동으로 바꾸지는 않습니다.
docker compose restart model_service이미지를 다시 빌드(--build)할 필요는 없습니다.
6. 협업 브랜치 전략
서브모듈을 직접 수정하는 팀원에게는 다음 규칙을 안내했습니다.
feature/*브랜치를 만들어 개발합니다.- 충분히 검증한 뒤에만
main브랜치로 merge 합니다. main에 push 하면 GitHub Actions이 메인 프로젝트를 자동으로 갱신합니다.
7. 정리
| 항목 | 요약 |
|---|---|
| 서브모듈 경로 | test2 |
| 서브모듈 원격 | https://github.com/2nan22/test2.git |
| 자동 반영 | GitHub Actions (update_submodule.yml) |
| 반영 후 동작 | 서버에서 서브모듈 갱신 후 Docker Compose restart |
| 협업 플로우 | feature → main merge 시 자동 반영 |