Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/build-mobile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,109 @@ jobs:
mobile/android/.gradle
mobile/.dart_tool
key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }}

build-sign-ios:
name: Build and sign iOS
needs: pre-job
permissions:
contents: read
# Run on main branch or workflow_dispatch
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true && github.ref == 'refs/heads/main' }}
runs-on: macos-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false

- name: Setup Flutter SDK
uses: subosito/flutter-action@v2
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
cache: true

- name: Install Flutter dependencies
working-directory: ./mobile
run: flutter pub get

- name: Generate translation files
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
working-directory: ./mobile

- name: Generate platform APIs
run: make pigeon
working-directory: ./mobile

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
working-directory: ./mobile/ios

- name: Install Fastlane
run: |
cd mobile/ios
gem install bundler
bundle install
Comment on lines +200 to +204
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there not a setup action for this? Or should we maybe do it via Mise instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the docs, this is how you are using installing fastlane https://docs.fastlane.tools/getting-started/ios/setup/

Maybe we test this first, then use mise later?


- name: Create API Key JSON
env:
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
API_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
working-directory: ./mobile/ios
run: |
mkdir -p ~/.appstoreconnect/private_keys
echo "$API_KEY_CONTENT" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
cat > api_key.json << EOF
{
"key_id": "${API_KEY_ID}",
"issuer_id": "${API_KEY_ISSUER_ID}",
"key": "$(cat ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8)",
"duration": 1200,
"in_house": false
}
EOF

- name: Import Certificate and Provisioning Profile
env:
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
working-directory: ./mobile/ios
run: |
echo "$IOS_CERTIFICATE_P12" | base64 --decode > certificate.p12
echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision

- name: Create keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
run: |
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -t 3600 -u build.keychain

- name: Build and deploy to TestFlight
env:
FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
KEYCHAIN_NAME: build.keychain
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
working-directory: ./mobile/ios
run: bundle exec fastlane release_ci

- name: Clean up keychain
if: always()
run: |
security delete-keychain build.keychain || true

- name: Upload IPA artifact
uses: actions/upload-artifact@v4
with:
name: ios-release-ipa
path: mobile/ios/Runner.ipa
1 change: 1 addition & 0 deletions mobile/ios/Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
source "https://rubygems.org"

gem "fastlane"
gem "cocoapods"
49 changes: 49 additions & 0 deletions mobile/ios/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,55 @@
default_platform(:ios)

platform :ios do
desc "iOS Release to TestFlight"
lane :release_ci do
# Setup CI environment
setup_ci

# Import certificate and provisioning profile
import_certificate(
certificate_path: "certificate.p12",
certificate_password: ENV["IOS_CERTIFICATE_PASSWORD"],
keychain_name: ENV["KEYCHAIN_NAME"],
keychain_password: ENV["KEYCHAIN_PASSWORD"]
)

# Install provisioning profile
install_provisioning_profile(path: "profile.mobileprovision")

# Configure code signing
update_code_signing_settings(
use_automatic_signing: false,
path: "./Runner.xcodeproj",
team_id: ENV["FASTLANE_TEAM_ID"],
profile_name: "app.alextran.immich AppStore"
)

# Increment build number
increment_build_number(
build_number: latest_testflight_build_number + 1,
xcodeproj: "./Runner.xcodeproj"
)

# Build the app
build_app(
scheme: "Runner",
workspace: "Runner.xcworkspace",
export_method: "app-store",
export_options: {
provisioningProfiles: {
"app.alextran.immich" => "app.alextran.immich AppStore"
}
}
)

# Upload to TestFlight
upload_to_testflight(
api_key_path: "api_key.json",
skip_waiting_for_build_processing: true
)
end

desc "iOS Release"
lane :release do
enable_automatic_code_signing(
Expand Down
Loading