-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: reusable-ios-build action #2837
Open
chrismclarke
wants to merge
73
commits into
master
Choose a base branch
from
feat/resusable-ios-build
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+221
−5
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR Checklist
Description
Add
reusable-ios-build
action to handle build of ios appImprove reusable build action to support custom post-build scripts and artifact upload. This enables triggering things like ios configuration scripts following the app build, so that follow-up runner doesn't have to manage deployment-specific code.
Author Notes
Once this PR is merged similar actions as the one in the debug repo PR can be added to other content repos to generate ios simulator builds. As the action depends on the latest version of the main code repo, the content repo variable for
APP_CODE_BRANCH
will also need to be set to one that includes these merged changesThe action does not (currently) upload automatically to testflight, nor can they generated artifacts be uploaded to the app store (requires follow-up work to handle code signing). So for now the main use-case is manually triggering the build action and then manually uploading the generated artifact to appetize for testing on ios simulator device
The content repo will also need and additional
GOOGLE_SERVICES_PLIST
secret if using the android-equivalentGOOGLE_SERVICES_JSON
to enable firebase features. This file can be generated from the firebase console for the associated project.Review Notes
The action is designed to be triggered by a content repo. A testing PR has been added to the debug repo used to trigger this action: IDEMSInternational/app-debug-content#154
See output artifacts from workflow run.
Example Deployment Repo Workflow Run
This should be a simulator build, able to run locally on a mac or uploaded directly to testflight.
Dev Notes
There's quite a lot going on in the action, and a whole lot more that will still require further work/follow-up. For now this really just seeks out to lay the groundwork for triggering ios builds, and is likely not yet in a state where it will drastically reduce the amount of ongoing manual work.
It should however at least be a decent proof-of-concept, and lead to a clearer understanding on the next steps required (the number of debug workflow runs on the content repo should be a good indicator of the learning involved!).
General action overview
Trigger the reusable web build to set and build code for deployment. Use an additional post-build script to sync the generated www folder to the ios app via the
npx cap sync
command. This is done as part of the build action to avoid having to reconfigure deployment and populate ios config in step 2. Upload the full ios folder as an artifact for use in next stepCheckout the builder repo and replace the default ios folder with the artifact generated in the build step (will contain public www contents as well as compiled capacitor.config.json). Install node_modules again as native plugins store podfiles in node_modules folders, and are required for build
This step could possibly be optimised if there were a cleaner way to store just the node_modules required for ios build in an artifact, so that we don't need to run a
yarn install
at all in this step.It would also be possible to generate an unsigned
.xcarchive
that could be imported locally into xcode, signed, and uploaded, although I think it would probably still be better to focus on integrating signing processes into CI instead. So for now the main purpose is generating builds capable of uploading to appetize.Github Actions - Choice of Tools
When it comes to building IOS via CI, there are generally 3 approaches
xcrun
orxcodebuild
commands directly on the runner, with additional steps to provision apple certificatesbuild-ios-action
andios-build-action
respectively which is super confusingI initially went for option 3. however found both actions were just thin wrappers around fastlane scripts (option 2), and included a mix of both a bunch of functionality that we don't want (e.g. direct upload to browserstack, enforce appstore login even when not uploading build), as well as lacking some functionality we may want (e.g. generate simulator/xcarchive builds, upload to appetize, generate screenshots etc.). I also noted the sparkfabrik repo started as a fork of the yukiarr repo, however both are loosely maintained/active.
Next I went for option 1. however quickly found there to just be a huge amount of boilerplate code required to achieve basic builds and very difficult to deubg/test locally (no access to xcode cli without a mac to test examples). Here's an example gist that should give an idea
So I settled on option 2. There is a follow-up choice of how to manage fastlane (namely whether to define scripts in a
fastfile
or execute inline. For now I've opted to execute inline although we may want to setup specific tracks in a fastfile in the futureCertificate Management
Building for IOS is typically more involved than android, as both certificates and provisioning profiles are required that need to be provided from a registered apple developer account
There's a few different approaches to this, as outlined in the fastlane codesigning docs, although the only viable for CI are:
I've experimented with both options, although limited in what can be done without access to various certs and keys that require developer account admin access as well as a local mac device. For now I've skipped the signing to process to generate only unsiged builds, which can still be exported as
.app
files to run on simulator or.xcarchive
which can later be signed and exported as.ipa
via xcode locally.I'd recommend a follow-up discussion to decide best way to handle signing builds before following up with action code to automate deploying to testflight.
For now I think the best option would likely be using fastlane match (1), authenticating via app-store-connect API. The benefit of this over (2) is the amount of secrets that would need encoding into the github action is fewer (1-2 vs 4-5). There would then be a follow-up choice to decide if fastlane match would store credentials in a private git repo or a google cloud storage bucket, here I would be leaning towards GCS as it has slightly better options for user-management (uses service accounts which are reasonably easy to set-up whereas github relies on personal access tokens which have much broader scope)
Debugging workflow
To speed up development workflow for triggered actions, I noted it would be possible to just run the build action once and then reference the generated artifacts in future builds via the run-id (instead of rebuilding each time). Local modification to the workflow looks like below (should note that build artifacts expire after 24h, so needs at least one new run per day while testing)
In order to trigger build, typically new commits need to be pushed on the debug repo. Empty commits can be added via command line
There is added complication that any changes made to builder repo files will only be available to the action after they have been merged into master, due to the way the
APP_CODE_BRANCH
variable specifies which builder branch to checkout. As such if making changes to builder repo files (e.g. creating fastlane files in the ios folder), then this should temporarily be updated to target the current pr branchMisc Notes
I've registered an ios app in the debug-app firebase project and added the google services plist to the debug content repo
GOOGLE_SERVICES_PLIST
secret for use in testingTODO - Follow-up
APP_CODE_BRANCH
variable in debug repo (currently targeting this branch, should targetmaster
)fastlane init
files in ios folder)Git Issues
Closes #
Screenshots/Videos
Example - content repo action artifacts. The

simulator_app
artifact contains app for upload to appetizeExample - Debug App built and (manually) uploaded to appetize
