From dfd2b534e6caa20ab5ac5f20623743162a372b87 Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Mon, 2 Jun 2025 21:15:57 +0200 Subject: [PATCH] Add iOS build workflow action (#887) --- .../build-browser-extension/action.yml | 7 +- .github/actions/build-ios-app/action.yml | 118 ++++++++++++++++++ .github/workflows/mobile-app-build.yml | 84 +++---------- .../ios/AliasVault.xcodeproj/project.pbxproj | 2 - 4 files changed, 138 insertions(+), 73 deletions(-) create mode 100644 .github/actions/build-ios-app/action.yml diff --git a/.github/actions/build-browser-extension/action.yml b/.github/actions/build-browser-extension/action.yml index 65fc694aa..b2c52f864 100644 --- a/.github/actions/build-browser-extension/action.yml +++ b/.github/actions/build-browser-extension/action.yml @@ -53,7 +53,7 @@ runs: - name: Unzip extension run: | mkdir -p dist/${{ inputs.browser }}-unpacked - unzip dist/aliasvault-browser-extension-${VERSION}-${{ inputs.browser }}.zip -d dist/${{ inputs.browser }}-unpacked + unzip dist/aliasvault-browser-extension-${{ env.VERSION }}-${{ inputs.browser }}.zip -d dist/${{ inputs.browser }}-unpacked shell: bash working-directory: apps/browser-extension @@ -81,9 +81,10 @@ runs: - name: Rename zip files run: | mv apps/browser-extension/dist/aliasvault-browser-extension-${{ env.VERSION }}-${{ inputs.browser }}.zip apps/browser-extension/dist/aliasvault-${{ env.VERSION }}-${{ inputs.browser }}.zip - mv apps/browser-extension/dist/aliasvault-browser-extension-${{ env.VERSION }}-sources.zip apps/browser-extension/dist/aliasvault-${{ env.VERSION }}-browser-extension-sources.zip + if [ -f apps/browser-extension/dist/aliasvault-browser-extension-${{ env.VERSION }}-sources.zip ]; then + mv apps/browser-extension/dist/aliasvault-browser-extension-${{ env.VERSION }}-sources.zip apps/browser-extension/dist/aliasvault-${{ env.VERSION }}-browser-extension-sources.zip + fi shell: bash - working-directory: apps/browser-extension - name: Upload to GitHub Release if: ${{ inputs.upload_to_release == 'true' }} diff --git a/.github/actions/build-ios-app/action.yml b/.github/actions/build-ios-app/action.yml new file mode 100644 index 000000000..f1468fde8 --- /dev/null +++ b/.github/actions/build-ios-app/action.yml @@ -0,0 +1,118 @@ +name: "Build iOS App" +description: "Builds iOS App, optionally signs and uploads to App Store Connect" +inputs: + run_tests: + description: "Whether to run iOS unit tests" + required: false + default: "false" + signed: + description: "Whether to sign the iOS build" + required: false + default: "false" + upload_to_app_store_connect: + description: "Whether to upload the iOS App to App Store Connect" + required: false + default: "false" + +runs: + using: "composite" + steps: + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: apps/mobile-app/package-lock.json + + - name: Install dependencies + run: npm ci + shell: bash + working-directory: apps/mobile-app + + - name: Extract version + run: | + VERSION=$(node -p "require('./app.json').expo.version") + echo "VERSION=$VERSION" >> $GITHUB_ENV + shell: bash + working-directory: apps/mobile-app + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2' + bundler-cache: true + + - name: Install Fastlane + run: gem install fastlane + shell: bash + + - name: Install CocoaPods + run: | + sudo gem install cocoapods + shell: bash + + - name: Create ASC private key file + if: ${{ inputs.signed == 'true' }} + run: | + mkdir -p $RUNNER_TEMP/asc + echo "${{ env.ASC_PRIVATE_KEY_BASE64 }}" | base64 --decode > $RUNNER_TEMP/asc/AuthKey.p8 + shell: bash + + - name: Install CocoaPods + run: | + cd ios + pod install + shell: bash + working-directory: apps/mobile-app + + - name: Build iOS IPA + if: ${{ inputs.signed == 'true' }} + env: + IDEFileSystemSynchronizedGroupsAreEnabled: NO + XCODE_WORKSPACE: AliasVault.xcworkspace + XCODE_SCHEME: AliasVault + XCODE_CONFIGURATION: Release + XCODE_ARCHIVE_PATH: AliasVault.xcarchive + XCODE_EXPORT_PATH: ./build + XCODE_SKIP_FILESYSTEM_SYNC: true + run: | + cd ios + xcodebuild clean -workspace "$XCODE_WORKSPACE" \ + -scheme "$XCODE_SCHEME" \ + -configuration "$XCODE_CONFIGURATION" + xcodebuild -workspace "$XCODE_WORKSPACE" \ + -scheme "$XCODE_SCHEME" \ + -configuration "$XCODE_CONFIGURATION" \ + -archivePath "$XCODE_ARCHIVE_PATH" \ + -destination 'generic/platform=iOS' \ + -allowProvisioningUpdates \ + -authenticationKeyPath $RUNNER_TEMP/asc/AuthKey.p8 \ + -authenticationKeyID ${{ env.ASC_KEY_ID }} \ + -authenticationKeyIssuerID ${{ env.ASC_ISSUER_ID }} \ + archive + xcodebuild -exportArchive \ + -archivePath "$XCODE_ARCHIVE_PATH" \ + -exportOptionsPlist ../exportOptions.plist \ + -exportPath "$XCODE_EXPORT_PATH" + shell: bash + working-directory: apps/mobile-app + + - name: Upload IPA as artifact + if: ${{ inputs.signed == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: aliasvault-${{ env.VERSION }}-ios.ipa + path: apps/mobile-app/ios/build/AliasVault.ipa + retention-days: 14 + + - name: Upload to App Store Connect via Fastlane + if: ${{ inputs.upload_to_app_store_connect == 'true' }} + env: + ASC_KEY_ID: ${{ env.ASC_KEY_ID }} + ASC_ISSUER_ID: ${{ env.ASC_ISSUER_ID }} + run: | + cd apps/mobile-app/ios + fastlane pilot upload \ + --ipa "./build/AliasVault.ipa" \ + --api_key_path "$RUNNER_TEMP/asc/AuthKey.p8" \ + --skip_waiting_for_build_processing true + shell: bash diff --git a/.github/workflows/mobile-app-build.yml b/.github/workflows/mobile-app-build.yml index 65943a8a6..9d4f44ff0 100644 --- a/.github/workflows/mobile-app-build.yml +++ b/.github/workflows/mobile-app-build.yml @@ -17,6 +17,11 @@ on: required: true type: boolean default: false + upload_to_app_store_connect: + description: 'Upload iOS IPA to App Store Connect' + required: true + type: boolean + default: false concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -153,75 +158,18 @@ jobs: needs: setup if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_ios_signed == 'true' runs-on: macos-15 - defaults: - run: - working-directory: apps/mobile-app steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Build iOS App + uses: ./.github/actions/build-ios-app with: - node-version: '20' - cache: 'npm' - cache-dependency-path: apps/mobile-app/package-lock.json - - - name: Install dependencies - run: npm ci - - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2' - bundler-cache: true - - - name: Install Fastlane - run: gem install fastlane - - - name: Create ASC private key file - run: | - mkdir -p $RUNNER_TEMP/asc - echo "${{ secrets.ASC_PRIVATE_KEY_BASE64 }}" | base64 --decode > $RUNNER_TEMP/asc/AuthKey.p8 - - - name: Install CocoaPods - run: | - cd ios - pod install - - - name: Build iOS IPA + signed: true + upload_to_app_store_connect: ${{ github.event.inputs.upload_to_app_store_connect }} env: - IDEFileSystemSynchronizedGroupsAreEnabled: NO - XCODE_WORKSPACE: AliasVault.xcworkspace - XCODE_SCHEME: AliasVault - XCODE_CONFIGURATION: Release - XCODE_ARCHIVE_PATH: AliasVault.xcarchive - XCODE_EXPORT_PATH: ./build - XCODE_SKIP_FILESYSTEM_SYNC: true - run: | - cd ios - xcodebuild clean -workspace "$XCODE_WORKSPACE" \ - -scheme "$XCODE_SCHEME" \ - -configuration "$XCODE_CONFIGURATION" - xcodebuild -workspace "$XCODE_WORKSPACE" \ - -scheme "$XCODE_SCHEME" \ - -configuration "$XCODE_CONFIGURATION" \ - -archivePath "$XCODE_ARCHIVE_PATH" \ - -destination 'generic/platform=iOS' \ - -allowProvisioningUpdates \ - -authenticationKeyPath $RUNNER_TEMP/asc/AuthKey.p8 \ - -authenticationKeyID ${{ secrets.ASC_KEY_ID }} \ - -authenticationKeyIssuerID ${{ secrets.ASC_ISSUER_ID }} \ - archive - xcodebuild -exportArchive \ - -archivePath "$XCODE_ARCHIVE_PATH" \ - -exportOptionsPlist ../exportOptions.plist \ - -exportPath "$XCODE_EXPORT_PATH" - - - name: Upload IPA - uses: actions/upload-artifact@v4 - with: - name: signed-ipa - path: apps/mobile-app/ios/build/AliasVault.ipa - retention-days: 14 - - + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ASC_PRIVATE_KEY_BASE64: ${{ secrets.ASC_PRIVATE_KEY_BASE64 }} + ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }} + ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} + ASC_TEAM_ID: ${{ secrets.ASC_TEAM_ID }} \ No newline at end of file diff --git a/apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj b/apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj index 06642d207..98561e02b 100644 --- a/apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj +++ b/apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj @@ -1128,7 +1128,6 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -1191,7 +1190,6 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES;