diff --git a/.github/workflows/fastlane_ci.yml b/.github/workflows/fastlane_ci.yml new file mode 100644 index 00000000..f401f7e5 --- /dev/null +++ b/.github/workflows/fastlane_ci.yml @@ -0,0 +1,66 @@ +name: Fastlane CI + +on: + pull_request: + branches: + - main + - develop + types: [closed] + +jobs: + fastlane: + name: Run Fastlane + runs-on: macos-latest + if: github.event.pull_request.merged == true + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.1 + + - name: Install Bundler + run: gem install bundler + + - name: Install dependencies + run: bundle install + + - name: Output Fastlane environment + run: bundle exec fastlane env + + - name: Run upload_testflight + if: github.event.pull_request.base.ref == 'develop' + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + APP_IDENTIFIER: ${{ secrets.APP_IDENTIFIER }} + FASTLANE_ITC_TEAM_ID: ${{ secrets.FASTLANE_ITC_TEAM_ID }} + TEAM_ID: ${{ secrets.TEAM_ID }} + PRIVATE_REPOSITORY: ${{ secrets.PRIVATE_REPOSITORY }} + MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + DISCORD_URL: ${{ secrets.DISCORD_URL }} + run: bundle exec fastlane upload_testflight + + - name: Run release_app_store on main + if: github.event.pull_request.base.ref == 'main' + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + APP_IDENTIFIER: ${{ secrets.APP_IDENTIFIER }} + FASTLANE_ITC_TEAM_ID: ${{ secrets.FASTLANE_ITC_TEAM_ID }} + TEAM_ID: ${{ secrets.TEAM_ID }} + PRIVATE_REPOSITORY: ${{ secrets.PRIVATE_REPOSITORY }} + MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + DISCORD_URL: ${{ secrets.DISCORD_URL }} + run: bundle exec fastlane release_app_store diff --git a/ByeBoo-iOS/fastlane/Fastfile b/ByeBoo-iOS/fastlane/Fastfile index e9d58bc2..66dfbbdc 100644 --- a/ByeBoo-iOS/fastlane/Fastfile +++ b/ByeBoo-iOS/fastlane/Fastfile @@ -18,15 +18,103 @@ default_platform(:ios) ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120" ENV["FASTLANE_XCODEBUILD_SETTINGS_RETRIES"] = "10" +XCODEPROJ = "ByeBoo-iOS.xcodeproj" +SCHEME = "ByeBoo-iOS" + platform :ios do + + def notify_discord_success(lane_name) + sh( + "curl -H 'Content-Type: application/json' " + + "-d '{\"content\": \"πŸ’ŸπŸŽ **#{lane_name}** 성곡! πŸŽ‰\"}' " + + "#{ENV['DISCORD_URL']}" + ) + end + + def notify_discord_failure(lane_name, error_message) + sh( + "curl -H 'Content-Type: application/json' " + + "-d '{\"content\": \"πŸ€”πŸŒ€ **#{lane_name}** μ‹€νŒ¨\\n```#{error_message.to_s.gsub('"', "'").gsub("\n", " ")}```\"}' " + + "#{ENV['DISCORD_URL']}" + ) + end + + def prepare_ci_and_signing + setup_ci + match(type: "appstore") + update_project_team( + path: XCODEPROJ, + teamid: ENV['TEAM_ID'] + ) + end + + def next_build_number + latest_build = latest_testflight_build_number( + app_identifier: ENV['APP_IDENTIFIER'], + initial_build_number: 0 + ) + latest_build + 1 + end + + desc "Push a new beta build to TestFlight" lane :upload_testflight do - increment_build_number(xcodeproj: "ByeBoo-iOS.xcodeproj") - match(type: "appstore") - build_app( - scheme: "ByeBoo-iOS", - export_method: "app-store" - ) - upload_to_testflight + begin + iprepare_ci_and_signing + + build_number = next_build_number + increment_build_number( + xcodeproj: XCODEPROJ, + build_number: build_number + ) + + build_app( + scheme: SCHEME, + export_method: "app-store" + ) + + upload_to_testflight( + skip_waiting_for_build_processing: true + ) + + notify_discord_success("TestFlight μ—…λ‘œλ“œ", build_number) + rescue => e + notify_discord_failure("TestFlight μ—…λ‘œλ“œ", e.message) + raise e + end end + + desc "Release a new version to the App Store" + lane :release_app_store do + begin + prepare_ci_and_signing + + build_number = next_build_number + increment_build_number( + xcodeproj: XCODEPROJ, + build_number: build_number + ) + + build_app( + scheme: SCHEME, + export_method: "app-store" + ) + + upload_to_app_store( + skip_screenshots: true, + skip_metadata: true, + force: true, + submit_for_review: true, # μžλ™μœΌλ‘œ 심사 제좜 + automatic_release: true, # 심사 톡과 ν›„ μžλ™ μΆœμ‹œ + precheck_include_in_app_purchases: false, + submission_information: { + add_id_info_uses_idfa: false, # admob μΆ”κ°€ μ‹œ true둜 λ³€κ²½ + export_compliance_uses_encryption: false + } + rescue => e + notify_discord_failure("App Store 배포", e.message) + raise e + end + end + end