# Shell script for continuous integration for iOS projects

> Note: This is a repost from  [This blogger post](https://nacho4d-nacho4d.blogspot.com/2018/10/shell-script-for-continuous-integration.html) to tests hashnode functionalities

I've done this various times in so different ways and for different services but in the end internally everything boils down to the xcodebuild command to build and test. Also generate unit tests and coverage report. Here is a not-fancy but effective and short way of doing it (Yeah, I know recently Circle, Travis, etc, even Azure Devops are more exciting these days).

## Build and Test an Xcode project


```bash
export LC_CTYPE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
cd change/to/xcodeproj/directory

carthage version
carthage bootstrap --cache-builds --platform iOS
# pod install

MY_SCHEME_NAME='MySchemeName'
MY_PROJECT_FILENAME='MyProject.xcodeproj'

xcodebuild -version
xcodebuild clean test -scheme "$MY_SCHEME_NAME" \
    -sdk iphonesimulator \
    -project "$MY_PROJECT_FILENAME" \
    -configuration Debug \
    -destination "platform=iOS Simulator,name=iPhone 8" \
    -enableCodeCoverage YES \
    | tee xcodebuild_${BUILD_NUMBER}.log \
    | xcpretty --report junit

slather version
slather coverage --verbose --jenkins --arch x86_64 \
    --scheme "$MY_SCHEME_NAME" --input-format profdata \
    --cobertura-xml --output-directory build/reports \
    --show "$MY_PROJECT_FILENAME"
``` 

### Explanation & Recommendations

- Make sure to set `LC_ALL` to `UTF8` because sometimes `xcpretty` cannot parse some *special* characters written by xcodebuild. Usually such characters coming from logs of your code.

- Make sure to print tools versions. Version numbers are helpful when problems occur and you want to reproduce CI environment locally or simply look for release notes or upgrade things.

- *xcpretty* is nice but sometimes it cuts the error logs incorrectly, specially for UI Tests. That is why I used *tee* to write the raw log from xcodebuild to a file. Otherwise considering disabling *xcpretty*.

- Disabling *xcpretty* means no junit report so Jenkins job might end in error.

- When using *slather* make sure to set the architecture. It is required when Xcode builds more than only one architecture.

-*slather* is cool but documentation is poor and some parameter don't work together. For example *--simple-output* and *--cobertura-xml* causes no errors and it silently skips cobertura xml output :(

## Upload IPA file to iTunes connect

Usually after building and testing the app you want to upload the IPA file to iTunes connect for TestFlight testing.

```
ALTOOL=
/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool
"$ALTOOL" --upload-app -u $USERNAME -p $PASSWORD -f $IPA_FILENAME
```

Hope it helps :]
