개발 기록

Brewfile로 클라우드 Mac의 Homebrew 도구 체인 고정하기

Brewfile로 클라우드 Mac의 Homebrew 도구 체인 고정하기

클라우드 Mac에서 몇 주 동안 빌드 작업을 계속 실행하다 보면, 가장 흔한 환경 문제는 도구가 설치되지 않은 것이 아니라 여러 사람이 서로 다른 시점에 도구를 설치했다는 데서 발생합니다. 어떤 작업은 jq에 의존하고, 다른 스크립트는 swiftlint가 이미 있다고 가정하며, 임시 문제 해결 과정에서 설치한 여러 formula가 그대로 남기도 합니다. 새 머신으로 교체할 때 저장소만 복사해서는 이러한 시스템 의존성을 복원할 수 없습니다. Brewfile은 ‘어떤 도구가 필요한가’를 관리하는 데 적합하지만 정확한 버전 잠금 파일은 아닙니다. 안정적으로 운영하려면 요구 사항 선언, 버전 증거, 정리 절차를 분리해 관리해야 합니다.

먼저 머신을 점검하고 전체 항목을 바로 내보내지 않기

먼저 Homebrew 경로와 현재 아키텍처를 확인해 스크립트가 과거의 다른 경로를 계속 사용하지 않도록 합니다.

command -v brew
brew --prefix
uname -m
brew doctor

이어서 최상위 formula, 전체 버전, 백그라운드 서비스를 각각 확인합니다.

brew leaves
brew list --formula --versions
brew services list

brew leaves는 주로 사용자가 직접 설치한 최상위 도구를 보여 주므로 전체 목록보다 요구 사항 선언의 출발점으로 적합합니다. 전체 버전 목록은 Brewfile에 그대로 넣는 대신 빌드 증거로 보관해야 합니다.

빌드 작업이 실행 중일 때는 업그레이드하거나 정리하지 마십시오. 먼저 작업 배포를 중단한 뒤 컴파일러, 데이터베이스 또는 보조 서비스가 프로세스에서 사용 중이지 않은지 확인해야 합니다.

머신을 이미 오랫동안 사용했다면 후보 파일을 먼저 내보낸 다음 한 줄씩 검토할 수 있습니다.

mkdir -p ci/homebrew
brew bundle dump --force --file=ci/homebrew/Brewfile.candidate
git diff -- ci/homebrew/Brewfile.candidate

후보 파일에는 개인용 도구, 임시 디버깅 소프트웨어 또는 프로젝트와 무관한 GUI 애플리케이션이 포함될 수 있습니다. 빌드와 문제 해결에 실제로 필요한 항목만 정식 목록에 추가해야 합니다.

Brewfile을 요구 사항 선언으로 사용하기

iOS 지속적 빌드에 사용하는 기본 목록은 간결하게 유지할 수 있습니다.

brew "git"
brew "jq"
brew "swiftlint"
brew "xcbeautify"

파일을 ci/homebrew/Brewfile로 커밋하고 설치할 때 경로를 명시적으로 지정합니다.

brew bundle check --file=ci/homebrew/Brewfile
brew bundle install --file=ci/homebrew/Brewfile --no-upgrade

check는 작업 진입점에서 실행하기에 적합합니다. 이 명령은 선언된 요구 사항이 충족되는지만 검증하므로 각 빌드 작업에서 전체 업그레이드를 자동으로 실행해서는 안 됩니다. install --no-upgrade를 사용하면 누락된 도구를 설치하면서도 일반적인 빌드 한 번이 기존 환경을 예기치 않게 변경할 가능성을 줄일 수 있습니다.

역할에 따라 목록 분리하기

동일한 VMKeep 클라우드 Mac에서 여러 유형의 작업을 처리해야 한다면 기본 목록과 프로젝트 목록으로 분리하는 것이 좋습니다. 예를 들어 기본 계층에는 Git, JSON 처리 도구, 로그 도구만 두고, 프로젝트 계층에는 코드 규칙 검사나 릴리스 보조 도구를 추가합니다. 설치 순서는 항상 기본 계층을 먼저, 프로젝트 계층을 나중에 설치하도록 고정합니다.

계속 커지는 하나의 전역 Brewfile로 모든 저장소를 포괄하지 마십시오. 그렇게 하면 정리할 때마다 영향 범위를 판단하기 어려워지고, 새 프로젝트에서 과거에 설치된 도구를 자체 필수 의존성으로 오해할 수 있습니다.

버전과 실행 컨텍스트를 별도로 기록하기

Brewfile은 일반적으로 보통 formula를 정확한 버전으로 잠그지 않습니다. 두 머신에 동일한 목록이 있다는 사실만으로 같은 결과가 생성된다고 보장할 수 없습니다. 환경을 변경할 때마다 실제 버전 스냅샷을 저장해야 합니다.

{
  date -u
  sw_vers
  xcodebuild -version
  brew --version
  brew list --formula --versions
} > ci/homebrew/toolchain.snapshot.txt

