You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions部署Ionic iOS TestFlight时导出IPA签名证书失败

问题

使用GitHub Actions为Ionic应用部署iOS TestFlight时,导出IPA包环节报错,提示找不到匹配团队ID 34CM2JS34W的iOS Distribution签名证书及私钥。已从Apple账号下载"Internal profile"配置文件、从Xcode导出.p12证书,转Base64后存入GitHub Secrets(密钥名分别为BUILD_PROVISION_PROFILE_BASE64和BUILD_CERTIFICATE)。

错误日志

Run #create export options
  #create export options
  EXPORT_PLIST_PATH=$RUNNER_TEMP/ExportOptions.plist
  echo -n "$EXPORT_PLIST" | base64 --decode --output $EXPORT_PLIST_PATH
  xcodebuild -exportArchive -archivePath Actions.xcarchive -exportOptionsPlist $EXPORT_PLIST_PATH -exportPath $RUNNER_TEMP/export
  shell: /bin/bash -e {0}
  env:
    JAVA_HOME: /Users/runner/hostedtoolcache/Java_Adopt_jdk/17.0.12-7/arm64/Contents/Home
    JAVA_HOME_17_ARM64: /Users/runner/hostedtoolcache/Java_Adopt_jdk/17.0.12-7/arm64/Contents/Home
    EXPORT_PLIST: ***
  
2024-08-26 09:34:10.363 xcodebuild[5528:29339] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path "/var/folders/4d/0gnh84wj53j7wyk695q0tc_80000gn/T/App_2024-08-26_09-34-10.362.xcdistributionlogs".
error: exportArchive: No signing certificate "iOS Distribution" found
** EXPORT FAILED **
Error Domain=IDECodesignResolverErrorDomain Code=1 "No signing certificate "iOS Distribution" found" UserInfo={IDEDistributionIssueSeverity=3, NSLocalizedRecoverySuggestion=No "iOS Distribution" signing certificate matching team ID "34CM2JS34W" with a private key was found., IDEProvisioningError_UserInfoKey_IDEProvisioningErrorSpecifier=iOS Distribution, NSLocalizedDescription=No signing certificate "iOS Distribution" found, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorPlatform=com.apple.platform.iphoneos, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorAction=5, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorTeam=<IDEProvisioningBasicTeam: 0x60000091d780; teamID='34CM2JS34W', teamName='(null)'>}
error: exportArchive: No signing certificate "iOS Distribution" found
Error Domain=IDECodesignResolverErrorDomain Code=1 "No signing certificate "iOS Distribution" found" UserInfo={IDEDistributionIssueSeverity=3, NSLocalizedRecoverySuggestion=No "iOS Distribution" signing certificate matching team ID "34CM2JS34W" with a private key was found., IDEProvisioningError_UserInfoKey_IDEProvisioningErrorSpecifier=iOS Distribution, NSLocalizedDescription=No signing certificate "iOS Distribution" found, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorPlatform=com.apple.platform.iphoneos, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorAction=5, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorTeam=<IDEProvisioningBasicTeam: 0x60000091d360; teamID='34CM2JS34W', teamName='(null)'>}
error: exportArchive: No signing certificate "iOS Distribution" found
Error Domain=IDECodesignResolverErrorDomain Code=1 "No signing certificate "iOS Distribution" found" UserInfo={IDEDistributionIssueSeverity=3, NSLocalizedRecoverySuggestion=No "iOS Distribution" signing certificate matching team ID "34CM2JS34W" with a private key was found., IDEProvisioningError_UserInfoKey_IDEProvisioningErrorSpecifier=iOS Distribution, NSLocalizedDescription=No signing certificate "iOS Distribution" found, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorPlatform=com.apple.platform.iphoneos, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorAction=5, IDEProvisioningError_UserInfoKey_IDEProvisioningErrorTeam=<IDEProvisioningBasicTeam: 0x60000091d7a0; teamID='34CM2JS34W', teamName='(null)'>}
error: exportArchive: No signing certificate "iOS Distribution" found

GitHub Actions配置文件

name: BucketIO app Build and Deploy

on:
  push:
    branches:
      - mobile-staging

