Hello,
I’ve built a full setup with gitlab-ci that works. My .gitlab-ci.yml
contains a job to run eas build
, which is waiting the whole time for its completion, using CI minutes. Then it runs another job running eas submit
, which is also waiting the whole time, using more CI minutes.
To avoid using a lot of CI minutes from gitlab, I should run eas build --no-wait --auto-submit
. But then, I won’t have any feedback in my CI pipeline telling me what’s going on in EAS.
For sure there’s a better way, and I tried making a PoC for that, but with limitations.
I could use a gitlab API, that enables to post a build status to a commit:
The only lifecycle scripts I can run today are, according to the doc, in package.json:
"eas-build-pre-install": "bash contrib/eas-build-pre-install.sh",
"eas-build-post-install": "bash contrib/eas-build-post-install.sh",
"eas-build-pre-upload-artifacts": "bash contrib/eas-build-pre-upload-artifacts.sh",
and I can add one before it runs on eas:
"prebuild:eas": "bash contrib/prebuild-eas.sh production",
"build:eas": "eas build --no-wait"
That way, I can build the following lifecycle:
contrib/prebuild-eas.sh production
curl --request POST \
--header "PRIVATE-TOKEN: ${CI_TOKEN}" \
-d "ref=${CI_COMMIT_REF_NAME}" \
-d "pipeline_id=${CI_PIPELINE_ID}" \
-d "state=pending" \
-d "name=EAS Build: ${1} / Android" \
-d "description=The Expo application build is pending on EAS" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}"
contrib/eas-build-pre-install.sh
curl --request POST \
--header "PRIVATE-TOKEN: ${CI_TOKEN}" \
-d "?ref=${CI_COMMIT_REF_NAME}" \
-d "&pipeline_id=${CI_PIPELINE_ID}" \
-d "&state=running" \
-d "&name=EAS Build: ${EAS_BUILD_PROFILE}" \
-d "&description=The Expo application is building on EAS" \
-d "&target_url=https://expo.dev/accounts/HARDCODED_ACCOUNT/projects/HARDCODED_PROJECT/builds/${EAS_BUILD_ID}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}"
contrib/eas-build-pre-upload-artifacts
curl --request POST \
--header "PRIVATE-TOKEN: ${CI_TOKEN}" \
-d "?ref=${CI_COMMIT_REF_NAME}" \
-d "&pipeline_id=${CI_PIPELINE_ID}" \
-d "&state=running" \
-d "&name=EAS Build: ${EAS_BUILD_PROFILE}" \
-d "&description=The Expo application is building on EAS" \
-d "&target_url=https://expo.dev/accounts/HARCODED_ACCOUNT/projects/HARCODED_PROJECT/builds/${EAS_BUILD_ID}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}"
though, to make the second and third script work, I need to pass the bunch of gitlab variables through to EAS. Because unlike app.json
that you can transform into app.config.js
, I need to dynamically update eas.json
, but there’s no eas.config.js
alternative, so I need to hack it using jq
:
BUILD_ENV=$(cat << EOS
.build.production.env |= . + {
"CI_COMMIT_SHA": "${CI_COMMIT_SHA}",
"CI_COMMIT_REF_NAME": "${CI_COMMIT_REF_NAME}",
"CI_PROJECT_ID": "${CI_PROJECT_ID}",
"CI_JOB_TOKEN": "${CI_JOB_TOKEN}",
"CI_PIPELINE_ID": "${CI_PIPELINE_ID}",
} | .cli |= . + { "requireCommit": false }
EOS
)
jq "${BUILD_ENV}" < eas.json > eas.tmp.json
mv eas.tmp.json eas.json
now it’s not perfect, there are issues:
-
on Gitlab side: the
$CI_JOB_TOKEN
cannot be used to update the build status, so I need to use a private token (set as$CI_TOKEN
on both expo.dev secrets and gitlab variables), but I’m pretty sure there’s a way, I know other tools that make it work. -
on EAS side:
- there’s no way to determine whether it’s an iOS build or Android build (like there’s
$EAS_BUILD_PROFILE
to know the current profile), I could fix that by adding an env variable within.build.production.env.ios
and.build.production.env.android
… - there’s no way to plug a script at the start/end of a submit action (something like
eas-submit-before
andeas-submit-after
).
- there’s no way to determine whether it’s an iOS build or Android build (like there’s
Also, injecting variables should be easier (using eas.config.js
).
That’s a start
Once it’s all working, I got on my wishlist to:
- follow the lifecycle of the submission
- publish the artifacts links either on the pipeline or on the merge request ;
- publish the app store/play store links (to validate the next steps) as an external job (to provide the link to finalize the publication)