我正在帮助为使用 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
都需要干预来选择正确的证书。
这是失败构建的输出(之前在管道中成功,无需更改代码):
- 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 (/[email protected]/src/prompt.ts:22:11)
at CreateOrReusePushKey.open (/[email protected]/src/credentials/views/IosPushCredentials.ts:281:31)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at CredentialsManager.run (/[email protected]/src/credentials/route.ts:42:12)
at runCredentialsManager (/[email protected]/src/credentials/route.ts:13:10)
at IOSBuilder.produceCredentials (/[email protected]/src/commands/build/ios/IOSBuilder.ts:168:7)
at IOSBuilder.prepareCredentials (/[email protected]/src/commands/build/ios/IOSBuilder.ts:124:7)
at IOSBuilder.run (/[email protected]/src/commands/build/ios/IOSBuilder.ts:46:7)
at IOSBuilder.command (/[email protected]/src/commands/build/BaseBuilder.ts:29:7)
at Command.<anonymous> (/[email protected]/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] (/[email protected]/src/credentials/views/Select.ts:176:9)
at CredentialsManager.run (/[email protected]/src/credentials/route.ts:49:42)
at runCredentialsManager (/[email protected]/src/credentials/route.ts:13:10)
at IOSBuilder.produceCredentials (/[email protected]/src/commands/build/ios/IOSBuilder.ts:168:7)
at IOSBuilder.prepareCredentials (/[email protected]/src/commands/build/ios/IOSBuilder.ts:124:7)
at IOSBuilder.run (/[email protected]/src/commands/build/ios/IOSBuilder.ts:46:7)
at IOSBuilder.command (/[email protected]/src/commands/build/BaseBuilder.ts:29:7)
at Command.<anonymous> (/[email protected]/src/exp.ts:85:7)
我的问题是:expo/gitlab-ci 支持这个工作流程吗?如果是的话,我做错了什么?我希望它能够可靠地构建,这样我就可以为这个反应本机应用程序开发一个可靠的 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 帐户用户名和密码都被使用:
env
中env
中以下值是在通过标准构建提示
expo bi
构建应用程序后创建的,然后使用 expo fetch:ios:certs
获取创建/生成的凭据。然后,二进制文件被编码为 base64,然后作为字符串上传。它们也作为环境变量公开。
expo fetch:ios:certs
命令输出。expo fetch:ios:certs
命令输出。我希望这可以帮助任何和我有同样问题的人!
您可以通过构建标志传递您的凭据。例如,要传递分发证书,您需要传递
--dist-p12-path
标志(请参阅文档此处)
从您的输出来看,您的按键似乎与您正在发布的应用程序没有关联。仅当您已为应用程序设置了凭据(即您已选择与应用程序关联的推送键)时,使用
non-interactive
标志进行构建才会起作用。