jobs:
  build-ios:
    runs-on: macos-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Install the Apple certificate and provisioning profile
        env:
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          # create variables
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
          # import certificate and provisioning profile from secrets
          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
          # create temporary keychain
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          # import certificate to keychain
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH
          # apply provisioning profile
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
          
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'adopt'
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install Dependencies
        working-directory: BucketIO.Ionic
        run: npm cache clean --force && npm install
      - name: Install Ionic CLI globally
        working-directory: BucketIO.Ionic
        run: npm install -g @ionic/cli
      - name: Install CocoaPods
        run: sudo gem install cocoapods
      - name: Install iOS Dependencies
        working-directory: BucketIO.Ionic/ios/App
        run: pod install
      - name: Build BucketIO for iOS
        working-directory: BucketIO.Ionic
        run: |
          ionic build
          npx cap sync ios
      - name: Build app
        working-directory: BucketIO.Ionic/ios/App
        run: xcodebuild -workspace "App.xcworkspace" -scheme "App" clean archive -archivePath "Actions" -configuration "Release Production"
      - name: export ipa
        working-directory: BucketIO.Ionic/ios/App
        env:
          EXPORT_PLIST: ${{ secrets.IOS_EXPORT_PRODUCTION }}
        run: |
            #create export options
            EXPORT_PLIST_PATH=$RUNNER_TEMP/ExportOptions.plist
            echo -n "$EXPORT_PLIST" | base64 --decode --output $EXPORT_PLIST_PATH
            xcodebuild -exportArchive -archivePath Actions.xcarchive -exportOptionsPlist $EXPORT_PLIST_PATH -exportPath $RUNNER_TEMP/export
      - name: Rename the file, remove whitespace
        working-directory: BucketIO.Ionic/ios/App
        run: |
            echo Export directory contents
            ls /Users/cobemacmini/ios-runner/_work/_temp/export/
            mv "/Users/cobemacmini/ios-runner/_work/_temp/export/App.ipa" "/Users/cobemacmini/ios-runner/_work/_temp/export/App.ipa"
            ls /Users/cobemacmini/ios-runner/_work/_temp/export/
      - name: Decode auth. api key file and save it
        working-directory: BucketIO.Ionic/ios/App
        env:
          API_KEY_BASE64: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
        run: |
            ls ~/private_keys
            echo -n "$API_KEY_BASE64" | base64 --decode --output ~/private_keys/AuthKey_${{ secrets.APPSTORE_API_KEY_ID }}.p8
            echo "After saving: "
            ls ~/private_keys
      - name: "Upload file to test flight using CLI"
        working-directory: BucketIO.Ionic/ios/App
        run: |
            echo "Staring upload. "
            ls ~/private_keys
            xcrun altool --validate-app -f /Users/cobemacmini/ios-runner/_work/_temp/export/App.ipa -t ios --apiKey ${{ secrets.APPSTORE_API_KEY_ID }} —-apiIssuer ${{ secrets.APPSTORE_ISSUER_ID }}
            xcrun altool --upload-app -f /Users/cobemacmini/ios-runner/_work/_temp/export/App.ipa -t ios --apiKey "${{ secrets.APPSTORE_API_KEY_ID }}" —-apiIssuer "${{ secrets.APPSTORE_ISSUER_ID }}"

解决方案

1. 验证证书与配置文件的匹配性

  • 确认导出的.p12证书是iOS Distribution类型,且属于团队ID 34CM2JS34W。在本地Keychain Access中查看证书详情,检查"组织单位"字段是否为该团队ID。
  • 登录Apple Developer后台,进入"Profiles"页面,查看"Internal profile"配置文件的"Signing Certificates"字段,确保包含你导出的.p12证书。

2. 修复证书导入命令的权限问题

修改证书导入相关命令,确保权限配置正确,并添加验证步骤:

# 导入证书时明确权限
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
# 修复分区列表权限,添加-s参数确保生效
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# 验证证书是否成功导入
security find-certificate -c "iOS Distribution" -k $KEYCHAIN_PATH

3. 检查ExportOptions.plist配置

确保导出配置文件指定了正确的团队ID和签名类型,示例配置如下(根据配置文件类型调整method字段):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>teamID</key>
    <string>34CM2JS34W</string>
    <key>method</key>
    <string>ad-hoc</string> <!-- Internal配置文件对应ad-hoc,App Store类型对应app-store -->
    <key>signingStyle</key>
    <string>manual</string>
    <key>signingCertificate</key>
    <string>iOS Distribution</string>
</dict>
</plist>

4. 明确归档命令的签名参数

在xcodebuild archive命令中添加团队ID和证书指定,避免自动签名冲突:

xcodebuild -workspace "App.xcworkspace" -scheme "App" clean archive -archivePath "Actions" -configuration "Release Production" -teamID 34CM2JS34W -signingCertificate "iOS Distribution"

5. 优化密钥链配置

确保临时密钥链被设为默认,并延长解锁超时:

# 设置临时密钥链为用户默认
security list-keychains -d user -s $KEYCHAIN_PATH login.keychain-db
# 延长密钥链解锁超时至1小时
security set-keychain-settings -t 3600 -u $KEYCHAIN_PATH

内容的提问来源于stack exchange,提问作者fajar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:57:04