확장 중인 모바일 팀과 주간 릴리스를 고려할 때, 안정적인 CI 파이프라인은 필수적입니다. 앱을 빌드하고 테스트한 후 App Store와 Google Play Store에 배포할 수 있어야 합니다. 또한 최신 기능을 테스트하기 위한 내부 프리뷰 버전도 유지 관리합니다.
저희가 ClickUp, Fastlane, GitHub Actions를 활용하여 지속적 통합(CI) 및 지속적 배포(CD)를 자동화하는 방법을 알아보세요.
버그의 생애 🐜
버그 관리 및 수정 프로세스를 간단히 살펴보는 것으로 시작해 보겠습니다.
- 버그(또는 기능 요청)가 보고되면 ClickUp에 작업이 생성됩니다.
- 작업은 개발자에게 할당되며 스테이징 브랜치에 대한 PR로 고정됩니다.
- CI는 모든 테스트를 실행하고, 앱을 빌드하며, 웹 미리보기를 배포하고, 모든 것을 ClickUp 작업에 업로드합니다.
- QA 팀이 수정 사항을 검증하고 문제가 없다면 해당 작업은 완료됨으로 표시됩니다.
- PR은 자동으로 스테이징 환경에 병합됩니다.
- 스테이징 브랜치는 빌드되어 내부 TestFlight 환경에 배포됩니다.
- 매주 수요일마다 릴리스 브랜치가 생성, 빌드 및 테스트됩니다.
- 매주 금요일, GitHub에 릴리스를 생성하면 CI가 해당 릴리스를 App Store와 Play Store에 배포합니다.
ClickUp 작업에는 버그에 관한 모든 정보가 포함됩니다. 진행 중이나 코드 검토 같은 맞춤형 상태를 사용하여 버그 진행 상황을 추적합니다. CI 워크플로우가 상태를 자동으로 변경합니다. 사용자 지정 필드에는 버그를 보고한 사람, 담당자, 출시 예정일 등 추가 정보가 포함됩니다.
PR 워크플로우 📜
위에서 설명한 첫 두 단계는 실제로 CI와 직접적인 관련이 없지만, 세 번째 단계는 흥미롭습니다…
개발 워크플로우(워크플로우)는 모든 PR에 대해 실행됩니다. 린트 검사, 형식 검사를 확인하고 모든 테스트를 실행한 후 Android 및 iOS 아티팩트 빌드를 시작합니다.
빌드가 성공하면 CI가 연결된 작업에 메시지를 게시합니다. QA 엔지니어는 PR로 이동하여 빌드 아티팩트를 다운로드하거나 웹 미리보기를 사용할 수 있습니다.

빌드 성공 후 연결된 ClickUp 작업에 게시되는 자동화된 CI 메시지
CI 러너에 Flutter 설정하기 🛠
CI 환경에서 Flutter를 설정하기 위해 널리 알려진 GitHub 액션인 subosito/flutter-action을 사용합니다. 기본적으로 최신 안정판 Flutter 버전이 설치됩니다. 새로운 Flutter 버전이 출시될 때 CI 워크플로우가 중단되는 것을 방지하려면 버전을 수동으로 지정해야 합니다.
여러 워크플로우가 있는 경우 플러터 버전을 파일로 저장하는 것이 좋습니다. 저희는 저장소 루트에 FLUTTER_VERSION을 사용합니다.
또 다른 쉬운 해결책은 Flutter 버전을 GitHub 비밀로 저장하고 {{ secrets.FLUTER_VERSION }}을 사용하여 접근하는 것입니다.
웹 미리보기 🕸
Flutter가 웹에서 실행될 수 있는 기능 덕분에 풀 리퀘스트의 완전한 기능의 웹 미리보기를 생성할 수 있습니다. device_preview 패키지를 사용하면 기기 크기 및 설정을 조정할 수 있습니다.
이 미리보기 기능은 매우 유용함이 입증되었으며 QA 팀뿐만 아니라 디자이너와 제품 관리자들도 새로운 기능을 신속하게 반복 작업하는 데 활용하고 있습니다.

