Bazel을 활용한 Ruby 프로젝트 빌드 및 테스트: rules_ruby 소개

[EN] Bazel for Ruby / Alex Rodionov @p0deje

작성자
RubyKaigi
발행일
2025년 05월 27일

핵심 요약

  • 1 Bazel은 Google에서 개발된 다국어 빌드 및 테스트 도구로, 모노레포에 최적화되어 효율성, 확장성, 재현성 및 분산 실행 기능을 제공합니다.
  • 2 `rules_ruby`는 Bazel 생태계 내에서 Ruby 언어를 지원하며, Ruby 인터프리터 설치, Bundler를 통한 의존성 관리, Gem 빌드 및 테스트 실행 기능을 제공합니다.
  • 3 Bazel의 그래프 기반 접근 방식은 변경된 코드에 필요한 테스트만 선별적으로 실행하고 결과를 캐싱하여, 테스트 시간을 단축하고 병렬 실행을 통해 개발 워크플로우를 가속화합니다.

도입

이 발표는 Ruby Kaigi에서 Bazel을 Ruby 프로젝트에 적용하는 방법에 대해 다룹니다. 발표자는 Selenium 프로젝트의 Ruby 관리자이자 Bazel rule author SIG의 멤버로서 Bazel 생태계 내에서 Ruby 언어 지원을 유지 관리하고 있습니다. Bazel은 Google에서 모노레포를 위해 개발된 빌드 및 테스트 도구로, Make나 Rake와 유사하지만, 다국어 지원, 효율성, 확장성, 재현성, 밀폐성 및 분산 기능을 특징으로 합니다. 본 발표에서는 Bazel이 무엇인지, Ruby 프로젝트에서 어떻게 활용되는지, 그리고 Bazel 생태계 내 Ruby 언어 지원의 현재 상태에 대해 설명합니다.

Bazel의 핵심 개념

  • 빌드 및 테스트 도구: Make, Rake와 유사하게 소프트웨어 빌드 및 테스트 실행을 위한 도구입니다.
  • 모노레포 최적화: Google에서 ‘Blaze’라는 이름으로 개발되어 모노레포 환경에 특화되었습니다.
  • 다국어 지원: Java, Python을 기본으로 지원하며, 확장 모듈을 통해 Go, JavaScript, Ruby 등 다양한 언어를 지원합니다.
  • 효율성 및 확장성: 수천 명의 엔지니어가 사용하는 코드베이스를 위해 설계되어 매우 효율적이고 확장 가능합니다.
  • 재현성(Reproducible) 및 밀폐성(Hermetic): 빌드에 필요한 모든 소프트웨어 및 도구를 격리된 환경에 설치하여 어떤 머신에서든 동일한 결과물을 보장합니다.
  • 분산 빌드: 로컬 캐싱 및 원격 빌드 실행을 통해 대규모 분산 시스템에서의 빌드를 지원합니다.

빌드 및 테스트 과정

  • 그래프 기반 접근: 모든 빌드 및 테스트는 입력(소스 코드, 환경 변수) -> 액션(명령어 실행) -> 출력(새로운 파일)의 세 단계로 나뉘며, 이는 방향성 비순환 그래프(DAG)로 표현됩니다.
  • 지능형 캐싱: Bazel은 빌드 그래프를 메모리에 유지하며 입력 변경 사항을 추적합니다. 소스 코드 변경 시 해당 변경에 영향을 받는 타겟만 재빌드/재테스트하여 효율성을 극대화합니다.
  • 병렬 실행: 격리된 샌드박스에서 여러 테스트를 병렬로 실행하여 테스트 시간을 단축합니다.

rules_ruby를 통한 Ruby 지원

  • rules_ruby 소개: Bazel 생태계 내 Ruby 언어 지원을 위한 공식 규칙 세트입니다. Selenium 프로젝트에서 시작되었으며, 현재 Bazel Rule Authors SIG에서 관리됩니다.
  • 주요 기능:
    • Ruby 인터프리터 설치: CRuby, JRuby, TruffleRuby 등 다양한 버전의 인터프리터 설치 및 관리를 지원합니다.
    • 의존성 관리: Bundler를 사용하여 Gemfile에 명시된 의존성을 설치하고 추적합니다.
    • 빌드 및 테스트 타겟: ruby_library (Ruby 파일 노출), ruby_binary (Ruby 스크립트 실행), ruby_test (RSpec, RuboCop 등 테스트 실행), ruby_gem (Gem 빌드), ruby_gem_push (Gem 푸시) 등을 제공합니다.
  • 사용 예시:
    • MODULE.bazel 파일에서 rules_ruby 모듈 로드, 인터프리터 및 Bundler 의존성을 설정합니다.
    • BUILD.bazel 파일에서 ruby_gem, ruby_library, ruby_test 등의 타겟을 정의하고 deps 속성을 통해 의존성을 명시합니다.
    • bazel build //:calendar (Gem 빌드), bazel run //:calendar_release (Gem 푸시), bazel test //spec/... (테스트 실행) 명령어를 통해 작업을 수행합니다.
  • 효율성 입증: RuboCop 테스트 예시에서 소스 코드 변경이 없을 시 cached 결과가 반환되어, Bazel의 지능적인 캐싱 능력을 보여줍니다.

rules_ruby의 현재 상태 및 향후 과제

  • 강점: 병렬 및 격리된 테스트 실행, 필요한 테스트만 실행하는 지능형 기능(Crystal Ball과 유사), 가시성 제어(Packwerk 유사), 원격 캐싱 및 실행 지원을 제공합니다.
  • 제한 사항: CRuby의 원격 빌드 실행을 위해서는 컴파일 및 설치가 필요 없는 독립형 버전이 필요합니다.
  • 향후 계획: 테스트 샤딩, 커버리지 지원(SimpleCov), Aspect(빌드 중 타입 체크 등 추가 명령 실행), Gemfile 의존성 관리 개선(자체 호스팅, Git 저장소), 디버깅 지원 강화 등이 있습니다.

결론

Bazel은 Ruby 프로젝트의 빌드 및 테스트 방식에 있어 강력하고 효율적인 대안을 제시합니다. `rules_ruby`를 통해 개발자는 Bazel의 다국어 지원, 지능형 캐싱, 병렬 실행, 재현성, 분산 빌드 등의 이점을 Ruby 프로젝트에서 활용할 수 있습니다. 특히 대규모 모노레포 환경에서 코드 변경에 따른 빌드 및 테스트 시간을 획기적으로 단축시키고, 일관된 개발 경험을 제공합니다. 아직 초기 단계이지만, `rules_ruby`는 이미 많은 강력한 기능을 제공하며, 향후 개선을 통해 Ruby 개발 생태계에 더욱 큰 기여를 할 것으로 기대됩니다. Bazel Slack 채널이나 이메일을 통해 커뮤니티에 참여하여 `rules_ruby`의 발전에 기여할 수 있습니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!