name: iOS Release on: push: tags: - "ios-v*" concurrency: group: ios-macos-runner cancel-in-progress: false jobs: # ── archive & release to TestFlight ────────────────────────────────────── # Triggered only on ios-v* tags (e.g. ios-v1.0.0). # Required secrets: # APPLE_CERTIFICATE_BASE64 - Distribution certificate (.p12) base64-encoded # APPLE_CERTIFICATE_PASSWORD - Password for the .p12 file # APPLE_PROVISIONING_PROFILE_BASE64 - App Store distribution profile base64-encoded # KEYCHAIN_PASSWORD - Temporary keychain password (any random string) # ASC_KEY_ID - App Store Connect API key ID # ASC_ISSUER_ID - App Store Connect issuer ID # ASC_PRIVATE_KEY - Contents of the .p8 private key file # APPLE_TEAM_ID - 10-character Apple Developer team ID (GHZXC6FVMU) release: name: Release to TestFlight runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Set up Ruby with rbenv run: | # Install rbenv and ruby-build if not already installed brew install rbenv ruby-build || true # Install Ruby 3.2.2 rbenv install 3.2.2 --skip-existing rbenv global 3.2.2 # Add rbenv to PATH for subsequent steps echo "$(rbenv root)/shims" >> $GITHUB_PATH # Verify Ruby version eval "$(rbenv init -)" ruby --version - name: Install dependencies working-directory: ios/LibNovel run: | eval "$(rbenv init -)" gem install bundler bundle install - name: Import signing certificate env: CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH echo "$CERTIFICATE_BASE64" | base64 --decode > $RUNNER_TEMP/cert.p12 security import $RUNNER_TEMP/cert.p12 \ -P "$CERTIFICATE_PASSWORD" \ -A -t cert -f pkcs12 \ -k $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH $(security list-keychains -d user | tr -d '"' | xargs) security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - name: Import provisioning profile env: PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }} run: | PP_PATH=$RUNNER_TEMP/profile.mobileprovision echo "$PROFILE_BASE64" | base64 --decode > $PP_PATH UUID=$(security cms -D -i "$PP_PATH" | plutil -extract UUID raw -) PROFILE_NAME=$(security cms -D -i "$PP_PATH" | plutil -extract Name raw -) mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles/$UUID.mobileprovision echo "Installed profile: $PROFILE_NAME (UUID: $UUID)" echo "PROFILE_NAME=$PROFILE_NAME" >> $GITHUB_ENV echo "PROFILE_UUID=$UUID" >> $GITHUB_ENV - name: Build and upload to TestFlight env: USER: runner LC_ALL: en_US.UTF-8 LANG: en_US.UTF-8 APPLE_KEY_ID: ${{ secrets.ASC_KEY_ID }} APPLE_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} APPLE_KEY_CONTENT: ${{ secrets.ASC_PRIVATE_KEY }} BUILD_NUMBER: ${{ gitea.run_number }} working-directory: ios/LibNovel run: | eval "$(rbenv init -)" echo "Using provisioning profile: $PROFILE_NAME (UUID: $PROFILE_UUID)" export PROVISIONING_PROFILE_NAME="$PROFILE_NAME" export PROVISIONING_PROFILE_UUID="$PROFILE_UUID" bundle exec fastlane beta - name: Cleanup keychain if: always() run: security delete-keychain $RUNNER_TEMP/app-signing.keychain-db