Created
April 16, 2017 04:18
-
-
Save RussellCollins/e2bc551b7ffe40724cf483d12eb1a7b0 to your computer and use it in GitHub Desktop.
A convenience script for automatically pulling Android builds from a static URL and distributing them to connected devices. Assumes AAPT and adb are in your PATH variable already.
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/sh | |
APK_URL="" ###### UPDATE THIS WITH THE URL TO THE ARCHIVED LAST SUCCESSFUL BUILD ARTIFACT ON JENKINS FOR EXAMPLE | |
FILEPATH="" | |
## MAKE SURE ADB IS RUNNING ## | |
adb version | |
## DEFAULTS ## | |
LAUNCH_ENABLED="false" | |
appVersionName="" | |
appPackageName="" | |
appVersionCode="" | |
appLaunchActivity="" | |
## USAGE ## | |
usage(){ | |
echo | |
echo | |
echo | |
echo "#################### USAGE ####################" | |
echo | |
echo " -i: Install. This uninstalls the current app and carries out an install based on the supplied" | |
echo " parameters. Valid args include 'new', which will download the latest build, 'saved' which" | |
echo " will install the current locally saved build, and 'upgrade' which will install over the top of" | |
echo " the current build using install -r." | |
echo | |
echo " -l: Launch app. This launches the app with its first listed launchable-activity" | |
echo | |
echo " -h: Help. Displays script usage." | |
echo | |
echo "#################### /USAGE ####################" | |
echo | |
echo | |
echo | |
} | |
## DEVICEINFO ## | |
getConnectedDeviceInfo(){ | |
rm -f actiontmpfile.txt | |
rm -f deviceInfoFile.txt | |
adb devices | grep device | grep -v attached | cut -f 1 > actiontmpfile.txt | |
if [ -s actiontmpfile.txt ]; then | |
while read deviceId; | |
do | |
DEVICE_OS_VERSION=`adb -s $deviceId shell getprop ro.build.version.release` | |
DEVICE_OS_SDK=`adb -s $deviceId shell getprop ro.build.version.sdk` | |
DEVICE_CARRIER=`adb -s $deviceId shell getprop ro.carrier` | |
DEVICE_BRAND=`adb -s $deviceId shell getprop ro.product.brand` | |
DEVICE_MODEL=`adb -s $deviceId shell getprop ro.product.model` | |
DEVICE_SIM_STATE=`adb -s $deviceId shell getprop gsm.sim.state` | |
DEVICE_SCREEN_DENSITY=`adb -s $deviceId shell getprop ro.sf.lcd_density` | |
DEVICE_SCREEN_RES=`adb -s $deviceId shell dumpsys window policy | grep mUnrestrictedScreen | cut -d' ' -f6` | |
echo "## device - $deviceId ###################" >> deviceInfoFile.txt | |
echo "Device OS:" >> deviceInfoFile.txt | |
echo " release version: $DEVICE_OS_VERSION" >> deviceInfoFile.txt | |
echo " SDK: $DEVICE_OS_SDK" >> deviceInfoFile.txt | |
echo "Device Build:" >> deviceInfoFile.txt | |
echo " brand: $DEVICE_BRAND" >> deviceInfoFile.txt | |
echo " model: $DEVICE_MODEL" >> deviceInfoFile.txt | |
echo " carrier: $DEVICE_CARRIER" >> deviceInfoFile.txt | |
echo " GSM SIM state: $DEVICE_SIM_STATE" >> deviceInfoFile.txt | |
echo "Device Screen:" >> deviceInfoFile.txt | |
echo " screen density: $DEVICE_SCREEN_DENSITY" >> deviceInfoFile.txt | |
echo " screen resolution: $DEVICE_SCREEN_RES" >> deviceInfoFile.txt | |
echo "" >> deviceInfoFile.txt | |
done < actiontmpfile.txt | |
else | |
echo "" | |
echo "NO attached devices found. Exiting." | |
echo "" | |
rm -f actiontmpfile.txt | |
exit 1 | |
fi | |
rm actiontmpfile.txt | |
} | |
## FILEPATH ## | |
# looks for APKs in directory. | |
# if there are none, it offers y/n for downloading a new one. | |
# if there is one, it outputs the value of that relative filepath | |
# if there are more than one, it offers to clear them and download/install a new one, or install one from a list by numerical index | |
getFilePath(){ | |
rm -f ./apklist.txt | |
ls *.apk > apklist.txt | |
apkArray=( $( cat ./apklist.txt ) ) | |
arraySize=${#apkArray[@]} | |
if [ "$arraySize" -lt "1" ]; then | |
echo "" | |
echo "Sorry, it looks like you didn't download an APK yet, would you like me to? y/n" | |
read downloadRequest | |
case $downloadRequest in | |
y) | |
echo "" | |
echo "You entered 'y' for Yes. Okay, downloading a new one now" | |
download | |
FILEPATH=$( ls *.apk ) | |
echo "$FILEPATH" | |
;; | |
n) | |
echo "" | |
echo "You entered 'n' for No. Well come back when you figure out what you want to do today." | |
exit 0 | |
;; | |
*) | |
echo "" | |
echo "Seems like you misread. Let's see those instructions again." | |
usage | |
exit 0 | |
;; | |
esac | |
elif [ "$arraySize" -gt "1" ]; then | |
echo "" | |
echo "" | |
echo "There are $arraySize APKs in this folder." | |
echo "" | |
echo "Type 'list' to choose from these or 'new' to delete them and download a new one." | |
read handleMultiples | |
case $handleMultiples in | |
new) | |
echo "" | |
echo "You entered 'new'. Let's clear the slate and grab a fresh APK." | |
rm -f ./*.apk | |
download | |
FILEPATH=$( ls *.apk ) | |
;; | |
list) | |
echo "" | |
echo "You entered 'list'. Let's pick from among your existing files." | |
arrayIndex="0" | |
echo "### These are your choices. Enter the index for the desired APK. ###" | |
for i in "${apkArray[@]}" | |
do | |
versionName=$( getVersionName "$i" ) | |
versionCode=$( getVersionCode "$i" ) | |
echo " [$arrayIndex] - $i - versionName: $versionName - versionCode: $versionCode" | |
arrayIndex=$(( arrayIndex+=1 )) | |
done | |
read inputIndex | |
if [ "$inputIndex" -gt $(( arraySize-1 )) ]; then | |
echo "" | |
echo "Your selection of index '$inputIndex' exceeded the bounds of the array size $arraySize." | |
exit 0 | |
elif [ "$inputIndex" -lt "$arraySize" ]; then | |
FILEPATH=${apkArray[$inputIndex]} | |
echo "" | |
echo "You selected $FILEPATH at index $inputIndex" | |
else | |
echo "" | |
echo "your input of '$inputIndex' was invalid." | |
usage | |
exit 0 | |
fi | |
;; | |
*) | |
echo "" | |
echo "Seems like you misread. Let's see those instructions again." | |
usage | |
exit 0 | |
;; | |
esac | |
elif [ "$arraySize" -eq "1" ]; then | |
FILEPATH=${apkArray[0]} | |
else | |
echo "" | |
echo "Something went horribly wrong with getFilePath() in this script." | |
exit 1 | |
fi | |
} | |
## VERSIONNAME ## | |
getVersionName(){ # takes $FILEPATH as a parameter and gets versionName by dumping the apk badging | |
appVersionName=`aapt dump badging $1 | grep package | awk '{print $4}' | sed s/versionName=//g | sed s/\'//g` | |
} | |
## PACKAGENAME ## | |
getPackageName(){ # takes $FILEPATH as a parameter and gets packageName by dumping the apk badging | |
appPackageName=`aapt dump badging $1 | grep package | awk '{print $2}' | sed s/name=//g | sed s/\'//g` | |
} | |
## VERSIONCODE ## | |
getVersionCode(){ # takes $FILEPATH as a parameter and gets versionCode by dumping the apk badging | |
appVersionCode=`aapt dump badging $1 | grep package | awk '{print $3}' | sed s/versionCode=//g | sed s/\'//g` | |
} | |
## LAUNCHABLEACTIVITY ## | |
getLaunchActivity(){ # takes $FILEPATH as a parameter and gets launchable-activity by dumping the apk badging | |
appLaunchActivity=`aapt dump badging $1 | grep launchable-activity | awk '{print $2}' | sed s/name=//g | sed s/\'//g` | |
} | |
## INSTALL ## | |
installApp(){ # where the first parameter is the $FILEPATH and the second is the $deviceId. Uninstall always happens first. | |
echo "Uninstalling $appPackageName from $2" | |
adb -s $2 uninstall $appPackageName | |
echo "Installing $1 on $2" | |
adb -s $2 install $1 | |
} | |
## UPGRADE ## | |
upgradeApp(){ # where the first parameter is the $FILEPATH and the second is the $deviceId. | |
echo "upgradeApp called with params $1 and $2..." | |
adb -s $2 install -r $i | |
} | |
## DOWNLOAD ## | |
download(){ | |
#### Using --insecure option because the old Jenkins instance which is currently handling builds has a bad SSL cert #### | |
echo "## Downloading using $APK_URL ##" | |
curl -O --insecure $APK_URL | |
} | |
## LAUNCH ## | |
launch(){ | |
LAUNCH_ENABLED=$1 | |
rm -f launchConfig.txt | |
if [[ "$LAUNCH_ENABLED" = "true" ]] ; then | |
LAUNCH_CONFIG="shell am start -n $appPackageName/$appLaunchActivity -f 0x14000000" | |
echo $LAUNCH_CONFIG > launchConfig.txt | |
adb devices | grep device | grep -v attached | cut -f 1 > launchtmpfile | |
while read deviceId; | |
do | |
echo "My launch config is: $LAUNCH_CONFIG" | |
adb -s $deviceId $LAUNCH_CONFIG | |
done < launchtmpfile | |
rm launchtmpfile | |
fi | |
} | |
## ACTION ## | |
installAction(){ | |
#I've separated these checks in case I want to do anything differently with upgrade paths in the future | |
if [[ "$1" = "install_new" ]] ; then | |
echo "Clearing all local APKs and downloading a new one" | |
rm -f ./*.apk | |
download | |
elif [[ "$1" = "upgrade" ]] ; then | |
echo "Clearing all local APKs and downloading a new one" | |
rm -f ./*.apk | |
download | |
else # call getVersionName directly since we're not sure whether the file has been updated manually | |
getFilePath | |
getVersionName $FILEPATH | |
fi | |
#identify app to install | |
getFilePath | |
#set app variables | |
getVersionName $FILEPATH | |
getVersionCode $FILEPATH | |
getPackageName $FILEPATH | |
getLaunchActivity $FILEPATH | |
adb devices | grep device | grep -v attached | cut -f 1 > actiontmpfile | |
while read deviceId; | |
do | |
case $1 in | |
install_new) | |
echo "installAction $1" | |
installApp $FILEPATH $deviceId | |
;; | |
reinstall) #identical to install_new for now because download logic is handled elsewhere | |
echo "installAction $1" | |
installApp $FILEPATH $deviceId | |
;; | |
upgrade) #for cases where you wish to upgrade the app without nuking app data | |
echo "installAction $1" | |
upgradeApp $FILEPATH $deviceId | |
;; | |
esac | |
done < actiontmpfile | |
rm actiontmpfile | |
} | |
######################################################################## | |
########################## MAIN FUNCTIONALITY ########################## | |
# Start by gathering information about the connected devices | |
getConnectedDeviceInfo | |
# Default behavior - If no arguments are provided the script will uninstall and reinstall | |
# the app at the hardcoded $FILEPATH values without launching it afterwards | |
if (( $# < 1 )) ; then | |
installAction reinstall | |
fi | |
# Set option index to 1 | |
OPTIND=1 | |
while getopts "hli:" VALUE "$@" ; do | |
if [ "$VALUE" = "h" ] ; then | |
usage | |
exit 0 | |
fi | |
if [ "$VALUE" = "l" ] ; then | |
LAUNCH_ENABLED="true" | |
fi | |
if [ "$VALUE" = "i" ] ; then | |
case $OPTARG in | |
new) | |
echo "user wants to install the newest build" | |
ACTION="install_new" | |
;; | |
saved) | |
echo "user wants to reinstall without a download" | |
ACTION="reinstall" | |
;; | |
upgrade) | |
echo "user wants to upgrade the current installation" | |
ACTION="upgrade" | |
;; | |
*) | |
echo "invalid -i parameter" | |
usage | |
exit 1 | |
;; | |
esac | |
fi | |
if [ "$VALUE" = "?" ] ; then | |
usage | |
exit 1 | |
fi | |
if [ "$VALUE" = ":" ] ; then | |
usage | |
exit 1 | |
fi | |
done | |
## call installAction after gathering inputs | |
installAction $ACTION | |
## call launch after gathering inputs and installs complete | |
launch $LAUNCH_ENABLED | |
######################################################################## | |
########################## JIRA FUNCTIONALITY ########################## | |
## JIRA new bug template output | |
rm -f jira_new_bug_template.txt | |
echo "Collecting build, device, and launch info for JIRA template." | |
echo "" | |
echo "h1. Issue" >> jira_new_bug_template.txt | |
echo "<< enter your description of the nature of the issue here >>" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "h1. Impact" >> jira_new_bug_template.txt | |
echo "<< enter your description of the impact of this issue on the users here >>" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "h1. Repro Steps" >> jira_new_bug_template.txt | |
echo "# enter your.." >> jira_new_bug_template.txt | |
echo "# steps to reproduce.." >> jira_new_bug_template.txt | |
echo "# the issue as observed here." >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "h1. App Details" >> jira_new_bug_template.txt | |
echo "* Source: $APK_URL" >> jira_new_bug_template.txt | |
echo "* File: $FILEPATH" >> jira_new_bug_template.txt | |
echo "* Release Version: $appVersionName" >> jira_new_bug_template.txt | |
echo "* Build Number/versionCode: $appVersionCode" >> jira_new_bug_template.txt | |
echo "* Launched Activity: $appLaunchActivity" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "h1. Device(s)" >> jira_new_bug_template.txt | |
echo "{noformat}" >> jira_new_bug_template.txt | |
cat deviceInfoFile.txt >> jira_new_bug_template.txt | |
echo "{noformat}" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "" >> jira_new_bug_template.txt | |
echo "h1. LogCat Snippet" >> jira_new_bug_template.txt | |
echo "{noformat}" >> jira_new_bug_template.txt | |
echo "replace this text with a copy of the relevant lines from the device(s) LogCat output" >> jira_new_bug_template.txt | |
echo "{noformat}" >> jira_new_bug_template.txt | |
## JIRA close bug template output | |
rm -f jira_close_bug_template.txt | |
echo "" | |
echo "h1. Scope of Work Tested" >> jira_close_bug_template.txt | |
echo "<< enter your description of the scope of work tested here >>" >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "h1. Validation Steps" >> jira_close_bug_template.txt | |
echo "# enter your.." >> jira_close_bug_template.txt | |
echo "# steps to validate.." >> jira_close_bug_template.txt | |
echo "# the fix as tested here." >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "h1. App Details" >> jira_close_bug_template.txt | |
echo "* Source: $APK_URL" >> jira_close_bug_template.txt | |
echo "* File: $FILEPATH" >> jira_close_bug_template.txt | |
echo "* Release Version: $appVersionName" >> jira_close_bug_template.txt | |
echo "* Build Number/versionCode: $appVersionCode" >> jira_close_bug_template.txt | |
echo "* Launched Activity: $appLaunchActivity" >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "" >> jira_close_bug_template.txt | |
echo "h1. Device(s)" >> jira_close_bug_template.txt | |
echo "{noformat}" >> jira_close_bug_template.txt | |
cat deviceInfoFile.txt >> jira_close_bug_template.txt | |
echo "{noformat}" >> jira_close_bug_template.txt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Looks like I borked the formatting when I uploaded it. I think all my tabbing is off now. Sorry about that.