Skip to content

Instantly share code, notes, and snippets.

@jainakshansh
Last active December 21, 2019 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jainakshansh/4c99fd133d9209fa0a46a10ff6b353f1 to your computer and use it in GitHub Desktop.
Save jainakshansh/4c99fd133d9209fa0a46a10ff6b353f1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Name variables.
ENVIRONMENT=$1
SLACK_TITLE=$2
# Safety checks. Exiting if the parameters are not passed.
if [[ -z "$ENVIRONMENT" ]]; then
echo "Need environment data. Choose from: Debug, Release, etc."
exit 1
fi
if [[ -z "$SLACK_TITLE" ]]; then
echo "What is the build for? Please provide a title for the Slack message. Exiting."
exit 1
fi
# Generating the Android App Bundle.
echo "Generating Android App Bundle"
echo "Creating $ENVIRONMENT build..."
# Following command builds the aab for the required environment.
echo ./gradlew bundle${ENVIRONMENT}
echo "$ENVIRONMENT build created"
# Starting the Internal App Sharing code here.
AAB_PATH="PATH TO YOUR AAB"
PLAYSTORE_KEY="PATH TO YOUR SERVICE ACCOUNT JSON"
PACKAGE_NAME="YOUR APP PACKAGE NAME HERE"
# Extracting variables from the Service Account JSON.
AUTH_TOKEN=$(cat ${PLAYSTORE_KEY} | jq -r '.private_key')
AUTH_ISS=$(cat ${PLAYSTORE_KEY} | jq -r '.client_email')
AUTH_AUD=$(cat ${PLAYSTORE_KEY} | jq -r '.token_uri')
# Empty check for above variables.
if [[ -z "$AUTH_TOKEN" ]] || [[ -z "$AUTH_ISS" ]] || [[ -z "$AUTH_AUD" ]]; then
echo "PLAYSTORE_SERVICE_KEY not as expected. Exiting."
exit 1
fi
# Getting access token.
echo "\nGetting access token..."
# Creating a file with auth token to pass as a parameter. Easier to read from a file.
echo "$AUTH_TOKEN" > auth.txt
# Generating the Base64 url encoded header.
JWT_HEADER=$(printf '{"alg":"RS256","typ":"JWT"}' | openssl base64 -e)
# Creating the Claims JSON.
CLAIMS="{\"iss\": \"$AUTH_ISS\",\"scope\": \"https://www.googleapis.com/auth/androidpublisher\",\"aud\": \"$AUTH_AUD\",\"exp\": $(($(date +%s)+3600)),\"iat\": $(($(date +%s)))}"
# Generating the Base64 url encoded claim set.
JWT_CLAIMS=$(printf "$CLAIMS" | openssl base64 -e)
# Stitching together the header and the claim as -> {Header.Claim}
JWT_PART_1=$(printf "$JWT_HEADER.$JWT_CLAIMS" | tr -d '\n' | tr -d '=' | tr '/+' '_-')
# Signing the Header.Claim with token.
JWT_SIGNING=$(printf "$JWT_PART_1" | openssl dgst -binary -sha256 -sign auth.txt | openssl base64 -e)
# Cleaning up the Signature.
JWT_PART_2=$(printf "$JWT_SIGNING" | tr -d '\n' | tr -d '=' | tr '/+' '_-')
# Stitching together JWT Part 1 & 2. Finally looks like {Header.Claims.Signing}
JWT_FINAL=$(printf "$JWT_PART_1.$JWT_PART_2")
# Removing the file with AUTH_TOKEN because it's no longer needed.
rm auth.txt
# Making an API request with the final generated JWT.
HTTP_RESPONSE_TOKEN=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
--request POST \
--data "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=$JWT_FINAL" \
"$AUTH_AUD")
HTTP_BODY_TOKEN=$(echo ${HTTP_RESPONSE_TOKEN} | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS_TOKEN=$(echo ${HTTP_RESPONSE_TOKEN} | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# Exit if the token generation fails.
if [[ ${HTTP_STATUS_TOKEN} != 200 ]]; then
echo -e "Create access token failed.\nStatus: $HTTP_STATUS_TOKEN\nBody: $HTTP_BODY_TOKEN\nExiting."
exit 1
fi
# Extracting Access Token from the JSON response.
ACCESS_TOKEN=$(echo ${HTTP_BODY_TOKEN} | jq -r '.access_token')
# Uploading AAB. This uploads the AAB to Internal App Sharing using Google APIs.
echo "Uploading AAB ...\n"
HTTP_RESPONSE_UPLOAD_AAB=$(curl --write-out "HTTPSTATUS:%{http_code}" \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Content-Type: application/octet-stream" \
--progress-bar \
--request POST \
--upload-file ${AAB_PATH} \
https://www.googleapis.com/upload/androidpublisher/v3/applications/internalappsharing/${PACKAGE_NAME}/artifacts/bundle?uploadType=media)
HTTP_BODY_UPLOAD_AAB=$(echo ${HTTP_RESPONSE_UPLOAD_AAB} | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS_UPLOAD_AAB=$(echo ${HTTP_RESPONSE_UPLOAD_AAB} | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# Check if the post request for uploading has been successful. If not, exit.
if [[ ${HTTP_STATUS_UPLOAD_AAB} != 200 ]]; then
echo -e "Upload aab failed"
echo "Status: $HTTP_STATUS_UPLOAD_AAB"
echo "Body: $HTTP_BODY_UPLOAD_AAB"
echo "Exiting"
exit 1
fi
# Extracting link of the AAB uploaded from the JSON.
LINK=$(echo ${HTTP_BODY_UPLOAD_AAB} | jq -r '.downloadUrl')
# Slack Notification.
SLACK_WEBHOOK="YOUR INCOMING SLACK WEBHOOK LINK HERE"
echo "Notifying Slack channel ..."
HTTP_RESPONSE_SLACK=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
--header "Content-type: application/json" \
--request POST \
--data \
"{ \
\"channel\": \"CHANNEL NAME - IF YOU WANT TO POST TO A PARTICULAR CHANNEL.\", \
\"text\": \"$SLACK_TITLE\", \
\"attachments\": [ \
{ \
\"fallback\": \"Test link button to: $LINK\",
\"actions\": [ \
{ \
\"type\": \"button\", \
\"name\": \"NAME IT W.R.T. TYPE OF BUILD MAYBE?\", \
\"text\": \"Install App\", \
\"url\": \"$LINK\", \
\"style\": \"primary\" \
} \
] \
} \
] \
}" \
"$SLACK_WEBHOOK")
# Extracting the content from the response.
HTTP_BODY_SLACK=$(echo ${HTTP_RESPONSE_SLACK} | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS_SLACK=$(echo ${HTTP_RESPONSE_SLACK} | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# Notifying the user if the sharing link to Slack has failed.
if [[ ${HTTP_STATUS_SLACK} != 200 ]]; then
echo -e "Slack notification failed"
echo "Status: $HTTP_STATUS_TOKEN"
echo "Body: $HTTP_BODY_TOKEN"
echo "Exiting"
exit 1
fi
# Notifying user if sharing the link to Slack has been successful.
if [[ ${HTTP_STATUS_SLACK} == 200 ]]; then
echo "Your build has been shared on Slack"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment