Last active
October 13, 2016 07:30
-
-
Save hlung/7818585 to your computer and use it in GitHub Desktop.
A bash script to build on top of Shenzhen (https://github.com/nomad/shenzhen). Use specified targets of an Xcode iOS project.xcworkspace file, then upload to TestFlight.
This file contains hidden or 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
#!/bin/bash | |
# TestFlight-upload.sh | |
# https://gist.github.com/hlung/7818585 | |
# | |
# By Thongchai Kolyutsakul @hlungx | |
# Version: v1.0.3 - 27 Oct 2014 | |
# | |
# Requirement: Shenzhen (https://github.com/nomad/shenzhen) | |
# | |
# A bash script that calls Shenzhen to build and upload to TestFlight. | |
# It builds schemes inside Xcode project.xcworkspace file. | |
# It also shows a summary of the number of succeeded/failed at the end of build and upload steps. | |
#============================================ | |
# INPUT PARAMETERS - change to fit your needs | |
#============================================ | |
# --- Feature options --- | |
# Example: | |
# - If you only want to build and not upload, set "DEBUG_TF_SKIP_UPLOAD=1" | |
# - If you want to only upload the already built ipa files, set "DEBUG_SKIP_BUILD=1" | |
DEBUG_SKIP_BUILD_STEP=0 # set to 1 if you don't want to clean and rebuild ipa files | |
DEBUG_SKIP_TESTFLIGHT_STEP=0 # set to 1 if you don't want the built ipa files to be uploaded | |
DEBUG_TF_SKIP_NOTIFY_USERS=1 # set to 1 to add --notify option, send notification emails to users after upload (optional) | |
DEBUG_TF_REPLACE_BUILD=0 # set to 1 to add --replace option, new build will appear with the same build version and same date (optional) | |
# Setup paths, relative to this script's position | |
PATH_XCODE_WORKSPACE="../Fingi.xcworkspace" | |
PATH_OUTPUT="../build" | |
# --- Build options --- | |
SDK='iphoneos' # SDK version to build with. 'iphoneos' uses latest SDK. | |
SCHEMES=('Put your app build scheme here') # all schemes to build, e.g. SCHEMES=('MyProj Staging' 'MyProj Production') | |
# --- TestFlight options --- https://testflightapp.com/api/doc/ | |
source ~/.bash_profile # load .bash_profile to get exported environment varables | |
TF_API_TOKEN='YOUR_TESTFLIGHT_API_TOKEN' | |
TF_TEAM_TOKEN='YOUR_TESTFLIGHT_TEAM_TOKEN' | |
# TF_DISTRIBUTION_LISTS is required, comma separated. | |
# Too bad there's no 'all' option. We can just put all lists here because permitted devices are already specified in the provisioning profile. | |
TF_DISTRIBUTION_LISTS='List 1, List 2' | |
TF_NOTE='build 1 | |
- Your release notes here | |
' | |
#============================================ | |
cd "$PWD" # cd to this script's directory | |
SCHEMES_COUNT=(${#SCHEMES[*]}) | |
declare -a FAILED_BUILDS=() | |
declare -a FAILED_UPLOADS=() | |
#============ | |
# Build | |
#============ | |
if [ $DEBUG_SKIP_BUILD_STEP -eq 0 ]; then | |
# Clean output files | |
echo "*** Remove output files in directory: $PATH_OUTPUT" | |
# do dangerous stuff | |
mkdir -p $PATH_OUTPUT # create directory if not exists | |
pushd "$PATH_OUTPUT" # use double quotes so path with space works | |
rm *.ipa | |
rm *.app.dSYM.zip | |
popd | |
# build each scheme, creating ipa and .dSYM.zip files | |
echo | |
echo "*** Start building ..." | |
echo "Project dir: $PATH_XCODE_WORKSPACE" | |
printf "All schemes ($SCHEMES_COUNT):" | |
printf " \"%s\"" "${SCHEMES[@]}" | |
echo | |
i=0 | |
number_of_successful_builds=0 | |
for SCHEME in "${SCHEMES[@]}"; do | |
i=`expr $i + 1` # increment | |
echo | |
echo Building scheme "($i/$SCHEMES_COUNT)": $SCHEME | |
echo " running (quotes omitted) > "ipa build -w "$PATH_XCODE_WORKSPACE" -s "$SCHEME" -c release --sdk "$SDK" -d "$PATH_OUTPUT" --no-archive | |
# Note: `ipa build` will clean and archive by default | |
# Hardcoded arguments: -c release, --no-archive | |
OUTPUT=$(ipa build -w "$PATH_XCODE_WORKSPACE" -s "$SCHEME" -c release --sdk "$SDK" -d "$PATH_OUTPUT" --no-archive) | |
echo | |
echo $OUTPUT | |
echo | |
success=$(grep -o "successfully built" <<< "$OUTPUT" | wc -l) | |
if [ $success -eq 1 ]; then | |
number_of_successful_builds=`expr $number_of_successful_builds + 1` # increment | |
else | |
FAILED_BUILDS+=("$SCHEME") | |
fi | |
done | |
echo "** $number_of_successful_builds of $SCHEMES_COUNT schemes successfully built **" | |
echo "${FAILED_UPLOADS[@]}" | |
else | |
echo "*** SKIPPING build step ..." | |
fi | |
#============ | |
# TesteFlight | |
#============ | |
if [ $DEBUG_SKIP_TESTFLIGHT_STEP -eq 0 ]; then | |
# list all ipa files | |
cd $PATH_OUTPUT | |
IPA_FILES=() | |
for f in *.ipa; do | |
mod=${f//.ipa/} | |
IPA_FILES+=("$mod") | |
done | |
IPA_FILES_COUNT=${#IPA_FILES[*]} | |
i=0 | |
number_of_successful_uploads=0 | |
# Optional arguments | |
# DO NOT wrap flags in double quotes when in execution line | |
if [ $DEBUG_TF_REPLACE_BUILD -eq 0 ]; then | |
TF_ARG_REPLACE="" | |
else | |
TF_ARG_REPLACE=" --replace" | |
fi | |
if [ $DEBUG_TF_SKIP_NOTIFY_USERS -eq 0 ]; then | |
TF_ARG_NOTIFY=" --notify" | |
else | |
TF_ARG_NOTIFY="" | |
fi | |
echo | |
echo "*** Start uploading ..." | |
for f in "${IPA_FILES[@]}"; do | |
if [ "$f" == "*" ]; then | |
echo "No ipa file found." | |
break | |
fi | |
i=`expr $i + 1` # increment | |
ipa=$f".ipa" | |
dsym=$f".app.dSYM.zip" | |
echo -e Uploading "($i/$IPA_FILES_COUNT)": \"$ipa\" with \"$dsym\" | |
echo " running (quotes omitted) > "ipa distribute:testflight -f "$ipa" -d "$dsym" -l "$TF_DISTRIBUTION_LISTS" --notes "$TF_NOTE" -a $TF_API_TOKEN -T $TF_TEAM_TOKEN$TF_ARG_NOTIFY$TF_ARG_REPLACE | |
echo | |
OUTPUT=$(ipa distribute:testflight -f "$ipa" -d "$dsym" -l "$TF_DISTRIBUTION_LISTS" --notes "$TF_NOTE" -a $TF_API_TOKEN -T $TF_TEAM_TOKEN$TF_ARG_NOTIFY$TF_ARG_REPLACE) | |
success=$(grep -o "successfully uploaded" <<< "$OUTPUT" | wc -l) | |
if [ $success -eq 1 ]; then | |
number_of_successful_uploads=`expr $number_of_successful_uploads + 1` # increment | |
else | |
FAILED_UPLOADS+=("$ipa") | |
fi | |
done | |
echo | |
echo "** $number_of_successful_uploads of $IPA_FILES_COUNT ipa files successfully uploaded **" | |
fi | |
echo | |
echo "[ SUMMARY ]" | |
if [ $DEBUG_SKIP_BUILD_STEP -eq 0 ]; then | |
if [ ${#FAILED_BUILDS[@]} -eq 0 ]; then | |
echo " ✓ All schemes are built." | |
else | |
printf " ✗ WARNING: failed to build schemes (${#FAILED_BUILDS[@]}):" | |
echo "${FAILED_BUILDS[@]}" | |
echo "Common cause: - try checking scheme name in project, it's not saved inside project file." | |
echo " - the *-Prefix.pch file was modified, try build with device." | |
fi | |
fi | |
if [ $DEBUG_SKIP_TESTFLIGHT_STEP -eq 0 ]; then | |
if [ ${#FAILED_UPLOADS[@]} -eq 0 ]; then | |
echo " ✓ All ipa files are uploaded." | |
else | |
printf " ✗ WARNING: failed to uploads ipa files (${#FAILED_UPLOADS[@]}):" | |
echo "${FAILED_UPLOADS[@]}" | |
echo "Common cause: - outdated shenzhen gem" | |
echo " - wrong provisioning profile" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How did you manage to make Shenzhen to support distribute:testflight command?