더 나은 Rome 사용법

20초 안에 의존성 업데이트가 가능하다면 믿으시겠습니까? 오늘은 지난 글에서 설명드렸던 내용에 대해 잘못 알고 있던 내용을 고치고 새로 알게된 내용을 설명드린 후 의존성 업데이트를 더 빠르게 끝낼 수 있는 방법을 알려드리겠습니다.

시작하며

지난 글에선 Carthage를 사용하는 프로젝트에서 협업 시에 의존성을 효율적으로 관리할 수 있는 방법인 Rome의 사용법에 대해 알아보았고 30분 걸리던 의존성 업데이트를 86초로 줄이는 마법을 보여드렸습니다.

오늘은 이전에 말씀드렸던 내용에서 제가 잘못 이해했던 내용에 대해 다시 설명하고 의존성 업데이트를 20초 안에 끝내는 새로운 마법을 보여드리겠습니다.

잘못 알았던 점

이전 글에서 제가 주로 봤던 내용은 이 부분인데요, 특히 (recommended)가 붙은 --cache-builds 워크플로우를 봤습니다.

하지만 레포에도 적혀있듯이 이 워크플로우는 의존성의 생산자이자 소비자인 CI를 위한 다운로드 -> 부트스트랩 -> 업로드를 하는 워크플로우였습니다. 그리고 --cache-build를 사용하면 로컬 캐시에 많이 의존하기 때문에 서로 다른 환경의 맥북에서 사용하기에는 적절하지 않은 워크플로우였습니다.

로컬 캐시에 의존하기 때문에 각자가 bootstrap하는 라이브러리가 달라지기도 했고 결국엔 배포 할 때 Rome을 쓰지 않고 Carthage 폴더를 압축해서 에어드랍으로 공유하는 사태가 발생하기도 했습니다.

새로 깨달은 점

결국 저는 Rome의 문서를 다시 읽어봤고 한 가지 깨달음을 얻었습니다. 새로운 의존성을 만드는 생산자는 의존성을 업로드하기만 하면 되고, 소비자는 의존성을 받기만 하면 된다는 사실을 깨달았습니다.

그래서 새로 만든 스크립트는 생산자 워크플로우(Producer Workflow)와 소비자 워크플로우(Consumer Workflow)를 참고해서 만들었습니다.

업로드하려면 아래 코드를 터미널에 입력하면 됩니다.

carthage bootstrap --platform ios --no-use-binaries --cache-builds && rome upload --platform ios --concurrently

다운로드하려면 아래 코드를 터미널에 입력하면 됩니다.

rome download --platform ios

의존성이 바뀌는 상황들

의존성이 바뀌는 경우는 carthage bootstrap만 있는게 아닙니다.

제가 정리한 바로는 총 세가지로, 아래와 같습니다.

  1. Cartfile.resolved 기준으로 carthage bootstrap하는 경우
  2. Cartfile 기준으로 carthage update하는 경우
  3. 특정 라이브러리만 업데이트(carthage update 특정라이브러리) 후 의존성을 업로드하는 경우

코드로 만들면 다음과 같습니다.

# Cartfile.resolved 기준으로 빌드 업로드 하는 법
carthage bootstrap --platform ios --no-use-binaries --cache-builds && rome upload --platform ios --concurrently

# Cartfile 기준으로 업데이트 후 빌드 업로드 하는 법
carthage update --platform ios --no-use-binaries --cache-builds && rome upload --platform ios --concurrently

# 특정 라이브러리만 업데이트 후 빌드 업로드 하는 법
carthage update 업데이트하고싶은라이브러리이름 --platform ios --no-use-binaries --cache-builds && rome upload --platform ios --concurrently

정리하기

rome upload 또는 rome download는 항상 반복되니 fastlane을 이용해서 좀 더 사용하기 편하게 만들어 보겠습니다.

lane :upload_dependency do
  rome(
    command: "upload",
    platform: "iOS",
    concurrently: "true",
  )
  sh("cd ..;carting update")
end

lane :download_dependency do
  rome(
    command: "download",
    platform: "iOS",
    concurrently: "true"
  )
  sh("cd ..;carting update")
end

CartingCarthage를 사용할 때 같이 쓰면 편한 라이브러리인데 이건 나중에 설명드리겠습니다.

fastlane 명령어까지 적용하면 아래와 같은 결과물이 나옵니다!

# Cartfile.resolved 기준으로 빌드 업로드 하는 법
carthage bootstrap --platform ios --no-use-binaries --cache-builds && fastlane upload_dependency

# Cartfile 기준으로 업데이트 후 빌드 업로드 하는 법
carthage update --platform ios --no-use-binaries --cache-builds && fastlane upload_dependency

# 특정 라이브러리만 업데이트 후 빌드 업로드 하는 법
carthage update 업데이트하고싶은라이브러리이름 --platform ios --no-use-binaries --cache-builds && fastlane upload_dependency

# 버전 다운로드하는 방법
fastlane download_dependency

정리하면 다음과 같습니다.

의존성 생산자: 의존성 업데이트 후 fastlane upload_dependency

의존성 소비자: fastlane download_dependency

깔끔하네요 🎉

테스트 시간

기능이 생겼으니 테스트를 해봐야겠죠?

먼저, 의존성을 업로드하고자 하는 프로젝트 폴더로 가서 fastlane upload를 실행합니다.

업로드가 다 됐으면 로컬 캐시를 모두 삭제합니다.

rm -rf ~/Library/Cache/carthage
rm -rf ~/Library/Cache/org.carthage.CarthageKit
rm -rf ~/Library/Cache/Rome
rm -rf PATH_OF_PROJECT_FOLDER/Carthage

다시 프로젝트 폴더로 돌아가서 fastlane download_dependency를 실행합니다.

image1

19초가 걸렸네요!

Carting 명령어를 넣지 않았으면 의존성이 5초만에 전부 업데이트 되었을 것입니다! 결과는 너무 충격적이어서 저는 처음에 에러가 발생한 줄 알고 몇 번이고 다시 해봤습니다.

결과적으로 저희는 의존성 업데이트에 걸리던 시간 30분을 5초로 줄였습니다!

뤼이드에 와서 Carthage를 처음 쓰면서 빌드할 때(Cmd + B)마다 의존성 빌드를 기다리지 않아도 돼서 너무 좋았는데 Rome을 쓰면서 의존성을 미리 빌드하는 것조차 하지 않아도 된다는 사실이 너무 행복합니다.

원래는 글로 쓸만큼 영양가 있을 만한 내용일지 몰랐는데 쓰고나니 다른 분들에게 꼭 추천드리고 싶네요.

Carthage + Rome 조합을 꼭 사용해주세요! 가능하면 Carting까지요.

여기까지 Rome을 어떻게 하면 제대로 쓸 수 있는지에 대한 내용이었습니다! 아래는 부록으로 위 작업하면서 귀찮았거나 편했던 것을 정리해두었으니 시간나시면 읽어주세요.

글 읽어주셔서 감사합니다. 새해 복 많이 받으세요 🙇‍♂️

부록

RomefileRepositoryMap 작성하는 꿀팁

Rome을 사용하다보면 효과적인 캐싱을 위해 RomefileRepositoryMap을 작성해야 하는 경우가 있습니다.

이럴때는 Carthage 폴더의 Build에 있는 .version 파일을 보면 됩니다.

제가 주로 봤던 .version 파일은 Firebase 관련 라이브러리들인데요, 이 프레임워크들은 binary-only라서 어떤 프레임워크를 다운받고 있는지 알려주지도 않기 때문에 RepositoryMap을 작성하기가 까다로웠습니다.

다음은 .FireBaseRemoteConfigBinary.version 파일의 일부입니다.

{
  "Mac" : [

  ],
  "watchOS" : [

  ],
  "tvOS" : [

  ],
  "commitish" : "6.14.0",
  "iOS" : [
    {
      "name" : "FirebaseABTesting",
      "hash" : "7502c676a9b4cb190758484c459ee9f5640139ed60ea302e8ecaec82a80070f1"
    },
    {
      "name" : "FirebaseRemoteConfig",
      "hash" : "b116dce572de9bf2ebf5bcc23d4e84a7ae741bfec55935f3e858bc8e28b5bebb"
    },
    {
      "name" : "Protobuf",
      "hash" : "915eef3900bccfbb06fe631cb86b1b412c90474777f619d75d93057faf9e397a"
    }
  ]
}

파일 내용에서 직관적으로 알 수 있듯이 iOS 타겟에서 FirebaseABTesting, FirebaseRemoteConfig, Protobuf를 의존성으로 가지고 있다는 것을 알 수 있습니다.

그러면 Romefile엔 다음과 같이 작성하면 됩니다. (중복되는 name이 있으면 안됩니다.)

repositoryMap:
- FirebaseABTestingBinary:
  - name: FirebaseABTesting
  - name: FirebaseRemoteConfig
  - name: Protobuf

저는 이 방법을 통해 모든 Firebase 프레임워크에 대하여 캐시가 유효하다는 판정을 받았습니다.

image2

버전이 제대로 다운로드되는지 확인하는 방법

버전이 잘 받아졌다는 것은 캐시가 모두 유효하다는 것과 똑같은 뜻입니다.

먼저 캐시를 삭제합니다.

rm -rf ~/Library/Cache/carthage
rm -rf ~/Library/Cache/org.carthage.CarthageKit
rm -rf ~/Library/Cache/Rome
rm -rf PATH_OF_PROJECT_FOLDER/Carthage

프로젝트 폴더에서 다음 명령어를 실행합니다.

rome download --platform ios --concurrently && carthage bootstrap --platform ios --no-use-binaries --cache-builds

모든 캐시가 유효하다고 뜨면 성공이고 아니면 실패입니다. 실패의 주요인은 보통 Romefile이니 RepositoryMap을 확인해주세요.

image3

Carting을 소개합니다

CartingCarthage를 사용할 때 Build Phase 부분을 자동으로 완성시켜주는 스크립트입니다.

레포에도 적혀있지만 Carthage + Carting = ❤️ 입니다.

artemnovichkov/Carting

fastlane 명령어 자동 완성

fastlane 명령어 하나 하나 쓰기가 너무 귀찮아서 만들까 하고 찾아보다가 찾은 내용입니다. fastlane에서 공식 지원하는 것 같으니 편하게 쓰셔도 될 것 같습니다.

Enable tab auto complete for fastlane lane names

부록까지 읽어주셔서 감사합니다! 다시 한 번 새해 복 많이 받으세요 :)