버전 스냅샷은 파이프라인 산출물로 보관할 수도 있고, 검토를 거친 환경 업그레이드 후 운영 기록에 커밋할 수도 있습니다. 차이가 발생하면 먼저 Xcode, macOS, Homebrew 및 직접 의존성의 버전을 비교하고 프로젝트 잠금 파일을 확인해야 합니다. 처음부터 모든 캐시를 삭제해서는 안 됩니다.

버전 경계를 명확히 정하기

brew pin은 현재 머신의 로컬 업그레이드만 차단합니다. 다른 새 머신에서도 동일한 과거 버전을 받을 수 있다고 보장하지는 않습니다. 따라서 단기적인 보호 수단으로는 사용할 수 있지만, 고정된 머신 이미지, 프로젝트 전용 버전 관리자 또는 검증된 바이너리 산출물을 대신할 수는 없습니다.

산출물에 직접 영향을 주는 도구는 스크립트 시작 시 허용 가능한 버전 범위를 확인하고 조건을 충족하지 않으면 명확하게 실패하도록 해야 합니다. 로그 출력만 보기 좋게 만드는 도구에는 더 넓은 범위를 허용해 중요하지 않은 차이 때문에 빌드가 중단되지 않도록 할 수 있습니다.

미리 보기와 유휴 시간대를 활용해 안전하게 정리하기

실제로 정리하기 전에 Brewfile에 포함되지 않은 항목을 먼저 확인합니다.

brew bundle cleanup --file=ci/homebrew/Brewfile

이 단계에서는 출력만 검토합니다. 목록에 표시된 formula를 다른 프로젝트, LaunchAgent 또는 백그라운드 서비스가 사용하지 않는지 확인한 뒤에 다음 명령을 실행합니다.

brew bundle cleanup --file=ci/homebrew/Brewfile --force
brew autoremove
brew cleanup

공유 머신에서는 특히 주의해야 합니다. 어떤 formula가 현재 저장소의 Brewfile에 없더라도 다른 작업에서 사용하지 않는다는 의미는 아닙니다. 더 안전한 경계는 장기간 운영하는 워크로드 유형별로 전용 물리 노드 한 대를 할당하는 것입니다. 최소한 실행 계정, 작업 디렉터리, 목록을 각각 분리해야 합니다.

정리 후 brew bundle check를 다시 실행한 다음 최소 검증 절차를 수행합니다. 도구 버전을 출력하고, 프로젝트 설정을 파싱하며, 산출물을 업로드하지 않는 빌드를 한 번 완료합니다. 이 세 단계가 모두 통과해야 환경 변경이 끝난 것으로 간주할 수 있습니다.

환경 변경을 검토 가능한 이벤트로 만들기

안정적인 프로세스에서는 빌드 스크립트가 임의로 brew install을 실행하도록 허용해서는 안 됩니다. 도구를 추가할 때는 Brewfile 변경 사항, 사용 목적, 버전 스냅샷, 롤백 방법을 하나의 커밋에 함께 포함해야 합니다. 업그레이드는 별도의 작업 시간대에 진행하고 대표 프로젝트를 먼저 검증한 뒤 작업 배포를 재개합니다.

일상 점검 항목은 다음 네 가지로 정리하는 것이 좋습니다.

  1. brew bundle check가 통과하는가;
  2. Xcode와 핵심 formula 버전이 예상과 일치하는가;
  3. Brewfile에 검토되지 않은 변경 사항이 있는가;
  4. 선언되지 않은 백그라운드 서비스가 계속 실행 중인가.

Brewfile의 가치는 모든 도구를 자동으로 설치하는 데 있지 않습니다. 시스템 의존성을 ‘머신에 이미 존재하는 사실’에서 저장소 안에서 논의하고 비교하며 롤백할 수 있는 선언으로 바꾸는 데 있습니다. 버전 스냅샷과 신중한 정리 절차를 함께 사용하면 클라우드 Mac의 환경 문제를 임시 추측이 아니라 증거가 있는 구성 차이로 다룰 수 있습니다.

자주 묻는 질문

Brewfile만으로 Homebrew 패키지 버전을 정확히 고정할 수 있나요?

아닙니다. Brewfile은 필요한 도구를 선언하지만 일반 formula 버전은 저장소 갱신을 따릅니다. 정확한 재현에는 버전 스냅샷, 고정된 머신 이미지 또는 별도 버전 관리가 필요합니다.

공유 클라우드 Mac에서 brew bundle cleanup --force를 바로 실행해도 되나요?

권장하지 않습니다. 먼저 --force 없이 삭제 대상을 확인하고 다른 작업의 사용 여부를 검토한 뒤 유휴 시간에 정리해야 합니다. 프로젝트별 실행 계정 분리도 필요합니다.

전용 물리 노드

클라우드 Mac에서 이 워크플로를 계속 검증하세요

세 가지 Apple Silicon 구성 중에서 필요한 메모리, 스토리지, 노드와 대여 기간을 선택하세요.

구성 선택 후 주문하기