일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Swift
- 성능 개선
- appstore
- DevTools
- TextInputFormatter
- Codemagic
- FocusNode
- 갤럭시폴드
- Codepush
- FLUTTER
- MVVM
- abstact
- IOS
- reject
- flutter web
- shorebird
- 무선빌드
- struct
- GetX
- fastlane
- Equatable
- Xcode
- SHIMMER
- PG결제
- BloC
- copy on write
- reactivex
- Android
- delegate
- error
- Today
- Total
뚝딱뚝딱 모바일
[Flutter] Code Push를 해보라고요? (2) - 맨땅에 헤딩하는 법 본문
아래 글에서 이어집니다.
[Flutter] Code Push를 해보라고요? (1) - 지피지기
오늘도 열심히 앱을 개발하고, QA를 거치고, 구글 플레이 스토어와 애플 앱스토어 심사를 거친 후 앱을 업데이트했습니다.어?? 앱 배포 후 미처 발견 못한 오류를 발견하였습니다.큰일 났습니다.
nkstar-ios.tistory.com
Codemagic의 악몽
기존 Codemagic 빌드가 있기에 간단하게 붙이면 되겠다~ 생각하고 호기롭게 Codemagic 연계 문서를 클릭하였습니다.
어? 이게 뭐지? 이런 건 처음 보는데? 싶은 yaml 파일이 쫜! 하고 앞에 있었습니다.
그렇습니다. Codemagic은 GUI 형식의 Workflow Editor와 yaml 파일, 두 가지 방식의 빌드 flow를 지원하고 있었고, Shorebird를 적용하기 위해서는 yaml 파일을 새로 만들어야 했습니다!
슬퍼할 시간도 없이 바로 Docs를 정독하기 시작하였습니다.
Codemagic Integration
Integrate Shorebird into your Codemagic workflow
docs.shorebird.dev
How to Set Up Flutter Code Push With Shorebird and Codemagic | Codemagic Blog
Learn how to set up Flutter code push with Shorebird and Codemagic
blog.codemagic.io
Using codemagic.yaml
Configure all your workflows in a single file
docs.codemagic.io
자료가 없다 보니 그냥 공식 Docs 위주로 닥치는 대로 봤던 것 같습니다. 그중에서 가장 도움이 되었다고 생각하는 문서들입니다. 쭉 읽어보시면 좋을 것 같습니다.
Codemagic 세팅
shorebird 로그인 후 나온 토큰을 Codemagic에 넣어주어야 사용이 가능해집니다.
Codemagic 프로젝트를 yaml 파일로 변경 후 좌측 탭의 Environment variables에 진입해 줍니다.
SHOREBIRD_TOKEN 키값으로 토큰을 넣어주고 group명은 shorebird로 적어줍니다. Secure 항목도 체크해주어야 합니다.
스토어 관련 환경변수 세팅
이번엔 각 스토어에 자동 배포를 위한 환경변수를 세팅해 보겠습니다.
위 첨부한 링크들을 보시면 더욱 도움 되실 겁니다.
Codemagic 좌측 탭의 Teams -> codemagic.yaml settings -> Code signing identites에 각각의 인증서를 포함하여 주면 됩니다. 각각 이름은 codemagic.yaml에 사용할 것이기에 명확한 이름으로 지어주시면 좋습니다.
- iOS : p12파일 및 provisioning profiles
- AOS : key store
구글은 API 권한이 필요하므로, 구글 API 권한 json을 발급받아 SHOREBIRD_TOKEN을 넣어둔 Environment variables에 넣어주시면 됩니다. 여기 키값도 codemagic.yaml에서 사용할 것입니다.
애플도 연결해 줍시다. Codemagic 좌측 탭의 Teams -> General settings -> Integrations의 Developer Portal을 클릭하여 key를 추가해 주시면 됩니다. 물론 여기 키값도 codemagic.yaml에서 사용할 것입니다.
codemagic.yaml 원문
매우 매우 많은 시행착오와 오류를 겪고...
성공적인 codemagic.yaml 파일을 작성할 수 있었습니다.
아래 설명과 함께 한 번씩 보시면 좋을 것 같습니다!
definitions:
# Reusable definitions go in this section
scripts:
- &shorebird_install
name: Install Shorebird CLI
script: |
# Install the Shorebird CLI
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
# Set Shorebird PATH
echo PATH="/Users/builder/.shorebird/bin:$PATH" >> $CM_ENV
- &setup_local_properties
name: Set up local.properties
script: echo "flutter.sdk=$HOME/programs/flutter" > "$CM_BUILD_DIR/android/local.properties"
- &use_provisioning_profiles
name: Use provisioning profiles
script: xcode-project use-profiles
- &flutter_setting
name: Flutter setting
script: |
flutter pub get
dart run build_runner build
- &release_android
name: Release Android
script: shorebird release android --flutter-version=3.22.2 --target lib/main_prod.dart
- &release_ios
name: Release iOS
script: shorebird release ios --flutter-version=3.22.2 --target lib/main_prod.dart -- --export-options-plist=/Users/builder/export_options.plist
# patch should behind get version
- &patch_android
name: Patch Android
script: |
VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
echo "Version: $VERSION"
shorebird patch android --target lib/main_prod.dart --release-version=$VERSION
- &patch_ios
name: Patch iOS
script: |
VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
echo "Version: $VERSION"
shorebird patch ios --target lib/main_prod.dart --release-version=$VERSION -- --export-options-plist=/Users/builder/export_options.plist
- &sentry_debug_file_upload
name: Sentry Debug File Upload
script: flutter packages pub run sentry_dart_plugin
workflows:
app-deploy-workflow:
name: Deploy
instance_type: mac_mini_m1
environment:
ios_signing:
provisioning_profiles:
- ios-profile
certificates:
- ios-certificate
android_signing:
- android-keystore
groups:
- shorebird
- google_credentials
flutter: 3.22.2
xcode: 15.4
integrations:
app_store_connect: app-store-connect
scripts:
- *setup_local_properties
- *shorebird_install
- *flutter_setting
- *release_android
- *use_provisioning_profiles
- *release_ios
- *sentry_debug_file_upload
artifacts:
- build/**/outputs/**/*.aab
- build/**/outputs/apk/**/*.apk
- build/ios/ipa/*.ipa
publishing:
app_store_connect:
auth: integration
google_play:
track: production
credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
slack:
channel: 'your_channel'
notify_on_build_start: true # To receive a notification when a build starts
notify:
success: true # To not receive a notification when a build succeeds
failure: true # To not receive a notification when a build fails
patch-workflow:
name: Hotfix Patch
instance_type: mac_mini_m1
environment:
android_signing:
- android-keystore
ios_signing:
provisioning_profiles:
- ios-profile
certificates:
- ios-certificate
groups:
- shorebird
flutter: 3.22.2
xcode: 15.4
scripts:
- *setup_local_properties
- *shorebird_install
- *flutter_setting
- *patch_android
- *use_provisioning_profiles
- *patch_ios
- *sentry_debug_file_upload
publishing:
slack:
channel: 'your_channel'
notify_on_build_start: true # To receive a notification when a build starts
notify:
success: true # To not receive a notification when a build succeeds
failure: true # To not receive a notification when a build fails
각 Script와 workflow에 대해 설명드리겠습니다. (저희 회사 기준이기에 입맛에 맞게 수정하시면 됩니다.)
각각의 Script 설명
shorebird_install
- &shorebird_install
name: Install Shorebird CLI
script: |
# Install the Shorebird CLI
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
# Set Shorebird PATH
echo PATH="/Users/builder/.shorebird/bin:$PATH" >> $CM_ENV
Shorebird를 install 하는 Script입니다. flow를 시작할 때 실행해 주시면 됩니다.
setup_local_properties
- &setup_local_properties
name: Set up local.properties
script: echo "flutter.sdk=$HOME/programs/flutter" > "$CM_BUILD_DIR/android/local.properties"
안드로이드 빌드할 때 사용하는 Script로, Flutter SDK 경로를 설정할 때 사용합니다.
use_provisioning_profiles
- &use_provisioning_profiles
name: Use provisioning profiles
script: xcode-project use-profiles
iOS 빌드할 때 사용하는 Script로, Xcode가 빌드할 때 프로비저닝 프로필을 사용하도록 합니다.
flutter_setting
- &flutter_setting
name: Flutter setting
script: |
flutter pub get
dart run build_runner build
프로젝트의 pubspec.yaml에 적혀있는 라이브러리를 가져오고, build_runner를 통해 추가적인 파일을 만들어냅니다. (build_runner를 사용하지 않으면 아래 명령어는 빼도 무방합니다.)
Android 관련 Scripts
- &release_android
name: Release Android
script: shorebird release android --flutter-version=3.22.2 --target lib/main_prod.dart
- &patch_android
name: Patch Android
script: |
VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
echo "Version: $VERSION"
shorebird patch android --target lib/main_prod.dart --release-version=$VERSION
- release_andoird : Shorebird를 통해 android를 빌드합니다.
- patch_android : pubspec.yaml의 version을 가져와 Shorebird를 통해 patch를 진행합니다.
iOS 관련 Scripts
- &release_ios
name: Release iOS
script: shorebird release ios --flutter-version=3.22.2 --target lib/main_prod.dart -- --export-options-plist=/Users/builder/export_options.plist
- &patch_ios
name: Patch iOS
script: |
VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
echo "Version: $VERSION"
shorebird patch ios --target lib/main_prod.dart --release-version=$VERSION -- --export-options-plist=/Users/builder/export_options.plist
- release_ios : Shorebird를 통해 iOS를 빌드합니다.
- patch_ios : pubspec.yaml의 version을 가져와 Shorebird를 통해 patch를 진행합니다.
sentry_debug_file_upload
- &sentry_debug_file_upload
name: Sentry Debug File Upload
script: flutter packages pub run sentry_dart_plugin
센트리 디버그 파일을 업로드하여, 오류가 발생한 위치를 알 수 있게 해 줍니다. 센트리를 사용하지 않다면 빼셔도 무방합니다.
Workflow 설명
앱을 스토어에 심사 직전까지 올려주는 app-deploy-workflow,
Shorebird를 통해 코드푸시를 진행하는 patch-workflow가 있습니다.
Workflow에 사용되는 인자에 대해 간단히 설명드리면
- name : Codemagic에서 표기되는 Workflow의 이름입니다. 명확한 이름으로 해주시면 좋습니다.
- instance_type : 가상 환경을 구동할 기기를 뜻합니다. iOS까지 빌드하여야 하기에 무조건 맥으로 설정하여야 합니다. (iOS를 안 하실 거면 Window나 Linux로 하여도 무방합니다.)
- environment : 환경변수들을 지정해 주는 필드입니다.
- ios_signing
- provisioning_profiles : 위에서 설정해 둔 프로비저닝 프로필의 이름을 넣어주시면 됩니다.
- certificates : 위에서 설정해 둔 인증서의 이름을 넣어주시면 됩니다.
- android_signing : 위에서 설정해둔 keystore의 이름을 넣어주시면 됩니다.
- groups : Environment variables에 설정해둔 group의 이름을 넣어주시면 됩니다. shorebird와 구글 API json 그룹명을 넣어주었습니다.
- flutter : flutter 버전을 뜻합니다. 저희 같은 경우는 3.22.2를 사용 중이라 3.22.2를 지정해 주었습니다.
- xcode : xcode 버전입니다. 저희는 xcode 16.0 마이그레이션을 진행하지 않아 15.4를 사용 중입니다.
- ios_signing
- integrations
- app_store_connect : 위에서 설정해 둔 Developer Portal의 이름을 적어주시면 됩니다.
- scripts : 본인이 빌드하고자 하는 순서대로 넣어주시면 됩니다.
- artifacts : 빌드가 완료되면 Codemagic을 통해 받으려고 하는 파일의 경로들입니다. 빌드가 끝나면 다운로드 링크가 제공됩니다.
- publishing : 퍼블리싱 관련 필드입니다.
- app_store_connect : App Store Connect로 업로드합니다.
- auth : 위에서 설정해둔 integration에서 가져오도록 해주었습니다.
- google_play : Google Play Console로 업로드합니다.
- track : Google Play Console에서 설정하신 track명을 적어주시면 됩니다.
- credentials : 위에서 설정한 구글 API의 키값(그룹명 아님!)을 적어주시면 됩니다.
- slack (참고 링크) : 슬랙 메시지를 보내줍니다.
- app_store_connect : App Store Connect로 업로드합니다.
Shorebird 통해서 Code Push 하기
이렇게 Codemagic을 설정하고, deploy flow를 통해서 배포 진행 후 코드 수정 후 patch flow를 실행하시면 됩니다.
배포 후에는 콘솔을 확인해 보시면 아래 사진과 같이 버전이 추가됩니다.
버전명을 클릭하여 아래 화면에 들어올 수 있습니다.
Code Push를 했다면, 이렇게 Patch가 추가됩니다. 이 탭에서 각각의 Patch들을 활성화 / 비활성화할 수 있고, Install 여부를 볼 수 있습니다.
주의사항
현재 배포된 버전과 patch 버전이 무조건 같아야 한다는 것입니다. 예시로 배포 버전 1.1.2+13이면 patch 버전 또한 1.1.2+13이어야 합니다. 메이저, 마이너, 패치, 빌드 넘버까지 모두 같아야 합니다.
또한, 전 글에서 말했듯 Shorebird는 Dart파일의 변경만을 감지하고 적용합니다. 그렇기에 asset을 변경했다거나, 다른 라이브러리를 추가하여 yaml 파일이 달라졌다면, 이는 적용이 되지 않습니다.
Code Push 후기
4~5번 정도의 Code Push를 진행하였는데요, 딱 임시방편의 느낌이 강했습니다.
Shorebird는 앱을 껐다 켜게 되면 적용이 되는데요. 이것이 사람마다 적용 시간이 달랐습니다.
저는 Code Push 후 30분 내로 적용이 되었고, 회사 분들은 1시간, 2시간 등등 편차가 다양했습니다.
그리고 모두가 적용이 되는 것이 아닌 것 같습니다. 한 분이 유독 Code Push가 적용이 안되었습니다. 추측하기로는 자동 업데이트 설정을 끄면 적용이 안 되는 것이 아닐까?라는 생각으로 자동 업데이트 설정을 켜고 앱을 재설치하니 적용이 되었습니다. 정확한 원인인지는 모르겠으나, Code Push 변경 사항이 적용이 되지 않았다면 이를 의심해 볼 수 있습니다.
이러한 점 때문에, 크리티컬 한 이슈가 터졌을 때 약간의 유저라도 불편을 덜 겪게 하자!라고 생각하신다면 Shorebird 사용을 추천드립니다. 그게 아니라면 스토어를 통한 정식 업데이트가 더욱 좋을 수 있습니다.
뭐야 되게 간단하네?라고 생각하실 겁니다. 저도 지금 보니 되게 간단한 내용 같습니다.
하지만 이렇게 구성하기까지 정말 많은 오류와 시행착오를 겪었습니다. 개발 당시 자료가 너무 없었고, 공식 Docs도 지금처럼 세세하게 작성이 안되어 있어, 그냥 제 맘대로 넣어보고, 실패하면 고치고를 수십 수백 번 반복했었습니다. 진짜 맨땅에 헤딩을 하듯 시도했고, 다행히 저는 머리가 깨지지 않고 머리가 단단해졌습니다.
이걸 통해서 자료가 없을 때 개발 하는 법과 가끔은 무식하게 맨땅에 헤딩하는 편이 자료를 찾고 분석하고 진행하는 것보다 좋을 때가 있다를 깨달았습니다. 이 Code Push를 적용하면서 좀 더 한 단계 성장한 기분이 듭니다.
다음 편은 제가 만났던 오류와 제 실수들을 적어보려고 합니다. 많은 도움이 되길 바라겠습니다.
'실무 이야기' 카테고리의 다른 글
[Flutter] Code Push를 해보라고요? (1) - 지피지기 (2) | 2024.11.22 |
---|---|
[Android] 갤럭시 폴드는 없지만 대응은 하고 싶어 (2) | 2024.11.19 |
[Flutter] PG결제 웹뷰 만들다 만난 이슈들 (1) | 2024.01.02 |
[Flutter] 아키텍처에 대한 고민 (2) - 익숙해지니 보이는 것들 (3) | 2023.12.07 |
[Flutter] 아키텍처에 대한 고민 (1) - 처음 해보는 Flutter (2) | 2023.12.07 |