iOS Build and Deploy #12
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#inspired by: | |
#https://canopas.com/automate-flutter-ios-app-deployment-with-github-actions-and-codemagic-cli-4d063ea6ef08 | |
#https://blog.okaryo.studio/en/20240911-flutter-ios-firebase-app-distribution-github-actions-not-auto-signing/ | |
#to create certificate: https://mzansibytes.com/2021/08/28/create-apple-developer-certificates-on-windows/ | |
name: iOS Build and Deploy | |
on: | |
workflow_dispatch: | |
jobs: | |
ios_deployment: | |
runs-on: macos-latest | |
steps: | |
# Step 1: Checkout Code | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
# Step 2: Set up Flutter SDK | |
- name: Set up Flutter SDK | |
uses: flutter-actions/setup-flutter@v3 | |
with: | |
channel: stable | |
version: 3.27.1 # Keep this up to date with flutter --version | |
# Step 3: Install Dependencies | |
- name: Install Dependencies | |
run: | | |
flutter clean | |
flutter pub get | |
flutter analyze --no-fatal-infos --no-fatal-warnings | |
# Step 4: Initialize Keychain | |
- name: Initialize Keychain | |
env: | |
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
run: | | |
security create-keychain -p "$KEYCHAIN_PASSWORD" $RUNNER_TEMP/app-signing.keychain-db | |
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $RUNNER_TEMP/app-signing.keychain-db | |
security list-keychain -d user -s $RUNNER_TEMP/app-signing.keychain-db | |
# Step 5: Configure Provisioning Profile | |
- name: Configure Provisioning Profile | |
env: | |
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }} | |
run: | | |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | |
echo "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/PiusApp_Distribution_24_12.mobileprovision | |
# Step 6: Configure Distribution Certificate | |
- name: Configure Distribution Certificate | |
env: | |
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} | |
P12_PASSWORD: ${{ secrets.P12_PASSWORD }} | |
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
run: | | |
echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode > /tmp/certificate.p12 | |
security import /tmp/certificate.p12 -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $RUNNER_TEMP/app-signing.keychain-db | |
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $RUNNER_TEMP/app-signing.keychain-db | |
# Step 7: Parse Build Number and Name from pubspec.yaml | |
- name: Parse Build Number and Name | |
id: version | |
run: | | |
VERSION_LINE=$(grep '^version:' pubspec.yaml) | |
VERSION=$(echo $VERSION_LINE | cut -d' ' -f2 | cut -d'+' -f1) | |
BUILD_NUMBER=$(echo $VERSION_LINE | cut -d'+' -f2) | |
echo "VERSION=$VERSION" >> $GITHUB_ENV | |
echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV | |
# Step 8: Generate ExportOptions.plist from Template | |
- name: Generate ExportOptions.plist | |
env: | |
EXPORT_METHOD: "app-store" | |
EXPORT_DESTINATION: "export" | |
BUNDLE_ID: "de.equirinya.piusapp" # Change this when adapting to another app | |
PROVISIONING_PROFILE: "PiusApp Distribution 24_12" | |
TEAM_ID: ${{ secrets.TEAM_ID }} | |
run: | | |
envsubst < ios/Runner/ExportOptions-Template.plist > ios/Runner/ExportOptions.plist | |
# Step 9: Build IPA | |
- name: Build IPA | |
run: | | |
flutter build ipa \ | |
--release \ | |
--build-number=$BUILD_NUMBER \ | |
--build-name=$VERSION \ | |
--export-options-plist=ios/Runner/ExportOptions.plist | |
# Step 10: Create API Key File | |
- name: Create API Key File | |
env: | |
APPSTORE_API_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }} | |
run: | | |
mkdir -p ~/.private_keys | |
echo "$APPSTORE_API_KEY" > ~/.private_keys/AuthKey_${{ secrets.APPSTORE_API_KEY_ID }}.p8 | |
chmod 600 ~/.private_keys/AuthKey_${{ secrets.APPSTORE_API_KEY_ID }}.p8 | |
# Step 11: Upload IPA to App Store Connect | |
- name: Upload to App Store Connect | |
env: | |
API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }} | |
API_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }} | |
run: | | |
APP_FILE=$(find $(pwd) -name "*.ipa") | |
xcrun altool --upload-app -f "$APP_FILE" -t ios --apiKey "$API_KEY_ID" --apiIssuer "$API_ISSUER_ID" | |
# Step 12: Upload IPA to GitHub Release | |
- name: Create Release | |
id: create_release | |
uses: actions/create-release@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: v$VERSION | |
release_name: "Release v$VERSION" | |
draft: true | |
prerelease: false | |
- name: Upload IPA to Release | |
uses: actions/upload-release-asset@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
upload_url: ${{ steps.create_release.outputs.upload_url }} | |
asset_path: $(find $(pwd) -name "*.ipa") | |
asset_name: PiusApp-v$VERSION.ipa | |
asset_content_type: application/octet-stream | |
# Step 13: Cleanup Keychain and Profiles | |
- name: Cleanup | |
if: ${{ always() }} | |
run: | | |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db | |
rm -rf ~/Library/MobileDevice/Provisioning\ Profiles | |
rm -rf ~/.private_keys |