diff --git a/.flutter-version b/.flutter-version new file mode 100644 index 0000000..9905a22 --- /dev/null +++ b/.flutter-version @@ -0,0 +1 @@ +3.41.4 diff --git a/.gitignore b/.gitignore index f7a4973..6d4d752 100644 --- a/.gitignore +++ b/.gitignore @@ -54,8 +54,7 @@ android/app/*.jks android/app/*.keystore # Fastlane -android/fastlane/play-store-key.json -android/fastlane/.image_hashes.json -ios/fastlane/report.xml -android/fastlane/report.xml +fastlane/play-store-key.json +fastlane/.image_hashes.json +fastlane/report.xml /.envrc diff --git a/android/Gemfile b/Gemfile similarity index 100% rename from android/Gemfile rename to Gemfile diff --git a/android/Gemfile.lock b/Gemfile.lock similarity index 100% rename from android/Gemfile.lock rename to Gemfile.lock diff --git a/Makefile b/Makefile index 2bdd38d..6c23210 100644 --- a/Makefile +++ b/Makefile @@ -210,7 +210,7 @@ android-upload: @echo "$(or $(TRACK),beta)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TRACK '$(TRACK)'. Must be: internal, alpha, beta, production"; exit 1) @echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1) @echo "Track: $(or $(TRACK),internal) | Status: $(or $(STATUS),draft)" - cd android && bundle exec fastlane deploy track:$(or $(TRACK),internal) status:$(or $(STATUS),draft) + bundle exec fastlane deploy track:$(or $(TRACK),internal) status:$(or $(STATUS),draft) .PHONY: android-deploy android-deploy: android-build-aab android-upload @@ -221,16 +221,16 @@ android-promote: @echo "$(or $(TO),production)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TO '$(TO)'. Must be: internal, alpha, beta, production"; exit 1) @echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1) @echo "Promote: $(or $(FROM),internal) -> $(or $(TO),production) | Status: $(or $(STATUS),draft)" - cd android && bundle exec fastlane promote from:$(or $(FROM),internal) to:$(or $(TO),production) status:$(or $(STATUS),draft) + bundle exec fastlane promote from:$(or $(FROM),internal) to:$(or $(TO),production) status:$(or $(STATUS),draft) .PHONY: ios-upload ios-upload: @echo "$(or $(DEST),testflight)" | grep -qE '^(testflight|appstore)$$' || (echo "Error: Invalid DEST '$(DEST)'. Must be: testflight, appstore"; exit 1) @echo "Destination: $(or $(DEST),testflight)" @if [ "$(or $(DEST),testflight)" = "appstore" ]; then \ - cd ios && bundle exec fastlane release; \ + bundle exec fastlane ios release; \ else \ - cd ios && bundle exec fastlane beta; \ + bundle exec fastlane ios beta; \ fi .PHONY: ios-deploy diff --git a/android/fastlane/Appfile b/android/fastlane/Appfile deleted file mode 100644 index b965411..0000000 --- a/android/fastlane/Appfile +++ /dev/null @@ -1,2 +0,0 @@ -json_key_file(ENV["GOOGLE_PLAY_KEY_FILE"]) -package_name("dev.casraf.pantry") diff --git a/ios/fastlane/Appfile b/fastlane/Appfile similarity index 57% rename from ios/fastlane/Appfile rename to fastlane/Appfile index b71abb9..5fa2f1b 100644 --- a/ios/fastlane/Appfile +++ b/fastlane/Appfile @@ -1,5 +1,9 @@ +# Android +json_key_file(ENV["GOOGLE_PLAY_KEY_FILE"]) +package_name("dev.casraf.pantry") + +# iOS app_identifier("dev.casraf.pantry") apple_id(ENV["APPLE_ID"]) - itc_team_id(ENV["ITC_TEAM_ID"]) team_id(ENV["APPLE_TEAM_ID"]) diff --git a/ios/fastlane/Deliverfile b/fastlane/Deliverfile similarity index 100% rename from ios/fastlane/Deliverfile rename to fastlane/Deliverfile diff --git a/android/fastlane/Fastfile b/fastlane/Fastfile similarity index 60% rename from android/fastlane/Fastfile rename to fastlane/Fastfile index 5c952ce..1dc7baf 100644 --- a/android/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,69 +1,62 @@ require "digest" require "json" +# -- Shared helpers -- + +def version_info + pubspec = File.read(File.expand_path("../pubspec.yaml", __dir__)) + version = pubspec.match(/^version:\s*(.+)$/)[1].strip + name, build = version.split("+") + { name: name, build: build } +end + +def version_name + v = version_info + "#{v[:build]} (#{v[:name]})" +end + +def changelog_notes + version = version_info[:name] + changelog_path = File.expand_path("../CHANGELOG.md", __dir__) + return "Release #{version}" unless File.exist?(changelog_path) + + changelog = File.read(changelog_path) + escaped = Regexp.escape(version) + pattern = /^## (?:\[#{escaped}\]|#{escaped}[\s(]).*?\n(.*?)(?=^## |\z)/m + match = changelog.match(pattern) + return "Release #{version}" unless match + + match[1].strip + .gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "") + .gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ") + .gsub(/^\*\s+/, "- ") + .gsub(/^### /, "") + .gsub(/\n{3,}/, "\n\n") + .strip + .then { |n| n.empty? ? "Release #{version}" : n } +end + +# -- Android -- + default_platform(:android) platform :android do - def version_info - pubspec = File.read(File.expand_path("../../pubspec.yaml", __dir__)) - version = pubspec.match(/^version:\s*(.+)$/)[1].strip - name, build = version.split("+") - { name: name, build: build } - end - - def version_name - v = version_info - "#{v[:build]} (#{v[:name]})" - end - # Google Play enforces a 500-char limit on release notes per language. PLAY_NOTES_MAX = 500 PLAY_NOTES_TRAILER = "\n\n… see full notes on GitHub." - def changelog_notes - version = version_info[:name] - changelog_path = File.expand_path("../../CHANGELOG.md", __dir__) - return "Release #{version}" unless File.exist?(changelog_path) - - changelog = File.read(changelog_path) - # Match the release heading (both `## [x.y.z]...` and `## x.y.z ...` forms), - # capture until the next `## ` heading (any form) or EOF. - escaped = Regexp.escape(version) - pattern = /^## (?:\[#{escaped}\]|#{escaped}[\s(]).*?\n(.*?)(?=^## |\z)/m - match = changelog.match(pattern) - return "Release #{version}" unless match - - notes = match[1].strip - .gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "") - .gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ") - .gsub(/^\*\s+/, "- ") - .gsub(/^### /, "") - .gsub(/\n{3,}/, "\n\n") - .strip - .then { |n| n.empty? ? "Release #{version}" : n } - - truncate_for_play(notes) - end - - # Truncate release notes to fit within the Play Store limit. If the - # notes exceed the limit, trim to a line boundary and append a trailer - # so the total stays under [PLAY_NOTES_MAX]. - def truncate_for_play(notes) + def play_changelog + notes = changelog_notes return notes if notes.length <= PLAY_NOTES_MAX budget = PLAY_NOTES_MAX - PLAY_NOTES_TRAILER.length truncated = notes[0, budget] - - # Cut at the last newline so we don't chop a bullet mid-word. last_newline = truncated.rindex("\n") truncated = truncated[0, last_newline] if last_newline && last_newline > budget / 2 - truncated.rstrip + PLAY_NOTES_TRAILER end # -- Image change detection -- - # We hash every file under metadata/android/*/images/ and compare to a - # cache file. If nothing changed, we skip image uploads entirely. IMAGE_HASH_CACHE = File.expand_path(".image_hashes.json", __dir__) @@ -95,18 +88,16 @@ platform :android do desc "Upload AAB to Google Play" lane :deploy do |options| - # Write release notes to the metadata tree so `supply` picks it up - # keyed by the current versionCode. version_code = version_info[:build] changelog_dir = File.expand_path("metadata/android/en-US/changelogs", __dir__) FileUtils.mkdir_p(changelog_dir) - File.write(File.join(changelog_dir, "#{version_code}.txt"), changelog_notes) + File.write(File.join(changelog_dir, "#{version_code}.txt"), play_changelog) changed = images_changed? UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.") upload_to_play_store( - aab: File.expand_path("../../build/app/outputs/bundle/release/app-release.aab", __dir__), + aab: File.expand_path("../build/app/outputs/bundle/release/app-release.aab", __dir__), track: options[:track] || "internal", release_status: options[:status] || "draft", version_name: version_name, @@ -154,3 +145,44 @@ platform :android do ) end end + +# -- iOS -- + +platform :ios do + def api_key + key_id = ENV.fetch("APP_STORE_API_KEY") + app_store_connect_api_key( + key_id: key_id, + issuer_id: ENV.fetch("APP_STORE_ISSUER_ID"), + key_filepath: File.join(ENV.fetch("APP_STORE_KEY_PATH"), "AuthKey_#{key_id}.p8"), + ) + end + + def find_ipa + ipa_path = Dir[File.expand_path("../build/ios/ipa/*.ipa", __dir__)].first + UI.user_error!("No IPA found in build/ios/ipa/. Run 'make ios-build' first.") unless ipa_path + ipa_path + end + + desc "Upload to TestFlight" + lane :beta do + upload_to_testflight( + api_key: api_key, + ipa: find_ipa, + changelog: changelog_notes, + skip_waiting_for_build_processing: true, + ) + end + + desc "Upload to App Store" + lane :release do + deliver( + api_key: api_key, + ipa: find_ipa, + skip_metadata: true, + skip_screenshots: true, + submit_for_review: false, + release_notes: { "en-US" => changelog_notes }, + ) + end +end diff --git a/android/fastlane/README.md b/fastlane/README.md similarity index 100% rename from android/fastlane/README.md rename to fastlane/README.md diff --git a/android/fastlane/metadata/android/en-US/changelogs/2.txt b/fastlane/metadata/android/en-US/changelogs/2.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/changelogs/2.txt rename to fastlane/metadata/android/en-US/changelogs/2.txt diff --git a/android/fastlane/metadata/android/en-US/changelogs/3.txt b/fastlane/metadata/android/en-US/changelogs/3.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/changelogs/3.txt rename to fastlane/metadata/android/en-US/changelogs/3.txt diff --git a/android/fastlane/metadata/android/en-US/changelogs/4.txt b/fastlane/metadata/android/en-US/changelogs/4.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/changelogs/4.txt rename to fastlane/metadata/android/en-US/changelogs/4.txt diff --git a/android/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/full_description.txt rename to fastlane/metadata/android/en-US/full_description.txt diff --git a/android/fastlane/metadata/android/en-US/images/featureGraphic.png b/fastlane/metadata/android/en-US/images/featureGraphic.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/featureGraphic.png rename to fastlane/metadata/android/en-US/images/featureGraphic.png diff --git a/android/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/icon.png rename to fastlane/metadata/android/en-US/images/icon.png diff --git a/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png rename to fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png rename to fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png rename to fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png rename to fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png rename to fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png rename to fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png b/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png rename to fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png b/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png rename to fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png diff --git a/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png b/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png similarity index 100% rename from android/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png rename to fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png diff --git a/android/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/short_description.txt rename to fastlane/metadata/android/en-US/short_description.txt diff --git a/android/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/title.txt rename to fastlane/metadata/android/en-US/title.txt diff --git a/android/fastlane/metadata/android/en-US/video.txt b/fastlane/metadata/android/en-US/video.txt similarity index 100% rename from android/fastlane/metadata/android/en-US/video.txt rename to fastlane/metadata/android/en-US/video.txt diff --git a/ios/Gemfile b/ios/Gemfile deleted file mode 100644 index 7a118b4..0000000 --- a/ios/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source "https://rubygems.org" - -gem "fastlane" diff --git a/ios/Gemfile.lock b/ios/Gemfile.lock deleted file mode 100644 index 35016d4..0000000 --- a/ios/Gemfile.lock +++ /dev/null @@ -1,338 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.8) - abbrev (0.1.2) - addressable (2.9.0) - public_suffix (>= 2.0.2, < 8.0) - artifactory (3.0.17) - atomos (0.1.3) - aws-eventstream (1.4.0) - aws-partitions (1.1237.0) - aws-sdk-core (3.244.0) - aws-eventstream (~> 1, >= 1.3.0) - aws-partitions (~> 1, >= 1.992.0) - aws-sigv4 (~> 1.9) - base64 - bigdecimal - jmespath (~> 1, >= 1.6.1) - logger - aws-sdk-kms (1.123.0) - aws-sdk-core (~> 3, >= 3.244.0) - aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.219.0) - aws-sdk-core (~> 3, >= 3.244.0) - 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.1.1) - claide (1.1.0) - colored (1.2) - colored2 (3.1.2) - commander (4.6.0) - highline (~> 2.0.0) - csv (3.3.5) - declarative (0.0.20) - digest-crc (0.7.0) - rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20240107) - dotenv (2.8.1) - emoji_regex (3.2.3) - excon (0.112.0) - faraday (1.10.5) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-cookie_jar (0.0.8) - faraday (>= 0.8.0) - http-cookie (>= 1.0.0) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.1) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-multipart (1.2.0) - multipart-post (~> 2.0) - faraday-net_http (1.0.2) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.4) - faraday_middleware (1.2.1) - faraday (~> 1.0) - fastimage (2.4.1) - fastlane (2.232.2) - CFPropertyList (>= 2.3, < 4.0.0) - abbrev (~> 0.1.2) - addressable (>= 2.8, < 3.0.0) - artifactory (~> 3.0) - aws-sdk-s3 (~> 1.197) - babosa (>= 1.0.3, < 2.0.0) - base64 (~> 0.2.0) - benchmark (>= 0.1.0) - bundler (>= 1.17.3, < 5.0.0) - colored (~> 1.2) - commander (~> 4.6) - csv (~> 3.3) - dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 4.0) - excon (>= 0.71.0, < 1.0.0) - faraday (~> 1.0) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 1.0) - fastimage (>= 2.1.0, < 3.0.0) - fastlane-sirp (>= 1.0.0) - 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.1.1) - google-cloud-storage (~> 1.31) - highline (~> 2.0) - http-cookie (~> 1.0.5) - json (< 3.0.0) - jwt (>= 2.1.0, < 3) - logger (>= 1.6, < 2.0) - mini_magick (>= 4.9.4, < 5.0.0) - multipart-post (>= 2.0.0, < 3.0.0) - mutex_m (~> 0.3.0) - 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) - simctl (~> 1.6.3) - terminal-notifier (>= 2.0.0, < 3.0.0) - terminal-table (~> 3) - tty-screen (>= 0.6.3, < 1.0.0) - tty-spinner (>= 0.8.0, < 1.0.0) - word_wrap (~> 1.0.0) - xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.4.1) - xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - fastlane-sirp (1.0.0) - sysrandom (~> 1.0) - gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.98.0) - google-apis-core (>= 0.15.0, < 2.a) - google-apis-core (0.18.0) - addressable (~> 2.5, >= 2.5.1) - googleauth (~> 1.9) - httpclient (>= 2.8.3, < 3.a) - mini_mime (~> 1.0) - mutex_m - representable (~> 3.0) - retriable (>= 2.0, < 4.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.61.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 (2.1.1) - faraday (>= 1.0, < 3.a) - google-cloud-errors (1.6.0) - google-cloud-storage (1.59.0) - addressable (~> 2.8) - digest-crc (~> 0.4) - google-apis-core (>= 0.18, < 2) - google-apis-iamcredentials_v1 (~> 0.18) - google-apis-storage_v1 (>= 0.42) - google-cloud-core (~> 1.6) - googleauth (~> 1.9) - mini_mime (~> 1.0) - 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) - signet (>= 0.16, < 2.a) - highline (2.0.3) - http-cookie (1.0.8) - domain_name (~> 0.5) - httpclient (2.9.0) - mutex_m - jmespath (1.6.2) - json (2.19.3) - jwt (2.10.2) - base64 - logger (1.7.0) - mini_magick (4.13.2) - mini_mime (1.1.5) - multi_json (1.19.1) - multipart-post (2.4.1) - mutex_m (0.3.0) - nanaimo (0.4.0) - naturally (2.3.0) - nkf (0.2.0) - optparse (0.8.1) - os (1.1.4) - ostruct (0.6.3) - plist (3.7.2) - public_suffix (7.0.5) - rake (13.3.1) - representable (3.2.0) - declarative (< 0.1.0) - trailblazer-option (>= 0.1.1, < 0.2.0) - uber (< 0.2.0) - retriable (3.4.1) - rexml (3.4.4) - rouge (3.28.0) - ruby2_keywords (0.0.5) - rubyzip (2.4.1) - security (0.1.5) - signet (0.21.0) - addressable (~> 2.8) - faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 4.0) - multi_json (~> 1.10) - simctl (1.6.10) - CFPropertyList - naturally - sysrandom (1.0.5) - terminal-notifier (2.0.0) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - trailblazer-option (0.1.2) - tty-cursor (0.7.1) - tty-screen (0.8.2) - tty-spinner (0.9.3) - tty-cursor (~> 0.7) - uber (0.1.0) - unicode-display_width (2.6.0) - word_wrap (1.0.0) - xcodeproj (1.27.0) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.4.0) - rexml (>= 3.3.6, < 4.0) - xcpretty (0.4.1) - rouge (~> 3.28.0) - xcpretty-travis-formatter (1.0.1) - xcpretty (~> 0.2, >= 0.0.7) - -PLATFORMS - arm64-darwin-24 - ruby - -DEPENDENCIES - fastlane - -CHECKSUMS - CFPropertyList (3.0.8) sha256=2c99d0d980536d3d7ab252f7bd59ac8be50fbdd1ff487c98c949bb66bb114261 - abbrev (0.1.2) sha256=ad1b4eaaaed4cb722d5684d63949e4bde1d34f2a95e20db93aecfe7cbac74242 - addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af - artifactory (3.0.17) sha256=3023d5c964c31674090d655a516f38ca75665c15084140c08b7f2841131af263 - atomos (0.1.3) sha256=7d43b22f2454a36bace5532d30785b06de3711399cb1c6bf932573eda536789f - aws-eventstream (1.4.0) sha256=116bf85c436200d1060811e6f5d2d40c88f65448f2125bc77ffce5121e6e183b - aws-partitions (1.1237.0) sha256=9b82f529b69ad83a8e4c5e123038924ed5e8f59bd6064a293ef20efc63364841 - aws-sdk-core (3.244.0) sha256=3e458c078b0c5bdee95bc370c3a483374b3224cf730c1f9f0faf849a5d9a18ea - aws-sdk-kms (1.123.0) sha256=d405f37e82f8fa32045ca8980be266c0b45b37aaf2012afe0254321a1e811f20 - aws-sdk-s3 (1.219.0) sha256=6a755d7377978525758b3c29185ca6a10128ce2b07555ca37c4549de10c2f1c7 - aws-sigv4 (1.12.1) sha256=6973ff95cb0fd0dc58ba26e90e9510a2219525d07620c8babeb70ef831826c00 - babosa (1.0.4) sha256=18dea450f595462ed7cb80595abd76b2e535db8c91b350f6c4b3d73986c5bc99 - base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507 - benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c - bigdecimal (4.1.1) sha256=1c09efab961da45203c8316b0cdaec0ff391dfadb952dd459584b63ebf8054ca - claide (1.1.0) sha256=6d3c5c089dde904d96aa30e73306d0d4bd444b1accb9b3125ce14a3c0183f82e - colored (1.2) sha256=9d82b47ac589ce7f6cab64b1f194a2009e9fd00c326a5357321f44afab2c1d2c - colored2 (3.1.2) sha256=b13c2bd7eeae2cf7356a62501d398e72fde78780bd26aec6a979578293c28b4a - commander (4.6.0) sha256=7d1ddc3fccae60cc906b4131b916107e2ef0108858f485fdda30610c0f2913d9 - csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f - declarative (0.0.20) sha256=8021dd6cb17ab2b61233c56903d3f5a259c5cf43c80ff332d447d395b17d9ff9 - digest-crc (0.7.0) sha256=64adc23a26a241044cbe6732477ca1b3c281d79e2240bcff275a37a5a0d78c07 - domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - dotenv (2.8.1) sha256=c5944793349ae03c432e1780a2ca929d60b88c7d14d52d630db0508c3a8a17d8 - emoji_regex (3.2.3) sha256=ecd8be856b7691406c6bf3bb3a5e55d6ed683ffab98b4aa531bb90e1ddcc564b - excon (0.112.0) sha256=daf9ac3a4c2fc9aa48383a33da77ecb44fa395111e973084d5c52f6f214ae0f0 - faraday (1.10.5) sha256=b144f1d2b045652fa820b5f532723e1643cc28b93dae911d784e5c5f88e8f6ed - faraday-cookie_jar (0.0.8) sha256=0140605823f8cc63c7028fccee486aaed8e54835c360cffc1f7c8c07c4299dbb - faraday-em_http (1.0.0) sha256=7a3d4c7079789121054f57e08cd4ef7e40ad1549b63101f38c7093a9d6c59689 - faraday-em_synchrony (1.0.1) sha256=bf3ce45dcf543088d319ab051f80985ea6d294930635b7a0b966563179f81750 - faraday-excon (1.1.0) sha256=b055c842376734d7f74350fe8611542ae2000c5387348d9ba9708109d6e40940 - faraday-httpclient (1.0.1) sha256=4c8ff1f0973ff835be8d043ef16aaf54f47f25b7578f6d916deee8399a04d33b - faraday-multipart (1.2.0) sha256=7d89a949693714176f612323ca13746a2ded204031a6ba528adee788694ef757 - faraday-net_http (1.0.2) sha256=63992efea42c925a20818cf3c0830947948541fdcf345842755510d266e4c682 - faraday-net_http_persistent (1.2.0) sha256=0b0cbc8f03dab943c3e1cc58d8b7beb142d9df068b39c718cd83e39260348335 - faraday-patron (1.0.0) sha256=dc2cd7b340bb3cc8e36bcb9e6e7eff43d134b6d526d5f3429c7a7680ddd38fa7 - faraday-rack (1.0.0) sha256=ef60ec969a2bb95b8dbf24400155aee64a00fc8ba6c6a4d3968562bcc92328c0 - faraday-retry (1.0.4) sha256=dc659233777fabf96c69c2ffe56c0a5d2c102af90321a42cc6c90157bcd716aa - faraday_middleware (1.2.1) sha256=d45b78c8ee864c4783fbc276f845243d4a7918a67301c052647bacabec0529e9 - fastimage (2.4.1) sha256=c64bebd46b6fd8943ab70c1e6e85ff728f970f2e48f92ecd249b6bc3a540ad20 - fastlane (2.232.2) sha256=978689f60f0fc3d54699de86ef12be4eda9f5b52217c1798965257c390d2b112 - fastlane-sirp (1.0.0) sha256=66478f25bcd039ec02ccf65625373fca29646fa73d655eb533c915f106c5e641 - gh_inspector (1.1.3) sha256=04cca7171b87164e053aa43147971d3b7f500fcb58177698886b48a9fc4a1939 - google-apis-androidpublisher_v3 (0.98.0) sha256=094fb952419c1131c16c4dfa66e0c96e6a2fa33adbe266f614b84b22cbc8c5cb - google-apis-core (0.18.0) sha256=96b057816feeeab448139ed5b5c78eab7fc2a9d8958f0fbc8217dedffad054ee - google-apis-iamcredentials_v1 (0.26.0) sha256=3ff70a10a1d6cddf2554e95b7c5df2c26afdeaeb64100048a355194da19e48a3 - google-apis-playcustomapp_v1 (0.17.0) sha256=d5bc90b705f3f862bab4998086449b0abe704ee1685a84821daa90ca7fa95a78 - google-apis-storage_v1 (0.61.0) sha256=b330e599b58e6a01533c189525398d6dbdbaf101ffb0c60145940b57e1c982e8 - google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf - google-cloud-env (2.1.1) sha256=cf4bb8c7d517ee1ea692baedf06e0b56ce68007549d8d5a66481aa9f97f46999 - google-cloud-errors (1.6.0) sha256=1da8476dd706ad04b9d32e3c4b90d07d3463b37d6407cb56d41342ea7647d0a1 - google-cloud-storage (1.59.0) sha256=b8c9a5661d775d65ccb279bb1d6be07fd8152576eb0146c2026bd023c4b186b9 - googleauth (1.11.2) sha256=7e6bacaeed7aea3dd66dcea985266839816af6633e9f5983c3c2e0e40a44731e - highline (2.0.3) sha256=2ddd5c127d4692721486f91737307236fe005352d12a4202e26c48614f719479 - http-cookie (1.0.8) sha256=b14fe0445cf24bf9ae098633e9b8d42e4c07c3c1f700672b09fbfe32ffd41aa6 - httpclient (2.9.0) sha256=4b645958e494b2f86c2f8a2f304c959baa273a310e77a2931ddb986d83e498c8 - jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1 - json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646 - jwt (2.10.2) sha256=31e1ee46f7359883d5e622446969fe9c118c3da87a0b1dca765ce269c3a0c4f4 - logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 - mini_magick (4.13.2) sha256=71d6258e0e8a3d04a9a0a09784d5d857b403a198a51dd4f882510435eb95ddd9 - mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef - multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 - multipart-post (2.4.1) sha256=9872d03a8e552020ca096adadbf5e3cb1cd1cdd6acd3c161136b8a5737cdb4a8 - mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 - nanaimo (0.4.0) sha256=faf069551bab17f15169c1f74a1c73c220657e71b6e900919897a10d991d0723 - naturally (2.3.0) sha256=459923cf76c2e6613048301742363200c3c7e4904c324097d54a67401e179e01 - nkf (0.2.0) sha256=fbc151bda025451f627fafdfcb3f4f13d0b22ae11f58c6d3a2939c76c5f5f126 - optparse (0.8.1) sha256=42bea10d53907ccff4f080a69991441d611fbf8733b60ed1ce9ee365ce03bd1a - os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f - ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 - plist (3.7.2) sha256=d37a4527cc1116064393df4b40e1dbbc94c65fa9ca2eec52edf9a13616718a42 - public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 - rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c - representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace - retriable (3.4.1) sha256=fb3f114b7d492121c158c01f3d5152b5a615c5b70d5877d0bc08c7ec3725c3bc - rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 - rouge (3.28.0) sha256=0d6de482c7624000d92697772ab14e48dca35629f8ddf3f4b21c99183fd70e20 - ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef - rubyzip (2.4.1) sha256=8577c88edc1fde8935eb91064c5cb1aef9ad5494b940cf19c775ee833e075615 - security (0.1.5) sha256=3a977a0eca7706e804c96db0dd9619e0a94969fe3aac9680fcfc2bf9b8a833b7 - signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b - simctl (1.6.10) sha256=b99077f4d13ad81eace9f86bf5ba4df1b0b893a4d1b368bd3ed59b5b27f9236b - sysrandom (1.0.5) sha256=5ac1ac3c2ec64ef76ac91018059f541b7e8f437fbda1ccddb4f2c56a9ccf1e75 - terminal-notifier (2.0.0) sha256=7a0d2b2212ab9835c07f4b2e22a94cff64149dba1eed203c04835f7991078cea - terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91 - trailblazer-option (0.1.2) sha256=20e4f12ea4e1f718c8007e7944ca21a329eee4eed9e0fa5dde6e8ad8ac4344a3 - tty-cursor (0.7.1) sha256=79534185e6a777888d88628b14b6a1fdf5154a603f285f80b1753e1908e0bf48 - tty-screen (0.8.2) sha256=c090652115beae764336c28802d633f204fb84da93c6a968aa5d8e319e819b50 - tty-spinner (0.9.3) sha256=0e036f047b4ffb61f2aa45f5a770ec00b4d04130531558a94bfc5b192b570542 - uber (0.1.0) sha256=5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc - unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a - word_wrap (1.0.0) sha256=f556d4224c812e371000f12a6ee8102e0daa724a314c3f246afaad76d82accc7 - xcodeproj (1.27.0) sha256=8cc7a73b4505c227deab044dce118ede787041c702bc47636856a2e566f854d3 - xcpretty (0.4.1) sha256=b14c50e721f6589ee3d6f5353e2c2cfcd8541fa1ea16d6c602807dd7327f3892 - xcpretty-travis-formatter (1.0.1) sha256=aacc332f17cb7b2cba222994e2adc74223db88724fe76341483ad3098e232f93 - -BUNDLED WITH - 4.0.7 diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile deleted file mode 100644 index ec34a6c..0000000 --- a/ios/fastlane/Fastfile +++ /dev/null @@ -1,63 +0,0 @@ -default_platform(:ios) - -platform :ios do - def api_key - key_id = ENV.fetch("APP_STORE_API_KEY") - app_store_connect_api_key( - key_id: key_id, - issuer_id: ENV.fetch("APP_STORE_ISSUER_ID"), - key_filepath: File.join(ENV.fetch("APP_STORE_KEY_PATH"), "AuthKey_#{key_id}.p8"), - ) - end - - def find_ipa - ipa_path = Dir[File.expand_path("../../build/ios/ipa/*.ipa", __dir__)].first - UI.user_error!("No IPA found in build/ios/ipa/. Run 'make ios-build' first.") unless ipa_path - ipa_path - end - - def changelog_notes - root = File.expand_path("../..", __dir__) - pubspec = File.read(File.join(root, "pubspec.yaml")) - version = pubspec.match(/^version:\s*(.+)$/)[1].strip.split("+").first - - changelog_path = File.join(root, "CHANGELOG.md") - return "Release #{version}" unless File.exist?(changelog_path) - - changelog = File.read(changelog_path) - pattern = /^## \[#{Regexp.escape(version)}\].*?\n(.*?)(?=^## \[|\z)/m - match = changelog.match(pattern) - return "Release #{version}" unless match - - match[1].strip - .gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "") - .gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ") - .gsub(/^\*\s+/, "- ") - .gsub(/^### /, "") - .gsub(/\n{3,}/, "\n\n") - .strip - .then { |n| n.empty? ? "Release #{version}" : n } - end - - desc "Upload to TestFlight" - lane :beta do - upload_to_testflight( - api_key: api_key, - ipa: find_ipa, - changelog: changelog_notes, - skip_waiting_for_build_processing: true, - ) - end - - desc "Upload to App Store" - lane :release do - deliver( - api_key: api_key, - ipa: find_ipa, - skip_metadata: true, - skip_screenshots: true, - submit_for_review: false, - release_notes: { "en-US" => changelog_notes }, - ) - end -end