iOS Github Actions (build, test and deploy) - ios

I'm trying to make a simple workflow using github actons, so when I push for example to my master branch, it builds the code in macOS-latest and test it on OS 12.4, iPhone 11 Pro Max.
Since it's very new, the tutorials are not complete, can someone lend me hand?
This is what I have for now:
name: StyleOn_Workflow
on: [push]
jobs:
build:
runs-on: macOS-latest
strategy:
matrix:
destination: ['platform=iOS Simulator,OS=12.4,name=iPhone 11 Pro Max']
steps:
- uses: actions/checkout#master
- name: Build
run: swift build -v
test:
name: Test
runs-on: macOS-latest
strategy:
matrix:
destination: ['platform=iOS Simulator,OS=12.4,name=iPhone 11 Pro Max']
steps:
- name: Checkout
uses: actions/checkout#master
- name: Run tests
run: swift test -v
Also since I'm not deploying the app to the app store, how can I do the deployment phase? Maybe merge it to the master branch? I need to have 3 phases, build, test and deploy
This is the error I'm getting:

Based on your question I think you should use xcodebuild command line tool instead of swift build and swift test.
As I see you should use a command like this for build:
set -o pipefail && xcodebuild clean -scheme $SCHEME -destination $DESTINATION -derivedDataPath $DERIVED_DATA_PATH build-for-testing
And use this for testing:
set -o pipefail && xcodebuild test-without-building -xctestrun $(find . -type f -name "*.xctestrun") -destination "platform=iOS Simulator,name=$DEVICE" -derivedDataPath $DERIVED_DATA_PATH -enableCodeCoverage YES
Please note that between jobs you should upload and download the .xctestrun file.
You can find a detailed example here.

Related

Github Actions: xcpretty is not found despite being installed

I'm trying to replace our iOS project's horrible Jenkins setup with Github Actions. I think I have all the pieces in place, but I'm getting a failure I don't understand. In the step where I run xcodebuild to build and test the app, I'm getting an error that xcpretty is an unknown command, despite being installed via bundler in a previous step. Here are the relevant files:
build-and-run.yml
---
name: Build & Test
on:
# Run tests when a PR merges.
push:
branches:
- develop
# Run tests when PRs are created or updated.
pull_request:
types: [opened, synchronize, reopened]
# Allow the workflow to be run manually.
workflow_dispatch:
env:
DEVELOPER_DIR: /Applications/Xcode_12.app/Contents/Developer
jobs:
test:
name: Build & Test
runs-on: 'macos-latest'
steps:
- name: Checkout Project
uses: actions/checkout#v2
with:
ref: develop
- name: Setup Ruby
uses: ruby/setup-ruby#v1.46.0
with:
ruby-version: 2.7.1
- name: Restore Ruby Cache
uses: actions/cache#v1
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: Restore Pod Cache
uses: actions/cache#v1
with:
path: Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Bundle Install
run: |
bundle config path vendor/bundle
bundle install --without=documentation --jobs 4 --retry 3
- name: Install Cocoapods
run: pod install --repo-update
- name: Show Xcode Version
run: xcode-select -p
- name: Show Build Settings
run: xcodebuild -workspace ./MyApp.xcworkspace -scheme 'MyApp-Test' -destination 'platform=iOS Simulator,name=iPhone 11' -showBuildSettings
- name: Test MyApp
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace MyApp.xcworkspace -scheme MyApp-Test -destination 'platform=iOS Simulator,name=iPhone 11' -enableCodeCoverage YES -derivedDataPath build/derived-data clean test | xcpretty -s
- name: Run Danger
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
run: bundle exec danger
Gemfile (we don't use fastlane in the action, but I have to keep it in the Gemfile for now so the builds don't break on our Jenkins box):
source 'https://rubygems.org'
ruby '2.7.1'
gem 'cocoapods'
gem 'danger'
gem 'fastlane'
gem 'xcpretty'
gem 'danger-slather'
gem 'danger-swiftlint'
gem 'danger-xcode_summary'
gem 'xcpretty-json-formatter'
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
In the Bundle Install step, the xcpretty gem is being installed:
Fetching xcpretty 0.3.0
Installing xcpretty 0.3.0
The Install Cocoapods step also works fine (probably because Cocoapods is pre-installed). When it gets to the Test MyApp step, the invocation creates an error:
Run set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace MyApp.xcworkspace -scheme MyApp-Test -destination 'platform=iOS Simulator,name=iPhone 11' -enableCodeCoverage YES -derivedDataPath build/derived-data clean test | xcpretty -s
/Users/runner/work/_temp/9d3633bf-6dae-45d7-a303-1c68abb63d53.sh: line 1: xcpretty: command not found
And then the workflow hangs for a very long time, so I usually cancel it. Any idea why xcpretty is not being found? My thought is, the directory where the gem is installed isn't in the search path, but I'm not sure about how I would do that. I'm sure there's a reasonable solution to this, but I'm having trouble finding it and am tired of banging my head against a wall.
I was facing the same issue while setting up fastlane to run my Xcode tests.
Finally, solved the issue by adding PATH in Jenkinsfile as below.
Note that SampleProject-TestCase-Executions is Sample app on my Desktop.
Please find GitHub Demo App for more info.
node {
stage "Run Fast file"
sh '''
cd /Users/bhooshanpatil/Desktop/SampleProject-TestCase-Executions
export PATH="$PATH:/usr/local/bin:/usr/local/bin:/usr/local/sbin$:"
fastlane scan
'''
}
Unfortunately, my solution was not at all tidy. I had to path into the gem installation directory and directly reference the gem executable. Thankfully, the relative path doesn't change, so I could just hardcode it into the test script. Maybe there's a more elegant solution, but once I got it working, I just dropped it.
And sorry if you're trying to reproduce this, but it was over a year ago and I left the company, so I don't have access to what the path was.
Jenkins -> Manage Jenkins -> Configure System -> Global properties -> Environment variables -> Name: LC_ALL, Value: en_US.UTF-8

How to do POD install in Bamboo Continuous integration for Xcode

I am integration my iOS project for continuous integration through bamboo. But I have difficulties in two steps. How to do a pod install and pass the certificate for signinging. However, I have the build command which is working fine in a local machine, but how to achieve this in bamboo server. Any help appericiate.
#!/bin/sh
Pod install
xcodebuild -workspace my-Container.xcworkspace -configuration -Release -scheme my-Container clean archive -archivePath build/my-Container
xcodebuild -exportArchive -archivePath build/my-Container.xcarchive -exportPath build/my-Containerr.ipa -exportOptionsPlist exportoption.plist
I have hard time to create my bamboo job for building. My steps ware:
Checkout the repo with correct branch
Script task with "pod install" inside. here
xcode build task with correct properties. You need to do some additional work in order to have this build task. Check the steps here
If you command works okay as you said then maybe you can create just a script task with your code.
In my case I had problems with certificates selection and I create script like this one:
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' MyProject/MyProject.xcodeproj/project.pbxproj
sed -i '' 's/CODE_SIGN_STYLE = Automatic;/CODE_SIGN_STYLE = Manual;/' MyProject/MyProject.xcodeproj/project.pbxproj
sed -i '' 's/CODE_SIGN_IDENTITY = "iPhone Developer";/CODE_SIGN_IDENTITY = "iPhone Distribution";/' MyProject/MyProject.xcodeproj/project.pbxproj
sed -i '' '<key>CFBundleVersion</key>= "";/PROVISIONING_PROFILE_SPECIFIER = "Profile 1";/' MyProject/MyProject.xcodeproj/project.pbxproj
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' MyProject/Info.plist
in order to build correctly

Failing to execute tests in Bitrise for debug variant

Description
I'm using Bitrise to run Detox tests. The build command runs ok and is a success. But the test command always fails.
Running locally:
Command detox test -c ios.sim.debug without starting the packager: 'No bundle URL present' error
Command detox test -c ios.sim.debug with the packager: Opens the packager and everything runs OK.
Command detox test -c ios.sim.release without the packager: works fine.
Command detox test -c ios.sim.release with the packager: works fine.
Running in Bitrise:
Command detox test -c ios.sim.debug --cleanup without starting the packager: 'No bundle URL present' error
Command detox test -c ios.sim.debug --cleanup with the packager:
Verify tests are up
"before all" hook:
Error: Timeout of 120000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/Users/vagrant/git/e2e/tests.spec.js)
Command detox test -c ios.sim.release --cleanup without the packager: works fine.
Command detox test -c ios.sim.release --cleanup with the packager: works fine.
Disclaimer
With/Without the packager means the variable RCT_NO_LAUNCH_PACKAGER equals false/true, respectively.
The package.json file
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PROJECT_NAME.app",
"build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/PROJECT_NAME.xcworkspace -scheme INTEGRATION_SCHEME -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 7"
},
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/PROJECT_NAME.app",
"build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/PROJECT_NAME.xcworkspace -scheme PRODUCTION_SCHEME -configuration Release -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 7 Plus"
},
The bitrise.yml file
_init_install:
steps:
- activate-ssh-key#3.1.1:
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
- git-clone#4.0.11: {}
- script#1.1.5:
inputs:
- content: |-
#!/usr/bin/env bash
# fail if any commands fails
set -e
# debug log
set -x
# write your script here
brew uninstall --ignore-dependencies node
brew install node#8
brew link --overwrite --force node#8
- yarn#0.0.7: {}
_detox_tests:
steps:
- npm#0.9.0:
title: Install Detox CLI
inputs:
- command: install -g detox-cli
- npm#0.9.0:
title: Install React-Native CLI
inputs:
- command: install -g react-native-cli
- script#1.1.5:
title: Install Detox Utils
inputs:
- content: |-
#!/bin/bash
brew tap facebook/fb
export CODE_SIGNING_REQUIRED=NO
brew install fbsimctl
brew tap wix/brew
brew install applesimutils --HEAD
- script#1.1.5:
title: Detox - Build Debug App
inputs:
- content: |-
#!/usr/bin/env bash
detox build -c ios.sim.debug
- script#1.1.5:
title: Detox - Run E2E Tests
inputs:
- content: |-
#!/usr/bin/env bash
detox test -c ios.sim.debug --cleanup
- deploy-to-bitrise-io#1.3.10: {}
test_ios:
before_run:
- _init_install
after_run:
- _detox_tests
steps:
- cocoapods-install#1.7.2:
inputs:
- podfile_path: ios/Podfile
- resource-archive#2.0.1:
inputs:
- extract_to_path: "$HOME/Documents/FacebookSDK/"
- archive_url:https://origincache.facebook.com/developers/resources/?id=facebook-ios-sdk-current.zip
- certificate-and-profile-installer#1.9.3: {}
```
Detox, Node, Device, Xcode and macOS Versions
Detox: v7.4.3
React Native: v0.51.0
Node: v9.4.0
Device: iPhone 7 (simulator)
Xcode: Version 9.3 (9E145)
macOS: 10.13.3 (17D102)
Device and verbose Detox logs
Error detox test -c ios.sim.debug --cleanup with the packager
pastebin
File detox.last_launch_app_log.err prints:
pastebin
TL;DR
I get an error when running Detox with Bitrise. The command detox test -c ios.sim.debug --cleanup should open a packager but looks like it's not doing it.
The version that is needed to test is the Debug one, no other options. Maybe I missed something about the installation, but all the files were checked with official docs and other examples and are the identical.
Related issues: 742, 749, 740

Xcode 9 - Xcodebuild error - UI tests not running, Timed out waiting for AX loaded notification

My tests do not start executing, and always timeout every time I try to use an xcodebuild command.
The command that I used is the following:
xcodebuild -workspace App.xcworkspace -scheme 'AppName' -sdk iphonesimulator -configuration 'UI_Automation' CODE_SIGN_STYLE='Manual' CODE_SIGN_IDENTITY='iPhone Developer: John Smith (XXXXXXXX)' PROVISIONING_PROFILE_SPECIFIER='John Smith PP Name' DEVELOPMENT_TEAM='ABC Company Apple DEV' -destination 'platform=iOS Simulator,name=iPhone 8,OS=11.2' -destination-timeout 600 -only-testing:AppUITests clean test
It goes through a process where the app is built, but then the tests do not start executing. As a matter of fact, the Simulator does not even start, and I get the following error.
Testing failed:
Timed out waiting for AX loaded notification If you believe this error represents a bug, please attach the log file at /var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/com.apple.dt.XCTest/IDETestRunSession-60333F56-66CA-4C34-8460-3846DCF59C14/AppUITests-F74C4FDD-17EE-44AD-A2BA-DDB1BC0A1D7E/Session-AppUITests-2017-12-28_150211-qwlao1.log
Does anyone know how to fix this? I have been racking my brain around this for the past 2 weeks and can't figure it out.
xcode build command changed since xcode 9. So you have to change your build command.
Follow the mentioned steps:
First build the project. Command for build app is
xcodebuild build-for-testing -workspace "Your.xcworkspace" -scheme "UpgradeAll" -destination "platform=iOS Simulator,name=iPad Air,OS=11.0" -derivedDataPath "All"
Then execute the test command using this.
xcodebuild test-without-building -xctestrun "All/Build/Products/UpgradeAll_iphonesimulator11.0-x86_64.xctestrun" -destination "platform=iOS Simulator,name=iPad Air,OS=11.0" '-only-testing:YourTestbundleName' -derivedDataPath 'build/reports/bundleName' | tee xcodebuild.log | ios-sim start --devicetypeid "iPad-Air, 11.0"
I got this error when trying to run my UI Tests through jenkins. What I did was:
Set up Jenkins as a Launch Agent instead of a daemon. (more info here https://medium.com/#ved.pandey/setting-up-jenkins-on-mac-osx-50d8fe16df9f)
Grant the jenkins user admin privileges under System Preferences -> Users & Groups -> Jenkins user -> 'Allow user to administer this computer'.
Rebooted my Mac Mini and the UI Tests work now.

Tests pass in Xcode but fail on Circle CI

Question: For this pull request, the tests do not pass on CircleCI but the tests pass locally. Why?
The CircleCI test output shows failures for all FBSnapshotTestCase tests. For example:
✗ testAdjustsFontSizeToFitWidth, ((comparisonSuccess__) is true) failed - Snapshot comparison failed: Error Domain=FBSnapshotTestControllerErrorDomain Code=1 "Unable to load reference image." UserInfo=0x7f85f36b0a50 {NSLocalizedFailureReason=Reference image not found. You need to run the test in record mode, NSLocalizedDescription=Unable to load reference image., FBReferenceImageFilePathKey=/Users/distiller/TTTAttributedLabel/Example/TTTAttributedLabelTests/ReferenceImages_32/TTTAttributedLabelTests/testAdjustsFontSizeToFitWidth#2x.png}
[…]
✗ testAttributedTruncationToken, ((comparisonSuccess__) is true) failed - Snapshot comparison failed: Error Domain=FBSnapshotTestControllerErrorDomain Code=1 "Unable to load reference image." UserInfo=0x7f85f35b06d0 {NSLocalizedFailureReason=Reference image not found. You need to run the test in record mode, NSLocalizedDescription=Unable to load reference image., FBReferenceImageFilePathKey=/Users/distiller/TTTAttributedLabel/Example/TTTAttributedLabelTests/ReferenceImages_32/TTTAttributedLabelTests/testAttributedTruncationToken#2x.png}
However, the same tests pass locally:
On CircleCI the tests use the ReferenceImages_32 directory, which does not exist:
/Users/distiller/TTTAttributedLabel/Example/TTTAttributedLabelTests/ReferenceImages_32/TTTAttributedLabelTests/testAdjustsFontSizeToFitWidth#2x.png
However, the images do exist in ReferenceImages_64. I expect the _64 directory to be used because the circle.yml file specifies to use the iPhone 6 simulator:
dependencies:
pre:
- xcrun instruments -w "iPhone 6 (8.3 Simulator)" || exit 0
override:
- sudo gem install cocoapods xcpretty obcd -N
- pod install --project-directory=Example
test:
override:
- set -o pipefail && xcodebuild -workspace 'Example/Espressos.xcworkspace' -scheme 'Espressos'
-sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 6"
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES clean test | xcpretty -c
--report junit --output ${CIRCLE_TEST_REPORTS}/junit.xml
What causes this?
How can I get the tests passing on CircleCI?
Possibly related: this FBSnapshotTestCase issue
Have you tried running the build without the cache? This often fixes these kinds of issues for me. To build without cache, just click the button at the top right.

Resources