From bce72d776c06933b0e0b8fac16ff1fbdc5d50545 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Thu, 12 Feb 2026 18:09:22 +0100 Subject: [PATCH] Add Fastlane config and update release workflow for v2 Single unified "Yattee" scheme replaces per-platform schemes. Release workflow now has toggleable platform inputs instead of matrix strategy. Standalone mac notarized workflow removed in favor of the build_mac_notarized toggle. Share extension bundle ID updated from Open-in-Yattee to ShareExtension. --- .../build-mac-notarized-macos15-xcode16.4.yml | 59 ---- .github/workflows/release.yml | 113 ++++++-- Gemfile.lock | 92 +++--- fastlane/Appfile | 4 + fastlane/Fastfile | 269 ++++++++++++++++++ fastlane/Matchfile | 3 + fastlane/README.md | 85 ++++++ 7 files changed, 498 insertions(+), 127 deletions(-) delete mode 100644 .github/workflows/build-mac-notarized-macos15-xcode16.4.yml create mode 100644 fastlane/Appfile create mode 100644 fastlane/Fastfile create mode 100644 fastlane/Matchfile create mode 100644 fastlane/README.md diff --git a/.github/workflows/build-mac-notarized-macos15-xcode16.4.yml b/.github/workflows/build-mac-notarized-macos15-xcode16.4.yml deleted file mode 100644 index 4a27da1c..00000000 --- a/.github/workflows/build-mac-notarized-macos15-xcode16.4.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Build and notarize macOS app (macOS 15, Xcode 16.4) -on: - workflow_dispatch: - -env: - APP_NAME: Yattee - FASTLANE_USER: ${{ secrets.FASTLANE_USER }} - FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} - ITC_TEAM_ID: ${{ secrets.ITC_TEAM_ID }} - TEAM_ID: ${{ secrets.TEAM_ID }} - DEVELOPER_KEY_ID: ${{ secrets.DEVELOPER_KEY_ID }} - DEVELOPER_KEY_ISSUER_ID: ${{ secrets.DEVELOPER_KEY_ISSUER_ID }} - DEVELOPER_KEY_CONTENT: ${{ secrets.DEVELOPER_KEY_CONTENT }} - TEMP_KEYCHAIN_USER: ${{ secrets.TEMP_KEYCHAIN_USER }} - TEMP_KEYCHAIN_PASSWORD: ${{ secrets.TEMP_KEYCHAIN_PASSWORD }} - DEVELOPER_APP_IDENTIFIER: ${{ secrets.DEVELOPER_APP_IDENTIFIER }} - GIT_AUTHORIZATION: ${{ secrets.GIT_AUTHORIZATION }} - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - CERTIFICATES_GIT_URL: ${{ secrets.CERTIFICATES_GIT_URL }} - -jobs: - mac_notarized: - name: Build and notarize macOS app (macOS 15, Xcode 16.4) - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.1' - bundler-cache: true - cache-version: 1 - - name: Replace signing certificate to Direct with Developer ID - run: | - sed -i '' 's/match AppStore/match Direct/' Yattee.xcodeproj/project.pbxproj - sed -i '' 's/3rd Party Mac Developer Application/Developer ID Application/' Yattee.xcodeproj/project.pbxproj - - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '16.4' - - name: Clear SPM cache - run: | - rm -rf ~/Library/Caches/org.swift.swiftpm/artifacts - rm -rf ~/Library/Developer/Xcode/DerivedData - rm -rf .build - - uses: maierj/fastlane-action@v3.0.0 - with: - lane: mac build_and_notarize - - run: | - echo "BUILD_NUMBER=$(cat Yattee.xcodeproj/project.pbxproj | grep -m 1 CURRENT_PROJECT_VERSION | cut -d' ' -f3 | sed 's/;//g')" >> $GITHUB_ENV - echo "VERSION_NUMBER=$(cat Yattee.xcodeproj/project.pbxproj | grep -m 1 MARKETING_VERSION | cut -d' ' -f3 | sed 's/;//g')" >> $GITHUB_ENV - - run: | - echo "APP_PATH=fastlane/builds/${{ env.VERSION_NUMBER }}-${{ env.BUILD_NUMBER }}/macOS/Yattee.app" >> $GITHUB_ENV - echo "ZIP_PATH=fastlane/builds/${{ env.VERSION_NUMBER }}-${{ env.BUILD_NUMBER }}/macOS/Yattee-${{ env.VERSION_NUMBER }}-macOS.zip" >> $GITHUB_ENV - - name: ZIP build - run: /usr/bin/ditto -c -k --keepParent ${{ env.APP_PATH }} ${{ env.ZIP_PATH }} - - uses: actions/upload-artifact@v4 - with: - name: mac-notarized-build - path: ${{ env.ZIP_PATH }} - if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3290eb0..8b9885d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,27 @@ name: Build and release to TestFlight and GitHub on: workflow_dispatch: + inputs: + build_ios: + description: 'Build iOS (TestFlight)' + type: boolean + default: true + build_tvos: + description: 'Build tvOS (TestFlight)' + type: boolean + default: false + build_mac_beta: + description: 'Build macOS (TestFlight)' + type: boolean + default: false + build_mac_notarized: + description: 'Build macOS (notarized)' + type: boolean + default: false + create_release: + description: 'Create GitHub release' + type: boolean + default: true env: APP_NAME: Yattee @@ -20,13 +41,9 @@ env: TESTFLIGHT_EXTERNAL_GROUPS: ${{ secrets.TESTFLIGHT_EXTERNAL_GROUPS }} jobs: - testflight: - strategy: - matrix: - # disabled mac beta lane - # lane: ['mac beta', 'ios beta', 'tvos beta'] - lane: ['ios beta', 'tvos beta'] - name: Releasing ${{ matrix.lane }} version to TestFlight + ios_beta: + if: ${{ inputs.build_ios }} + name: Release iOS to TestFlight runs-on: macos-latest steps: - uses: actions/checkout@v4 @@ -35,24 +52,72 @@ jobs: ruby-version: '3.1' bundler-cache: true cache-version: 1 - - name: Replace signing certificate to AppStore + - name: Set signing to manual for CI run: | - sed -i '' 's/match Development/match AppStore/' Yattee.xcodeproj/project.pbxproj - sed -i '' 's/iPhone Developer/iPhone Distribution/' Yattee.xcodeproj/project.pbxproj - - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '26.0.1' + sed -i '' 's/CODE_SIGN_STYLE = Automatic/CODE_SIGN_STYLE = Manual/' Yattee.xcodeproj/project.pbxproj - name: Clear SPM cache run: rm -rf ~/Library/Caches/org.swift.swiftpm/artifacts - uses: maierj/fastlane-action@v3.0.0 with: - lane: ${{ matrix.lane }} + lane: ios beta - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.lane }} build + name: ios-beta-build path: fastlane/builds/**/*.ipa if-no-files-found: ignore + + tvos_beta: + if: ${{ inputs.build_tvos }} + name: Release tvOS to TestFlight + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.1' + bundler-cache: true + cache-version: 1 + - name: Set signing to manual for CI + run: | + sed -i '' 's/CODE_SIGN_STYLE = Automatic/CODE_SIGN_STYLE = Manual/' Yattee.xcodeproj/project.pbxproj + - name: Clear SPM cache + run: rm -rf ~/Library/Caches/org.swift.swiftpm/artifacts + - uses: maierj/fastlane-action@v3.0.0 + with: + lane: tvos beta + - uses: actions/upload-artifact@v4 + with: + name: tvos-beta-build + path: fastlane/builds/**/*.ipa + if-no-files-found: ignore + + mac_beta: + if: ${{ inputs.build_mac_beta }} + name: Release macOS to TestFlight + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.1' + bundler-cache: true + cache-version: 1 + - name: Set signing to manual for CI + run: | + sed -i '' 's/CODE_SIGN_STYLE = Automatic/CODE_SIGN_STYLE = Manual/' Yattee.xcodeproj/project.pbxproj + - name: Clear SPM cache + run: rm -rf ~/Library/Caches/org.swift.swiftpm/artifacts + - uses: maierj/fastlane-action@v3.0.0 + with: + lane: mac beta + - uses: actions/upload-artifact@v4 + with: + name: mac-beta-build + path: fastlane/builds/**/*.pkg + if-no-files-found: ignore + mac_notarized: + if: ${{ inputs.build_mac_notarized }} name: Build and notarize macOS app runs-on: macos-latest steps: @@ -62,13 +127,9 @@ jobs: ruby-version: '3.1' bundler-cache: true cache-version: 1 - - name: Replace signing certificate to Direct with Developer ID + - name: Set signing to manual with Developer ID run: | - sed -i '' 's/match AppStore/match Direct/' Yattee.xcodeproj/project.pbxproj - sed -i '' 's/3rd Party Mac Developer Application/Developer ID Application/' Yattee.xcodeproj/project.pbxproj - - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '26.0.1' + sed -i '' 's/CODE_SIGN_STYLE = Automatic/CODE_SIGN_STYLE = Manual/' Yattee.xcodeproj/project.pbxproj - name: Clear SPM cache run: rm -rf ~/Library/Caches/org.swift.swiftpm/artifacts - uses: maierj/fastlane-action@v3.0.0 @@ -84,11 +145,13 @@ jobs: run: /usr/bin/ditto -c -k --keepParent ${{ env.APP_PATH }} ${{ env.ZIP_PATH }} - uses: actions/upload-artifact@v4 with: - name: mac notarized build + name: mac-notarized-build path: ${{ env.ZIP_PATH }} if-no-files-found: error + release: - needs: ['testflight', 'mac_notarized'] + if: ${{ inputs.create_release && !cancelled() }} + needs: ['ios_beta', 'tvos_beta', 'mac_beta', 'mac_notarized'] name: Create GitHub release runs-on: ubuntu-latest steps: @@ -100,12 +163,12 @@ jobs: path: artifacts - uses: ncipollo/release-action@v1 with: - artifacts: artifacts/**/*.ipa,artifacts/**/*.zip + artifacts: artifacts/**/*.ipa,artifacts/**/*.zip,artifacts/**/*.pkg commit: main tag: ${{ env.VERSION_NUMBER }}-${{ env.BUILD_NUMBER }} prerelease: true bodyFile: CHANGELOG.md + update_altstore: needs: ['release'] uses: ./.github/workflows/update-altstore.yml - diff --git a/Gemfile.lock b/Gemfile.lock index f3ab5731..bde794f5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,8 +9,8 @@ GEM ast (2.4.3) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1198.0) - aws-sdk-core (3.240.0) + aws-partitions (1.1213.0) + aws-sdk-core (3.242.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -18,17 +18,18 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.118.0) - aws-sdk-core (~> 3, >= 3.239.1) + aws-sdk-kms (1.121.0) + aws-sdk-core (~> 3, >= 3.241.4) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.209.0) - aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-s3 (1.213.0) + aws-sdk-core (~> 3, >= 3.241.4) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.12.1) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) + benchmark (0.5.0) bigdecimal (4.0.1) claide (1.1.0) colored (1.2) @@ -44,7 +45,7 @@ GEM dotenv (2.8.1) emoji_regex (3.2.3) excon (0.112.0) - faraday (1.10.4) + faraday (1.10.5) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -63,7 +64,7 @@ GEM faraday-em_synchrony (1.0.1) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.1.1) + faraday-multipart (1.2.0) multipart-post (~> 2.0) faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) @@ -73,15 +74,16 @@ GEM faraday_middleware (1.2.1) faraday (~> 1.0) fastimage (2.4.0) - fastlane (2.230.0) + fastlane (2.232.1) CFPropertyList (>= 2.3, < 4.0.0) abbrev (~> 0.1.2) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) - aws-sdk-s3 (~> 1.0) + aws-sdk-s3 (~> 1.197) babosa (>= 1.0.3, < 2.0.0) base64 (~> 0.2.0) - bundler (>= 1.12.0, < 3.0.0) + benchmark (>= 0.1.0) + bundler (>= 1.17.3, < 5.0.0) colored (~> 1.2) commander (~> 4.6) csv (~> 3.3) @@ -96,7 +98,7 @@ GEM gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) - google-cloud-env (>= 1.6.0, < 2.0.0) + google-cloud-env (>= 1.6.0, <= 2.1.1) google-cloud-storage (~> 1.31) highline (~> 2.0) http-cookie (~> 1.0.5) @@ -109,6 +111,7 @@ GEM naturally (~> 2.2) nkf (~> 0.2.0) optparse (>= 0.1.1, < 1.0.0) + ostruct (>= 0.1.0) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.5) @@ -124,38 +127,40 @@ GEM fastlane-sirp (1.0.0) sysrandom (~> 1.0) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.54.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.3) + google-apis-androidpublisher_v3 (0.96.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-core (0.18.0) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) mini_mime (~> 1.0) + mutex_m representable (~> 3.0) retriable (>= 2.0, < 4.a) - rexml - google-apis-iamcredentials_v1 (0.17.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-playcustomapp_v1 (0.13.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.31.0) - google-apis-core (>= 0.11.0, < 2.a) + google-apis-iamcredentials_v1 (0.26.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-playcustomapp_v1 (0.17.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-storage_v1 (0.60.0) + google-apis-core (>= 0.15.0, < 2.a) google-cloud-core (1.8.0) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) - google-cloud-env (1.6.0) - faraday (>= 0.17.3, < 3.0) + google-cloud-env (2.1.1) + faraday (>= 1.0, < 3.a) google-cloud-errors (1.5.0) - google-cloud-storage (1.47.0) + google-cloud-storage (1.58.0) addressable (~> 2.8) digest-crc (~> 0.4) - google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.31.0) + google-apis-core (>= 0.18, < 2) + google-apis-iamcredentials_v1 (~> 0.18) + google-apis-storage_v1 (>= 0.42) google-cloud-core (~> 1.6) - googleauth (>= 0.16.2, < 2.a) + googleauth (~> 1.9) mini_mime (~> 1.0) - googleauth (1.8.1) - faraday (>= 0.17.3, < 3.a) + googleauth (1.11.2) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.1) jwt (>= 1.4, < 3.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) @@ -166,7 +171,7 @@ GEM httpclient (2.9.0) mutex_m jmespath (1.6.2) - json (2.18.0) + json (2.18.1) jwt (2.10.2) base64 language_server-protocol (3.17.0.5) @@ -174,7 +179,7 @@ GEM logger (1.7.0) mini_magick (4.13.2) mini_mime (1.1.5) - multi_json (1.18.0) + multi_json (1.19.1) multipart-post (2.4.1) mutex_m (0.3.0) nanaimo (0.4.0) @@ -182,13 +187,14 @@ GEM nkf (0.2.0) optparse (0.8.1) os (1.1.4) + ostruct (0.6.3) parallel (1.27.0) - parser (3.3.10.0) + parser (3.3.10.1) ast (~> 2.4.1) racc plist (3.7.2) - prism (1.7.0) - public_suffix (7.0.0) + prism (1.9.0) + public_suffix (7.0.2) racc (1.8.1) rainbow (3.1.1) rake (13.3.1) @@ -214,8 +220,8 @@ GEM rspec-support (~> 3.13.0) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.13.6) - rubocop (1.82.1) + rspec-support (3.13.7) + rubocop (1.84.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -223,13 +229,13 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.48.0, < 2.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.48.0) + rubocop-ast (1.49.0) parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-rspec (3.8.0) + prism (~> 1.7) + rubocop-rspec (3.9.0) lint_roller (~> 1.1) rubocop (~> 1.81) ruby-progressbar (1.13.0) diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 00000000..11b1ed13 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,4 @@ +app_identifier(ENV['DEVELOPER_APP_IDENTIFIER']) +apple_id(ENV['FASTLANE_USER']) +itc_team_id(ENV['ITC_TEAM_ID']) +team_id(ENV['TEAM_ID']) diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 00000000..47e3f05a --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,269 @@ +# Yattee v2 Fastlane configuration +# Single unified "Yattee" scheme, platform selected via destination parameter + +APP_NAME = ENV['APP_NAME'] || 'Yattee' +DEVELOPER_KEY_ID = ENV['DEVELOPER_KEY_ID'] +DEVELOPER_KEY_ISSUER_ID = ENV['DEVELOPER_KEY_ISSUER_ID'] +DEVELOPER_KEY_CONTENT = ENV['DEVELOPER_KEY_CONTENT'] +TEAM_ID = ENV['TEAM_ID'] +TEMP_KEYCHAIN_USER = ENV['TEMP_KEYCHAIN_USER'] +TEMP_KEYCHAIN_PASSWORD = ENV['TEMP_KEYCHAIN_PASSWORD'] +DEVELOPER_APP_IDENTIFIER = ENV['DEVELOPER_APP_IDENTIFIER'] +GIT_AUTHORIZATION = ENV['GIT_AUTHORIZATION'] +TESTFLIGHT_EXTERNAL_GROUPS = ENV['TESTFLIGHT_EXTERNAL_GROUPS'] + +XCODEPROJ = "#{APP_NAME}.xcodeproj" +SCHEME = APP_NAME + +def delete_temp_keychain(name) + delete_keychain( + name: name + ) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db") +end + +def create_temp_keychain(name, password) + create_keychain( + name: name, + password: password, + unlock: false, + timeout: 0 + ) +end + +def ensure_temp_keychain(name, password) + delete_temp_keychain(name) + create_temp_keychain(name, password) +end + +add_extra_platforms(platforms: [:tvos]) + +before_all do + update_fastlane +end + +desc "Bump build number and commit" +lane :bump_build do + increment_build_number(xcodeproj: XCODEPROJ) + + commit_version_bump( + message: "Bump build number to #{get_build_number(xcodeproj: XCODEPROJ)}", + xcodeproj: XCODEPROJ + ) +end + +desc "Bump version number and commit" +lane :bump_version do + increment_version_number(xcodeproj: XCODEPROJ) + + commit_version_bump( + message: "Bump version number to #{get_version_number(xcodeproj: XCODEPROJ, target: SCHEME)}", + xcodeproj: XCODEPROJ + ) +end + +platform :ios do + desc "Push a new beta build to TestFlight" + lane :beta do + ensure_temp_keychain(TEMP_KEYCHAIN_USER, TEMP_KEYCHAIN_PASSWORD) + + api_key = app_store_connect_api_key( + key_id: DEVELOPER_KEY_ID, + issuer_id: DEVELOPER_KEY_ISSUER_ID, + key_content: DEVELOPER_KEY_CONTENT, + is_key_content_base64: true + ) + + build = get_build_number(xcodeproj: XCODEPROJ) + version = get_version_number( + xcodeproj: XCODEPROJ, + target: SCHEME + ) + + match( + type: 'appstore', + platform: 'ios', + app_identifier: ["#{DEVELOPER_APP_IDENTIFIER}", "#{DEVELOPER_APP_IDENTIFIER}.ShareExtension"], + git_basic_authorization: Base64.strict_encode64(GIT_AUTHORIZATION), + readonly: true, + keychain_name: TEMP_KEYCHAIN_USER, + keychain_password: TEMP_KEYCHAIN_PASSWORD, + api_key: api_key + ) + + build_app( + scheme: SCHEME, + destination: "generic/platform=iOS", + output_directory: "fastlane/builds/#{version}-#{build}/iOS", + output_name: "#{APP_NAME}-#{version}-iOS.ipa", + export_options: { + provisioningProfiles: { + "#{DEVELOPER_APP_IDENTIFIER}" => "match AppStore #{DEVELOPER_APP_IDENTIFIER}", + "#{DEVELOPER_APP_IDENTIFIER}.ShareExtension" => "match AppStore #{DEVELOPER_APP_IDENTIFIER}.ShareExtension" + } + } + ) + + changelog_path = File.expand_path('../CHANGELOG.md', __dir__) + changelog = File.exist?(changelog_path) ? File.read(changelog_path) : "" + + upload_to_testflight( + api_key: api_key, + ipa: lane_context[SharedValues::IPA_OUTPUT_PATH], + changelog: changelog + ) + end +end + +platform :tvos do + desc "Push a new beta build to TestFlight" + lane :beta do + ensure_temp_keychain(TEMP_KEYCHAIN_USER, TEMP_KEYCHAIN_PASSWORD) + + api_key = app_store_connect_api_key( + key_id: DEVELOPER_KEY_ID, + issuer_id: DEVELOPER_KEY_ISSUER_ID, + key_content: DEVELOPER_KEY_CONTENT, + is_key_content_base64: true + ) + + build = get_build_number(xcodeproj: XCODEPROJ) + version = get_version_number( + xcodeproj: XCODEPROJ, + target: SCHEME + ) + + match( + type: 'appstore', + platform: 'tvos', + app_identifier: "#{DEVELOPER_APP_IDENTIFIER}", + git_basic_authorization: Base64.strict_encode64(GIT_AUTHORIZATION), + readonly: true, + keychain_name: TEMP_KEYCHAIN_USER, + keychain_password: TEMP_KEYCHAIN_PASSWORD, + api_key: api_key + ) + + build_app( + scheme: SCHEME, + destination: "generic/platform=tvOS", + output_directory: "fastlane/builds/#{version}-#{build}/tvOS", + output_name: "#{APP_NAME}-#{version}-tvOS.ipa", + export_method: "app-store", + export_options: { + provisioningProfiles: { + "#{DEVELOPER_APP_IDENTIFIER}" => "match AppStore #{DEVELOPER_APP_IDENTIFIER} tvos" + } + } + ) + + changelog_path = File.expand_path('../CHANGELOG.md', __dir__) + changelog = File.exist?(changelog_path) ? File.read(changelog_path) : "" + + upload_to_testflight( + api_key: api_key, + ipa: lane_context[SharedValues::IPA_OUTPUT_PATH], + changelog: changelog + ) + end +end + +platform :mac do + desc "Push a new beta build to TestFlight" + lane :beta do + ensure_temp_keychain(TEMP_KEYCHAIN_USER, TEMP_KEYCHAIN_PASSWORD) + + api_key = app_store_connect_api_key( + key_id: DEVELOPER_KEY_ID, + issuer_id: DEVELOPER_KEY_ISSUER_ID, + key_content: DEVELOPER_KEY_CONTENT, + is_key_content_base64: true + ) + + build = get_build_number(xcodeproj: XCODEPROJ) + version = get_version_number( + xcodeproj: XCODEPROJ, + target: SCHEME + ) + + match( + type: 'appstore', + platform: 'macos', + additional_cert_types: ['mac_installer_distribution'], + app_identifier: "#{DEVELOPER_APP_IDENTIFIER}", + git_basic_authorization: Base64.strict_encode64(GIT_AUTHORIZATION), + readonly: true, + keychain_name: TEMP_KEYCHAIN_USER, + keychain_password: TEMP_KEYCHAIN_PASSWORD, + api_key: api_key + ) + + build_mac_app( + scheme: SCHEME, + output_directory: "fastlane/builds/#{version}-#{build}/macOS", + output_name: "#{APP_NAME}-#{version}-macOS.app", + export_method: "app-store", + export_options: { + provisioningProfiles: { + "#{DEVELOPER_APP_IDENTIFIER}" => "match AppStore #{DEVELOPER_APP_IDENTIFIER} macos" + } + } + ) + + changelog_path = File.expand_path('../CHANGELOG.md', __dir__) + changelog = File.exist?(changelog_path) ? File.read(changelog_path) : "" + + upload_to_testflight( + api_key: api_key, + pkg: lane_context[SharedValues::PKG_OUTPUT_PATH], + changelog: changelog + ) + end + + desc "Build for Developer ID distribution and notarize" + lane :build_and_notarize do + ensure_temp_keychain(TEMP_KEYCHAIN_USER, TEMP_KEYCHAIN_PASSWORD) + + api_key = app_store_connect_api_key( + key_id: DEVELOPER_KEY_ID, + issuer_id: DEVELOPER_KEY_ISSUER_ID, + key_content: DEVELOPER_KEY_CONTENT, + is_key_content_base64: true + ) + + build = get_build_number(xcodeproj: XCODEPROJ) + version = get_version_number( + xcodeproj: XCODEPROJ, + target: SCHEME + ) + + match( + type: 'developer_id', + platform: 'macos', + app_identifier: "#{DEVELOPER_APP_IDENTIFIER}", + git_basic_authorization: Base64.strict_encode64(GIT_AUTHORIZATION), + readonly: true, + keychain_name: TEMP_KEYCHAIN_USER, + keychain_password: TEMP_KEYCHAIN_PASSWORD, + api_key: api_key + ) + + build_mac_app( + scheme: SCHEME, + output_directory: "fastlane/builds/#{version}-#{build}/macOS", + output_name: APP_NAME, + export_method: "developer-id", + export_options: { + provisioningProfiles: { + "#{DEVELOPER_APP_IDENTIFIER}" => "match Direct #{DEVELOPER_APP_IDENTIFIER} macos" + } + } + ) + + notarize( + package: "fastlane/builds/#{version}-#{build}/macOS/#{APP_NAME}.app", + bundle_id: "#{DEVELOPER_APP_IDENTIFIER}", + api_key: api_key, + print_log: true + ) + end +end diff --git a/fastlane/Matchfile b/fastlane/Matchfile new file mode 100644 index 00000000..144263e7 --- /dev/null +++ b/fastlane/Matchfile @@ -0,0 +1,3 @@ +git_url(ENV['CERTIFICATES_GIT_URL']) +storage_mode("git") +type("appstore") diff --git a/fastlane/README.md b/fastlane/README.md new file mode 100644 index 00000000..27d5d38c --- /dev/null +++ b/fastlane/README.md @@ -0,0 +1,85 @@ +fastlane documentation +---- + +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +```sh +xcode-select --install +``` + +For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) + +# Available Actions + +### bump_build + +```sh +[bundle exec] fastlane bump_build +``` + +Bump build number and commit + +### bump_version + +```sh +[bundle exec] fastlane bump_version +``` + +Bump version number and commit + +---- + + +## iOS + +### ios beta + +```sh +[bundle exec] fastlane ios beta +``` + +Push a new beta build to TestFlight + +---- + + +## tvos + +### tvos beta + +```sh +[bundle exec] fastlane tvos beta +``` + +Push a new beta build to TestFlight + +---- + + +## Mac + +### mac beta + +```sh +[bundle exec] fastlane mac beta +``` + +Push a new beta build to TestFlight + +### mac build_and_notarize + +```sh +[bundle exec] fastlane mac build_and_notarize +``` + +Build for Developer ID distribution and notarize + +---- + +This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. + +More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). + +The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).