Github Actions for iOS projects
source link: https://sarunw.com/posts/github-actions-for-ios-projects/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
My purpose is to gauge its ease of use and speed. You can compare it with your current CI and judge it for yourself.
In the following example, I will set up Github Actions to build and run tests, record failing UI tests, and release the app to TestFlight.
Configuration file
First thing you have to do is create a .yml
file, which is a configuration file that Github Action can understand.
You must store workflow files in the .github/workflows/
directory in your repository. You can name the file whatever you want.
.github/workflows/your-ga-file.yml
Github Action will execute the workflow following the events under on
key. In this example, we want to run it only when we push to develop
and feature
branches.
name: CI # This workflow is triggered on pushes to the repository. on: push: branches: - develop - feature/*
A workflow run is made up of one or more jobs. For our simple example, we need only one job.
The type of virtual host machine to run the job on. For our case, we need macOS-latest
.
Each macOS contain different installed software. You can check a list of supported software, tools, and packages in each virtual environment here .
jobs: test: # Job name is test name: Test # This job runs on macOS runs-on: macOS-latest
strategy and matrix
A strategy creates a build matrix for your jobs. You can define different variations of an environment to run each job in. A build matrix is a set of different configurations of the virtual environment.
It is easier to understand with an example. In the following example, we create a matrix of two jobs, setting the destination
for our test target. As a result, two jobs will be running with a different test destination (iPhone 8 and 9).
strategy: matrix: destination: ['platform=iOS Simulator,OS=13.1,name=iPhone 8', 'platform=iOS Simulator,OS=13.1,name=iPhone 9'] steps: - name: Build and test run: bundle exec fastlane scan --destination "${destination}" --scheme "YOUR-SCHEME" env: destination: $
You can define as many matrices as you want. The total jobs are all the possible cases among those matrices. If you wish to test English and Japanese locale on iPhone 8 and 9, you can declare two matrices like this, which will create a total of 4 jobs (2 destinations x 2 schemes).
strategy: matrix: destination: ['platform=iOS Simulator,OS=13.1,name=iPhone 8', 'platform=iOS Simulator,OS=13.1,name=iPhone 9'] scheme: ['YOU-SCHEME', 'YOU-SCHEME-WITH-JAPANESE-SYSTEM-LANGUAGE'] steps: - name: Build and test run: bundle exec fastlane scan --destination "${destination}" --scheme "${scheme}" env: scheme: $ destination: $
A job contains a sequence of tasks called steps.
You can have a granular step that runs only one command or a multi-line with a sequence of tasks pack together.
A single-line command.
- name: Bundle Install run: bundle install
You pipe (|) for a multi-line command.
- name: Dependencies run: | carthage bootstrap --no-use-binaries --platform iOS --cache-builds bundle exec pod install
Environment variables
To add/remove new variables.
- Navigate to the main page of the repository.
- Under your repository name, click Settings.
- In the left sidebar, click Secrets.
Adding secrets doesn't mean it available to an action. To pass a secret to an action, set the secret as an input or environment variable in your workflow.
steps: - name: My first action env: SUPER_SECRET: ${{ secrets.SUPER_SECRET }} FIRST_NAME: Mona LAST_NAME: Octocat
Then you can use ENV['SUPER_SECRET']
in your scripts or actions.
I think these are everything you need to know to run a basic workflow.
Here is the workflow which installs Cocoapods and Carthage dependencies, running a test with fastlane scan
, upload failing UI tests if needed, and upload it to Testflight.
name: CI # This workflow is triggered on pushes to the repository. on: push: branches: - develop - feature/* jobs: test: # Job name is Test name: Test # This job runs on macOS runs-on: macOS-latest strategy: matrix: destination: ['platform=iOS Simulator,OS=13.1,name=iPhone 8'] xcode: ['/Applications/Xcode_11.1.app/Contents/Developer'] steps: - name: Checkout uses: actions/checkout@v1 - name: Bundle Install run: bundle install env: BUNDLE_GITHUB__COM: x-access-token:${{ secrets.GITHUB_PERSONAL_ACCESS_TOKEN }} - name: Dependencies run: | carthage bootstrap --no-use-binaries --platform iOS --cache-builds bundle exec pod install env: DEVELOPER_DIR: ${{ matrix.xcode }} - name: Build and test run: bundle exec fastlane scan --destination "${destination}" --scheme "YOUR_APP_SCHEME" env: destination: ${{ matrix.destination }} DEVELOPER_DIR: ${{ matrix.xcode }} - name: Archive Failed Tests artifacts if: failure() uses: actions/upload-artifact@v1 with: name: FailureDiff path: YouAppTests/FailureDiffs - name: Releasing run: bundle exec fastlane release env: DEVELOPER_DIR: ${{ matrix.xcode }} ... YOUR_ENVIRONMENT_VARIABLES_HERE: ${{ secret.XXX }} ...
Most of this is quite self explain, I won't go through the detail here, but I have will point out some obstrucle and important note I found.
Hard to access private resources
If your projects need access to other private resources, this isn't a straight forward as other CI. Most CI out there allow us to add ssh key to let CI run on behalf of that ssh. But this isn't a case for Github Actions.
GitHub automatically creates a GITHUB_TOKEN
secretto use in your workflow.
When you enable GitHub Actions, GitHub installs a GitHub App on your repository. The GITHUB_TOKEN
secret is a GitHub App installation access token used to authenticate on behalf of the GitHub App installed on your repository. The token's permissions are limited to the repository that contains your workflow. So if you need to access private gems or repositories, there might be some workaround involved.
No running build number
I always use CI build number as my Build number ( CFBundleVersion
). It is easy to trace back to exact commit where the app is running against when you have a build number. Lack of this feature is quite surprising for me. There are some 3rd party actions out there, but this is not straight forward.
BUNDLE_GITHUB__COM for private gem
Due to theabove. If you have a private gem in your Gemfile, you might need to add BUNDLE_GITHUB__COM
to env
.
- name: Bundle Install run: bundle install env: BUNDLE_GITHUB__COM: x-access-token:${{ secrets.YOUR_PERSONAL_ACCESS_TOKEN }}
Use DEVELOPER_DIR to select Xcode version
Each environment has many versions of Xcodeinstalled. Set DEVELOPER_DIR
in your env
to make sure you get the right iOS SDK to work on.
- name: Build and test run: bundle exec fastlane scan --destination "${destination}" --scheme "YOUR_APP_SCHEME" env: destination: $ DEVELOPER_DIR: '/Applications/Xcode_11.1.app/Contents/Developer'
Use git_basic_authorization in your fastlane match
If you use fastlane match, you need to access private repository which isn't possible with GITHUB_TOKEN
secret. In this case you need to specify git_basic_authorization
in your match command. The value of this key needed to be base64 encoded of username:access_token
.
match(git_basic_authorization: base64encoded(username:github_personal-access-token))
To check the result, go to Actions tab under the main page of the repository.
Following is just one sample I pick up as an example. It might not reflect overall performance.
Travis Github Actions fastlane scan 12m 38.31s 6m 35s fastlane match/gym/pilot 26m 32.20s 20m 41s The whole process of building and testing ~20m ~10m The whole process of building, testing, and deploy ~45m ~32mGithub Actions contains most features that other CI have. The only cons I see is the lack of building number and complication of access to private resources.
The speed is on par. For the price, it might vary based on the number of tasks and how often do you run the CI. I think you have to try and see for yourself.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK