繁体   English   中英

为 react-native ios 应用程序构建 ci/cd 管道:如何在 gitlab-ci 中运行 expo 构建?

[英]Building a ci/cd pipeline for react-native ios app: How to run expo build in gitlab-ci?

我正在帮助为使用 expo 开发的react-native应用程序设置 gitlab ci 管道。 这是我的gitlab-ci.yml

image: node/apline
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - ~/.npm

stages:
  - deploy
  - tag
before_script:
  - echo $CI_BUILD_REF
  - echo $CI_PROJECT_DIR
  - apk add --no-cache bash build-base gcc git python3 curl
  - PATCH=`git log --pretty=oneline | wc -l | sed -e 's/^[[:space:]]*//'`
  - VERSION=`cat VERSION`
  - VERSION=${VERSION%?}
  - TAG="${VERSION}${PATCH}"
  - echo "Build version = ${TAG}"

expo-build:
  stage: deploy
  artifacts:
    paths:
    - ipas/
  script:
    - sed -i "s/0.0.0/${TAG}/g" app.json
    - npm ci --production --cache .npm --prefer-offline
    - npx expo login -u $EXPO_USERNAME -p $EXPO_PASSWORD
    - EXPO_DEBUG=true npx expo build:ios --non-interactive
    - mkdir -p ipas
    - curl "$(npx expo url:ipa --non-interactive)" -o ipas/my-app-$TAG.ipa
  only:
    - master

我想要做的是让应用程序在每次需要掌握时都构建一个新的.ipa 这样我就可以将.ipa上传到我的 mdm 以分发应用程序。

问题是,如果我每个人都构建一个不同的应用程序(我有多个应用程序我正在尝试这样做),那么构建步骤似乎需要在本地运行,然后才能再次在 ci 中运行。 我的意思是命令npx expo build:ios --non-interactive每次我使用我的苹果凭证进行单独构建时都需要干预选择正确的证书。

这是来自失败构建的 output(之前在管道中成功,无需更改代码):

- Making sure project is set up correctly...
[17:26:33] Checking if there is a build in progress...
[17:26:34] Fetching available credentials
[17:26:38] Unable to validate distribution certificate due to insufficient Apple Credentials
[17:26:38] Unable to determine validity of Push Keys due to insufficient Apple Credentials
[17:26:38] CommandError: Input is required, but Expo CLI is in non-interactive mode.
Required input:
> Push Notifications Key (Key ID: XXX, Team ID: XXX)
>     not used by any apps
>     ✅ Currently valid on Apple's servers. 
>  Would you like to use this Push Key?
   at prompt (/expo-cli@3.17.17/src/prompt.ts:22:11)
   at CreateOrReusePushKey.open (/expo-cli@3.17.17/src/credentials/views/IosPushCredentials.ts:281:31)
   at processTicksAndRejections (internal/process/task_queues.js:97:5)
   at CredentialsManager.run (/expo-cli@3.17.17/src/credentials/route.ts:42:12)
   at runCredentialsManager (/expo-cli@3.17.17/src/credentials/route.ts:13:10)
   at IOSBuilder.produceCredentials (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:168:7)
   at IOSBuilder.prepareCredentials (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:124:7)
   at IOSBuilder.run (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:46:7)
   at IOSBuilder.command (/expo-cli@3.17.17/src/commands/build/BaseBuilder.ts:29:7)
   at Command.<anonymous> (/expo-cli@3.17.17/src/exp.ts:85:7) {
 code: 'NON_INTERACTIVE',
 isCommandError: true
}
[17:26:39] Failed to prepare all credentials. 
The next time you build, we will automatically use the following configuration:
[17:26:39]
[17:26:39] Project Credential Configuration:
[17:26:39]   Experience: @team/app, bundle identifier: com.app.profile
[17:26:39]     Provisioning profile (ID: XXX)
[17:26:39]     Apple Team ID: XXX,  Apple Team Name: ---------
[17:26:39]
[17:26:39]   Distribution Certificate - Certificate ID: XXX
[17:26:39]     Apple Team ID: XXX,  Apple Team Name: A Company, LLC (In-House)
[17:26:39]     used by
     @team/app, (com.app.profile)
[17:26:39] 
[17:26:39] Error
   at CredentialsManager.doQuit [as _quit] (/expo-cli@3.17.17/src/credentials/views/Select.ts:176:9)
   at CredentialsManager.run (/expo-cli@3.17.17/src/credentials/route.ts:49:42)
   at runCredentialsManager (/expo-cli@3.17.17/src/credentials/route.ts:13:10)
   at IOSBuilder.produceCredentials (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:168:7)
   at IOSBuilder.prepareCredentials (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:124:7)
   at IOSBuilder.run (/expo-cli@3.17.17/src/commands/build/ios/IOSBuilder.ts:46:7)
   at IOSBuilder.command (/expo-cli@3.17.17/src/commands/build/BaseBuilder.ts:29:7)
   at Command.<anonymous> (/expo-cli@3.17.17/src/exp.ts:85:7)

我的问题是:expo/gitlab-ci 是否支持这个工作流程,如果是,我做错了什么? 我希望它能够可靠地构建,这样我就可以为这个 react-native 应用程序开发一个可靠的 ci/cd 管道。 如果这个用例有更好的流程可供我遵循(构建和部署 react-native ios 应用程序),我也会全力以赴。 任何事情都有帮助。

阅读文档后,直接与 expo slack 上的一些好心人交谈。 这是我最终得出的结论,以便在 gitlab-ci 中为我的 react-native ios 应用程序获得可靠的 ci 构建。

这是我的gitlab-ci.yml文件中的构建阶段:

expo-build:
  stage: deploy
  artifacts:
    paths:
    - ipas/
  script:
    - sed -i "s/0.0.0/${TAG}/g" app.json
    - npm ci --prefer-offline
    - echo $P8_KEY > ${HOME}/${CI_PROJECT_NAME}.p8
    - echo $P12_DIST | base64 -d > ${HOME}/${CI_PROJECT_NAME}.p12
    - echo $PROVISIONING_PROFILE | base64 -d > ${HOME}/${CI_PROJECT_NAME}.mobileprovision
    - npx expo login -u $EXPO_USERNAME -p $EXPO_PASSWORD
    - npx expo build:ios --team-id $APPLE_TEAM_ID --push-id $PUSH_KEY_ID --dist-p12-path ${HOME}/${CI_PROJECT_NAME}.p12 --push-p8-path ${HOME}/${CI_PROJECT_NAME}.p8 --provisioning-profile-path ${HOME}/${CI_PROJECT_NAME}.mobileprovision --no-publish --non-interactive
    - mkdir -p ipas
    - curl "$(npx expo url:ipa --non-interactive)" -o ipas/${CI_PROJECT_NAME}-${TAG}.ipa
  only:
    - ci-build-test # Build api without pushing to master (protected branch)
    - master

请注意,构建命令包含以下所有标志:

--team-id 
--push-id
--dist-p12-path 
--push-p8-path
--provisioning-profile-path 
--no-publish 
--non-interactive

需要注意的是所有正在使用的环境变量。 注意我的苹果开发者和 expo 帐户用户名和密码都被使用:

  • 苹果ID
    • 我的小程序
    • 用于与 Apple Developer 门户交互
    • 需要从命令行登录苹果
  • APPLE_TEAM_ID
    • Apple Developer 门户中我的团队的 ID
    • ci 命令未显式使用,但必须使用此键在env
  • EXPO_APPLE_PASSWORD
    • 使用我的 appleid 生成的应用程序特定密码
    • 需要从命令行登录苹果
    • ci 命令未显式使用,但必须使用此键在env
  • EXPO_USERNAME
    • 我的 expo 帐户用户名
  • EXPO_PASSWORD
    • 上述用户帐户的密码

以下值是在通过标准构建提示expo bi构建应用程序后创建的,然后使用expo fetch:ios:certs获取创建/生成的凭据。 然后将二进制文件编码为 base64,然后作为字符串上传。 它们也作为环境变量公开。

  • P8_KEY
    • 应用程序名称_apns_key.p8
    • 直接在 CI 中使用
  • P12_DIST
    • 应用程序名称_dist.p12
    • 在作为环境变量上传之前在 base64 中编码
  • PROVISIONING_PROFILE
    • 应用程序名称.mobileprovision
    • 在作为环境变量上传之前在 base64 中编码
  • PUSH_KEY_ID
    • output 由expo fetch:ios:certs命令。
    • 最初我在第一次构建应用程序时让 expo 生成这个。
  • EXPO_IOS_DIST_P12_PASSWORD
    • 从 expo 生成签名证书
    • output 由expo fetch:ios:certs命令。

我希望这可以帮助任何与我有同样问题的人!

您可以通过构建标志传递您的凭据。 例如,要传递分发证书,您需要传递--dist-p12-path标志(请参阅此处的文档)

从您的 output 看来,您的按键似乎与您在其下发布的应用程序没有关联。 仅当您已经为应用程序设置了凭据(即)您已经选择了与您的应用程序关联的推送键时,使用non-interactive标志进行构建才有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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