Flutter를 통해
웹 미리보기 생성 방법 🐶
시작하기 전에, 앱이 Flutter 웹과 호환되는지 확인하세요—모든 API가 지원되는 것은 아닙니다.
예를 들어, 저희 앱에서는 푸시 알림과 웹 소켓을 비활성화해야 했습니다.
이 샘플 워크플로우에서는 Flutter 앱의 웹 미리보기를 빌드하여 S3 버킷에 업로드합니다. 프로덕션 환경에서는 ENABLE_DEVICE_PREVIEW 환경 변수를 사용하여 device_preview를 비활성화합니다.
Fix base href 단계는 미리보기가 버킷의 루트에 위치하지 않기 때문에 필요합니다.
그리고 device_preview를 조건부로 활성화하는 코드도 확인해 보세요.
환경 변수는 강력한 tool로, Flutter의 트리 셰이킹 알고리즘이 릴리스 빌드에서 디버그 코드를 제거할 수 있게 합니다.
Fastlane 💨
Fastlane은 Flutter 앱의 빌드, 서명 및 배포 과정을 크게 간소화합니다. 당사의 인증서, 프로비저닝 프로필 및 기타 설정을 관리합니다. 비밀번호와 토큰은 GitHub 시크릿을 통해 안전하게 저장합니다.
유용한 Fastlane 액션:
- fastlane match를 사용하여 GitHub 저장소에 iOS 키 및 프로필을 생성하고 저장합니다.
- iOS 및 Android 앱 빌드를 위한 build_app
- upload_to_testflight 및 iOS 빌드 배포
- upload_to_play_store를 통해 Android 빌드를 배포합니다
샘플 iOS 개발 빌드 🍏
setup_ci를 잊지 마세요. 이상한 오류로부터 여러분을 구해줄 거예요 👾. Flutter 앱을 위한 Fastlane에 대해 자세히 알아보기.
Android 서명 🔒
안드로이드 릴리스 빌드를 보안적으로 서명하는 가장 쉬운 방법은 토큰을 GitHub 시크릿으로 저장하고 환경 변수 및 CI에서 생성된 임시 키를 사용하는 것입니다.
우리는 키.jks를 base64 인코딩된 문자열로 GitHub Secrets에 저장하고 워크플로우에서 이를 디코딩합니다:
릴리스 및 프로덕션 워크플로우 🚀
릴리스 전 워크플로우는 release/v로 시작하는 브랜치에 대해 실행됩니다. 이 워크플로우에서는 디버깅 및 내부 코드를 모두 제거하여 릴리스될 코드와 동일한 코드를 테스트할 수 있도록 합니다.
또한 출시 전 워크플로우는 다양한 Slack 채널에 게시하여 들어오는 webhook을 통해 QA 및 마케팅 팀에 새 릴리스를 알립니다.
모든 테스트를 철저히 수행한 후, GitHub에서 프로덕션 워크플로우를 트리거하는 릴리스를 생성합니다. 이 릴리스는 앱을 빌드하고 프로덕션 인증서로 서명한 후 앱 스토어로 전송합니다.
CI를 위한 더 많은 팁 🦾
GitHub Actions의 푸시 트리거를 사용하는 경우, 동일한 브랜치에 짧은 시간 간격으로 여러 번 푸시가 발생하면 문제가 발생할 수 있습니다. 워크플로우 인스턴스가 여러 개 시작되어 빌드 시간을 소모하거나 다른 문제를 일으킬 수 있습니다.
- 워크플로우 인스턴스를 모두 취소하려면 '워크플로우 작업 취소' 기능을 사용하는 것이 좋습니다.
- 순차적인 빌드 번호를 생성하기 위한 쉽고 유지보수 가능한 솔루션을 찾고 계시다면, 빌드 번호 생성기를 사용해 보세요. GITHUB_RUN_ID를 사용할 수도 있지만, 이는 맞춤형 설정이 불가능합니다.
- ClickUp GitHub 앱을 확인하여 ClickUp 작업 내에서 바로 브랜치, 커밋 및 GitHub 상태를 확인하세요. 고급 자동화를 위해 ClickUp 자동화 또는 ClickUp 공개 API를 사용하세요.
요약 🍩
CI 구축은 즐거운 과정입니다. 시작하기 쉽고 진행하면서 발전시킬 수 있습니다. 저희 CI는 ClickUp의 핵심 가치 중 하나인 완벽을 향한 진보를 실천합니다. QA 및 엔지니어링 팀을 위한 CI 개선 작업을 지속적으로 진행 중입니다.
ClickUp, GitHub Actions, Fastlane의 조합은 매우 강력하여 1시간도 채 걸리지 않고 유연하고 완전히 자동화된 CI/CD 파이프라인을 구축할 수 있습니다. 한번 시도해 보세요!
앞으로 소개할 멋진 주제가 많이 준비되어 있으니, ClickUp 엔지니어링 블로그를 계속 지켜봐 주세요! 🦄

