Improve iOS mobile release versioning (#5994)

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo Hong 2026-06-21 12:25:25 -07:00 committed by GitHub
parent 2157a8ea5b
commit f6b82829f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 88 additions and 7 deletions

View File

@ -8,6 +8,16 @@ on:
tags:
- 'mobile-ios-v*'
workflow_dispatch:
inputs:
bump_patch_version:
description: 'Bump the iOS marketing version patch number before release'
required: false
default: false
type: boolean
release_version:
description: 'Optional exact iOS marketing version override, e.g. 0.0.15'
required: false
type: string
jobs:
ios-build:
@ -51,6 +61,17 @@ jobs:
bundler-cache: true
working-directory: mobile
- name: Resolve release version and build number
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
ASC_API_KEY_P8: ${{ secrets.ASC_API_KEY_P8 }}
MOBILE_IOS_RELEASE_VERSION: ${{ github.event.inputs.release_version }}
MOBILE_IOS_BUMP_PATCH_VERSION: ${{ github.event.inputs.bump_patch_version }}
FASTLANE_SKIP_UPDATE_CHECK: '1'
FASTLANE_HIDE_CHANGELOG: '1'
run: bundle exec fastlane ios prepare_release_version version:"$MOBILE_IOS_RELEASE_VERSION" bump_patch:"$MOBILE_IOS_BUMP_PATCH_VERSION"
- name: Expo prebuild
run: npx expo prebuild --platform ios --no-install

View File

@ -15,24 +15,84 @@
# manually against the imported cert — works with any team API key.
require "base64"
require "json"
default_platform(:ios)
APP_CONFIG_PATH = "app.json"
WORKSPACE = "ios/Orca.xcworkspace"
SCHEME = "Orca"
BUNDLE_ID = "com.stably.orca.mobile"
TESTFLIGHT_GROUPS = ["peeps"].freeze
def app_store_connect_api_key_from_env
app_store_connect_api_key(
key_id: ENV.fetch("ASC_KEY_ID"),
issuer_id: ENV.fetch("ASC_ISSUER_ID"),
key_content: ENV.fetch("ASC_API_KEY_P8"),
is_key_content_base64: true,
in_house: false,
)
end
def load_mobile_app_config
JSON.parse(File.read(APP_CONFIG_PATH))
end
def write_mobile_app_config(config)
File.write(APP_CONFIG_PATH, "#{JSON.pretty_generate(config)}\n")
end
def current_mobile_version(config)
config.fetch("expo").fetch("version")
end
def truthy_option?(value)
%w[1 true yes on].include?(value.to_s.strip.downcase)
end
def bump_patch_version(version)
match = version.match(/\A(\d+)\.(\d+)\.(\d+)\z/)
UI.user_error!("Cannot bump non-semver mobile version '#{version}'") unless match
"#{match[1]}.#{match[2]}.#{match[3].to_i + 1}"
end
def resolve_requested_version(options, config)
requested = options[:version].to_s.strip
return requested unless requested.empty?
current_version = current_mobile_version(config)
truthy_option?(options[:bump_patch]) ? bump_patch_version(current_version) : current_version
end
platform :ios do
desc "Resolve the iOS release version and next TestFlight build number"
lane :prepare_release_version do |options|
api_key = app_store_connect_api_key_from_env
config = load_mobile_app_config
version = resolve_requested_version(options, config)
latest_build_number = latest_testflight_build_number(
api_key: api_key,
app_identifier: BUNDLE_ID,
version: version,
initial_build_number: 0,
)
build_number = latest_build_number.to_i + 1
# Keep app.json authoritative because Expo prebuild copies these values into
# the native project and runtime manifest used by the About screen.
config.fetch("expo")["version"] = version
config.fetch("expo").fetch("ios")["buildNumber"] = build_number.to_s
write_mobile_app_config(config)
UI.message("Prepared Orca Mobile iOS #{version} (#{build_number})")
end
desc "Build, sign, upload, and share Orca Mobile on TestFlight"
lane :release do
api_key = app_store_connect_api_key(
key_id: ENV.fetch("ASC_KEY_ID"),
issuer_id: ENV.fetch("ASC_ISSUER_ID"),
key_content: ENV.fetch("ASC_API_KEY_P8"),
is_key_content_base64: true,
in_house: false,
)
api_key = app_store_connect_api_key_from_env
team_id = ENV.fetch("APPLE_TEAM_ID")