简体   繁体   中英

iOS build fails on GitHub Actions (without fastlane), but it works intermittently

I have slightly different approach for building iOS apps. Instead of putting a bunch of code in the .yaml file, I prefer to put most stuff in a shell script and have a simpler .yaml file... is there any problem in this approach?

My build gets stuck in the "Build app" step. The other steps work fine. Intermittently, like once every 15 times it just magically works, but most of the time it fails. It gets stuck and I can't see the log, until I cancel the job, but the log doesn't say anything useful. Running the scripts in my local machine works 100% of time. It seems to be something very particular to GitHub actions.

Is there any problem, limitation on using this approach (bash script) in GitHub actions? Why would this fail?

I am not using using fastlane. Here is my YAML file:

name: Build iOS

on:
push:
    branches:
    - master

jobs:
build:
    runs-on: macOS-latest
    steps:
    - uses: actions/checkout@v2

    - name: Switch XCode Version
        run: sudo xcode-select -s /Applications/Xcode_11.2.app

    - name: Get dependencies
        run: source .github/ios/build.sh && get_dependencies

    - name: Decrypt secrets
        run: source .github/ios/build.sh && decrypt_secrets ${{ secrets.SECRET_KEY }}
        env:
        SECRET_KEY: ${{ secrets.SECRET_KEY }}

    - name: Set up code signing
        run: source .github/ios/build.sh && setup_code_signing

    - name: Build app
        run: source .github/ios/build.sh && build_app

    - name: Upload artifacts
        run: source .github/ios/build.sh && upload_artifacts

and the script

#!/bin/bash

PROVISIONING_PROFILE="MyApp"
CODE_SIGN_IDENTITY="Apple Development: MyApp (XXXXXXXXXX)"
DOMAIN="MyApp.com"
PRODUCT_BUNDLE_IDENTIFIER="com.MyApp.app"

# Get dependencies
function get_dependencies()
{
    yarn
    cd ios
    pod install
    cd ..
}

function decrypt
{
    INPUT=$1
    OUTPUT="${1%.*}"
    openssl aes-256-cbc -salt -a -d -in $INPUT -out $OUTPUT -pass pass:$SECRET_KEY
}

# Decrypt secrets
function decrypt_secrets
{
    export SECRET_KEY=$1
    decrypt .github/ios/secrets/MyApp.mobileprovision.encrypted
    decrypt .github/ios/secrets/MyApp.p12.encrypted
    decrypt .github/ssh/id_rsa.encrypted
}

# Set up code signing
function setup_code_signing()
{
    mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles

    # provisioning
    cp .github/ios/secrets/MyApp.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$PROVISIONING_PROFILE.mobileprovision

    # keychain
    security create-keychain -p "MyApp" build.keychain
    security import ./.github/ios/secrets/MyApp.p12 -t agg -k ~/Library/Keychains/build.keychain -P "" -A

    security list-keychains -s ~/Library/Keychains/build.keychain
    security default-keychain -s ~/Library/Keychains/build.keychain
    security unlock-keychain -p "MyApp" ~/Library/Keychains/build.keychain

    security set-key-partition-list -S apple-tool:,apple: -s -k "MyApp" ~/Library/Keychains/build.keychain
}

# Build
function build_app()
{
    # dev environment
    echo "API_URL=https://backend.$DOMAIN/" > .env

    # build number
    BUILD_NUMBER=${GITHUB_RUN_NUMBER:-1}

    # ExportOptions.plist
    sed -e "s/__BUILD_NUMBER__/$BUILD_NUMBER/g" \
        -e "s/__PRODUCT_BUNDLE_IDENTIFIER__/$PRODUCT_BUNDLE_IDENTIFIER/g" \
        -e "s/__CODE_SIGN_IDENTITY__/$CODE_SIGN_IDENTITY/g" \
        .github/ios/ExportOptions.plist > ios/ExportOptions.plist

    cd ios

    set -e
    set -o pipefail

    # archive
    xcodebuild archive \
        -workspace MyApp.xcworkspace \
        -scheme MyApp \
        -sdk iphoneos13.2 \
        -configuration Release \
        -archivePath "$PWD/build/MyApp.xcarchive" \
        PRODUCT_BUNDLE_IDENTIFIER="$PRODUCT_BUNDLE_IDENTIFIER" \
        PROVISIONING_PROFILE="$PROVISIONING_PROFILE" \
        CODE_SIGN_IDENTITY="$CODE_SIGN_IDENTITY" \
        CURRENT_PROJECT_VERSION="$BUILD_NUMBER"

    # export
    xcodebuild \
        -exportArchive \
        -archivePath "$PWD/build/MyApp.xcarchive" \
        -exportOptionsPlist "$PWD/ExportOptions.plist" \
        -exportPath "$PWD/build"
}

# Upload artifacts
function upload_artifacts()
{
    chmod 600 .github/ssh/id_rsa
    BUILD_PATH="www/app/builds/$GITHUB_RUN_NUMBER"
    ssh -i .github/ssh/id_rsa -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' ubuntu@MyApp.dev "mkdir -p $BUILD_PATH"
    scp -i .github/ssh/id_rsa -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' -r ios/build/Apps/* ubuntu@MyApp.dev:$BUILD_PATH
    scp -i .github/ssh/id_rsa -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' -r ios/build/manifest.plist ubuntu@MyApp.dev:$BUILD_PATH
}

Most of the time, the log gets stuck on this line:

/usr/bin/codesign --force --sign F4D55F28BEBE840ADF175A67B471FFBF2E27B222 --entitlements /Users/runner/Library/Developer/Xcode/DerivedData/MyApp-fhnolcbrhrsoglcxtgrffszyvmwz/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/IntermediateBuildFilesPath/MyApp.build/Release-iphoneos/MyApp.build/MyApp.app.xcent --timestamp=none /Users/runner/Library/Developer/Xcode/DerivedData/MyApp-fhnolcbrhrsoglcxtgrffszyvmwz/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/InstallationBuildProductsLocation/Applications/MyApp.app

Kudos to the answers from here: Jenkins - Xcode build works codesign fails

The problem that happened to me is that I was trying to follow the first only the first answer from Jamieson (the accepted one), but maybe it is not up to date anymore.

I used the answer from Stephen Quan and it worked perfectly! My final keychain part now is:

# Create temporary keychain
KEYCHAIN="MyApp$$.keychain"
KEYCHAIN_PASSWORD="MyApp"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"

# Append keychain to the search list
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | sed s/\"//g)
security list-keychains

# Unlock the keychain
security set-keychain-settings "$KEYCHAIN"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"

# Import certificate
security import .github/ios/secrets/MyApp.p12 -k "$KEYCHAIN" -P "" -T "/usr/bin/codesign"

# Detect the iOS identity
IOS_IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN" | head -1 | grep '"' | sed -e 's/[^"]*"//' -e 's/".*//')
IOS_UUID=$(security find-identity -v -p codesigning "$KEYCHAIN" | head -1 | grep '"' | awk '{print $2}')

# New requirement for MacOS 10.12+
security set-key-partition-list -S apple-tool:,apple: -s -k $KEYCHAIN_PASSWORD $KEYCHAIN

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM