Google Copybara: 저장소 간 코드 이동

2 hours ago 2
  • Copybara는 Google 내부에서 쓰이는 도구로, 여러 저장소 사이에서 소스 코드를 변환하고 이동해 confidential 저장소와 public 저장소를 동기화하는 사례에 쓰임
  • 하나의 저장소를 권위 있는 저장소로 선택해 단일 진실 공급원을 유지하지만, 기여는 어느 저장소에서도 받을 수 있고 릴리스도 어느 저장소에서든 만들 수 있음
  • 주요 사용 사례는 반복적인 코드 이동이며, confidential 저장소에서 public 저장소로 일부 코드를 가져오거나 public 저장소 변경을 authoritative 저장소로 가져오는 흐름을 지원함
  • Copybara는 상태를 별도 서버가 아니라 대상 저장소의 커밋 메시지 라벨에 저장하는 stateless 방식이라, 여러 사용자나 서비스가 같은 설정과 저장소에서 같은 결과를 얻을 수 있음
  • 현재 지원 저장소 유형은 Git이며 Mercurial 읽기는 실험적 기능이고, 확장 가능한 구조로 맞춤 origin과 destination을 추가할 수 있음

Copybara가 해결하는 문제

  • Copybara는 저장소 간 소스 코드 이동과 변환을 위한 도구임
  • 소스 코드가 여러 저장소에 존재해야 하는 경우가 있으며, Copybara는 이런 저장소 사이에서 코드를 변환하고 이동할 수 있게 함
  • 대표 사례는 confidential 저장소public 저장소를 동기화해서 유지하는 프로젝트임
  • 가장 흔한 사용 방식은 한 저장소에서 다른 저장소로 코드를 반복적으로 옮기는 것임
  • 새 저장소로 코드를 한 번만 옮기는 용도로도 사용할 수 있음

권위 저장소와 기여 흐름

  • Copybara는 저장소 중 하나를 authoritative repository로 선택해야 함
    • 항상 하나의 source of truth가 존재하도록 하기 위한 조건임
  • 기여는 어느 저장소에서도 가능함
  • 릴리스도 어느 저장소에서든 만들 수 있음
  • 비권위 저장소에서 변경이 발생하면 Copybara가 해당 변경을 변환해 권위 저장소의 적절한 위치로 이동할 수 있음
    • 예시는 public 저장소의 contributor가 만든 변경임
    • 병합 충돌은 권위 저장소 안에서 오래된 변경을 처리하는 방식과 동일하게 다룸

사용 예시

  • Copybara 사용 예시는 다음을 포함함
    • confidential 저장소의 코드 일부를 public 저장소로 가져오기
    • public 저장소의 코드를 confidential 저장소로 가져오기
    • non-authoritative 저장소의 변경을 authoritative 저장소로 가져오기
  • 예시 설정은 core.workflow로 origin과 destination을 정의함
    • origin은 git.github_origin으로 https://github.com/google/copybara.git의 master를 사용함
    • destination은 git.destination으로 file:///tmp/foo를 사용함
    • destination_files는 third_party/copybara/**를 대상으로 하고 README_INTERNAL.txt는 제외함
    • core.replace와 core.move로 BUILD 파일 경로 치환과 디렉터리 이동을 수행함
  • 실행 예시는 bare Git 저장소를 만든 뒤 copybara copy.bara.sky를 실행하는 방식임

상태 저장 방식과 저장소 지원

  • Copybara의 주요 특징 중 하나는 stateless 구조임
  • 더 정확히는 상태를 대상 저장소에 저장함
    • 저장 위치는 커밋 메시지의 라벨
  • 이 방식으로 여러 사용자나 서비스가 같은 설정과 저장소 조합을 사용해 같은 결과를 얻을 수 있음
  • 현재 지원되는 저장소 유형은 Git
  • Mercurial 저장소에서 읽는 기능은 가능하지만 아직 실험적
  • 확장 가능한 아키텍처를 통해 거의 모든 사용 사례에 맞는 bespoke origin과 destination을 추가할 수 있음
  • 다른 저장소 유형의 공식 지원은 향후 추가될 예정임

설치와 빌드

  • 시작하기 가장 쉬운 방법은 사전 빌드 바이너리가 포함된 주간 snapshot release를 사용하는 것임
  • 미릴리스 버전을 쓰려면 HEAD에서 빌드해야 함
    • JDK 11 설치 필요
    • Bazel 설치 필요
    • git clone https://github.com/google/copybara.git로 소스 복제
    • bazel build //java/com/google/copybara로 빌드
    • 실행 가능한 uberjar는 bazel build //java/com/google/copybara:copybara_deploy.jar로 생성
    • 테스트는 bazel test //...로 실행 가능함
  • 일부 테스트는 Mercurial, Quilt 같은 기반 도구 설치가 필요함
    • Pull Request가 해당 모듈과 관련 없으면 해당 테스트를 건너뛰어도 됨
    • CI는 모든 테스트를 실행함
  • Arch Linux에서는 aur/copybara-git 패키지를 사용할 수 있음

Bazel에서 사전 빌드 Copybara 사용

  • 주간 snapshot release를 Bazel에서 사용할 수 있음
  • Copybara는 class file version 65.0으로 제공되므로 Java Runtime 21 이상에서 실행해야 함
    • .bazelrc에 run --java_runtime_version=remotejdk_21 추가 필요
  • http_jar로 release artifact를 내려받음
    • WORKSPACE에서는 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") 사용
    • MODULE.bazel에서는 http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") 사용
  • WORKSPACE 또는 MODULE.bazel에서 [version] 자리를 채워 copybara_deploy.jar를 지정함
  • BUILD 파일에서는 java_binary를 선언해 com.google.copybara.Main을 main class로 사용함
  • 실행 예시는 bazel run //tools:copybara -- migrate copy.bara.sky임

외부 Bazel 저장소로 소스 빌드

  • Copybara 의존성을 위한 편의 매크로가 제공됨
  • WORKSPACE에 http_archive를 추가하고 {{ sha256sum }}과 {{ commit }} 값을 채움
  • 이후 다음 매크로를 로드하고 호출함
    • copybara_repositories()
    • copybara_maven_repositories()
    • copybara_go_repositories()
  • 워크스페이스 안에서 bazel run @com_github_google_copybara//java/com/google/copybara -- <args...>로 빌드 및 실행할 수 있음

Docker 사용

  • Docker로 Copybara를 빌드하고 실행하는 방식은 현재 실험적
  • 빌드는 docker build --rm -t copybara .로 수행함
  • 실행은 대상 코드 루트에서 docker run -it -v "$(pwd)":/usr/src/app copybara help 형태로 수행함
  • 컨테이너 실행 인자 대신 환경 변수를 사용할 수 있음
    • COPYBARA_SUBCOMMAND=migrate: 실행 명령 변경, 기본값은 migrate
    • COPYBARA_CONFIG=copy.bara.sky: 설정 파일 경로 지정, 기본값은 루트의 copy.bara.sky
    • COPYBARA_WORKFLOW=default: 실행할 workflow 지정, 기본값은 default
    • COPYBARA_SOURCEREF='': sourceref 지정, 기본값 없음
    • COPYBARA_OPTIONS='': Copybara 옵션 지정, 기본값 없음
  • Git 설정과 SSH 자격 증명은 Docker 컨테이너에 공유할 수 있음
    • 예시는 ~/.gitconfig, ~/.ssh, SSH_AUTH_SOCK를 컨테이너에 마운트하는 방식임

문서와 문의

Read Entire Article