iOS 构建在 GitHub 操作上失败(没有 fastlane),但它会间歇性地工作
iOS build fails on GitHub Actions (without fastlane), but it works intermittently
我构建 iOS 应用程序的方法略有不同。与其将一堆代码放在 .yaml 文件中,我更喜欢将大部分内容放在 shell 脚本中并有一个更简单的 .yaml 文件...这种方法有什么问题吗?
我的构建卡在了 "Build app" 步骤。其他步骤工作正常。
间歇性地,就像每 15 次一次它神奇地起作用,但大多数时候它都失败了。它卡住了,我看不到日志,直到我取消作业,但日志没有说任何有用的东西。 运行 我本地机器上的脚本 100% 有效。 GitHub actions.
好像很特别
在GitHub 操作中使用此方法(bash 脚本)是否有任何问题和限制?
为什么会失败?
我没有使用 fastlane。
这是我的 YAML 文件:
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
和剧本
#!/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=
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=
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
}
大多数时候,日志卡在这一行:
/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
感谢这里的回答:
Jenkins - Xcode build works codesign fails
发生在我身上的问题是,我试图仅遵循 Jamieson 的第一个答案(已接受的答案),但也许它不再是最新的了。
我使用了 Stephen Quan 的答案,效果非常好!
我现在的最后一个钥匙串部分是:
# 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 }')
# New requirement for MacOS 10.12+
security set-key-partition-list -S apple-tool:,apple: -s -k $KEYCHAIN_PASSWORD $KEYCHAIN
我构建 iOS 应用程序的方法略有不同。与其将一堆代码放在 .yaml 文件中,我更喜欢将大部分内容放在 shell 脚本中并有一个更简单的 .yaml 文件...这种方法有什么问题吗?
我的构建卡在了 "Build app" 步骤。其他步骤工作正常。 间歇性地,就像每 15 次一次它神奇地起作用,但大多数时候它都失败了。它卡住了,我看不到日志,直到我取消作业,但日志没有说任何有用的东西。 运行 我本地机器上的脚本 100% 有效。 GitHub actions.
好像很特别在GitHub 操作中使用此方法(bash 脚本)是否有任何问题和限制? 为什么会失败?
我没有使用 fastlane。 这是我的 YAML 文件:
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
和剧本
#!/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=
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=
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
}
大多数时候,日志卡在这一行:
/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
感谢这里的回答: Jenkins - Xcode build works codesign fails
发生在我身上的问题是,我试图仅遵循 Jamieson 的第一个答案(已接受的答案),但也许它不再是最新的了。
我使用了 Stephen Quan 的答案,效果非常好! 我现在的最后一个钥匙串部分是:
# 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 }')
# New requirement for MacOS 10.12+
security set-key-partition-list -S apple-tool:,apple: -s -k $KEYCHAIN_PASSWORD $KEYCHAIN