-
-
Save ouchadam/c74fa26c639a50d68bc35ee5749f868c to your computer and use it in GitHub Desktop.
#!/bin/bash | |
set -e | |
CONFIG=$@ | |
for line in $CONFIG; do | |
eval "$line" | |
done | |
AUTH="X-API-Token: $token" | |
CONTENT_TYPE=application/vnd.android.package-archive | |
echo "Creating release (1/7)" | |
request_url="https://api.appcenter.ms/v0.1/apps/$owner/$app/uploads/releases" | |
upload_json=$(curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" "$request_url") | |
ID=$(echo $upload_json | jq -r '.id') | |
UPLOAD_DOMAIN=$(echo $upload_json | jq -r '.upload_domain') | |
PACKAGE_ASSET_ID=$(echo $upload_json | jq -r '.package_asset_id') | |
URL_ENCODED_TOKEN=$(echo $upload_json | jq -r '.url_encoded_token') | |
FILE_NAME=$(basename $file) | |
FILE_SIZE=$(stat --printf="%s" $file) | |
echo "Creating metadata (2/7)" | |
set_metadata_url="$UPLOAD_DOMAIN/upload/set_metadata/$PACKAGE_ASSET_ID?file_name=$FILE_NAME&file_size=$FILE_SIZE&token=$URL_ENCODED_TOKEN&content_type=$CONTENT_TYPE" | |
meta_response=$(curl -s -d POST -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" "$set_metadata_url") | |
chunk_size=$(echo $meta_response | jq -r '.chunk_size') | |
TMP_BUILD_DIR=build/appcenter-tmp | |
rm -rf $TMP_BUILD_DIR | |
mkdir $TMP_BUILD_DIR | |
split -b $chunk_size $file $TMP_BUILD_DIR/split | |
echo "Uploading chunked binary (3/7)" | |
binary_upload_url="$UPLOAD_DOMAIN/upload/upload_chunk/$PACKAGE_ASSET_ID?token=$URL_ENCODED_TOKEN" | |
block_number=1 | |
for f in $TMP_BUILD_DIR/* | |
do | |
url="$binary_upload_url&block_number=$block_number" | |
size=$(stat --printf="%s" $f) | |
curl -X POST $url --data-binary "@$f" -H "Content-Length: $size" -H "Content-Type: $CONTENT_TYPE" | |
block_number=$(($block_number + 1)) | |
printf "\n" | |
done | |
echo "Finalising upload (4/7)" | |
finish_url="$UPLOAD_DOMAIN/upload/finished/$PACKAGE_ASSET_ID?token=$URL_ENCODED_TOKEN" | |
curl -d POST -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" "$finish_url" | |
echo "Commit release (5/7)" | |
commit_url="https://api.appcenter.ms/v0.1/apps/$owner/$app/uploads/releases/$ID" | |
curl -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" \ | |
--data '{"upload_status": "uploadFinished","id": "$ID"}' \ | |
-X PATCH \ | |
$commit_url | |
release_status_url="https://api.appcenter.ms/v0.1/apps/$owner/$app/uploads/releases/$ID" | |
release_id=null | |
counter=0 | |
max_poll_attempts=15 | |
echo "Polling for release id (6/7)" | |
while [[ $release_id == null && ($counter -lt $max_poll_attempts)]] | |
do | |
poll_result=$(curl -s -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" $release_status_url) | |
release_id=$(echo $poll_result | jq -r '.release_distinct_id') | |
echo $counter $release_id | |
counter=$((counter + 1)) | |
sleep 3 | |
done | |
if [[ $release_id == null ]]; | |
then | |
echo "Failed to find release from appcenter" | |
exit 1 | |
fi | |
echo "Applying destination to release (7/7)" | |
distribute_url="https://api.appcenter.ms/v0.1/apps/$owner/$app/releases/$release_id" | |
curl -H "Content-Type: application/json" -H "Accept: application/json" -H "X-API-Token: $token" \ | |
--data '{"destinations": [{ "name": "$destination_name"}] }' \ | |
-X PATCH \ | |
$distribute_url | |
echo https://appcenter.ms/orgs/$owner/apps/$app/distribute/releases/$release_id |
@m046418 thanks for the heads up! I had a version which included those extra steps but forgot to update the gist, the latest revision includes polling for the release id and applying a final destination with destination_name
I noticed some minor issues with this script when running on macOS:
- Seems like
jq
isn't installed on macOS by default (or else my setup is just "special" somehow) - I had to convert this command
(stat --printf="%s" $file)
to(stat -f %z $file)
on lines 23 & 43. Apparently --printf isn't supported on macOS: https://stackoverflow.com/questions/42891856/mac-lack-of-printf-for-stat - Using a nested folder as in line 30 required adding the
-p
flag to themkdir
command on line 33. (https://phoenixnap.com/kb/create-directory-linux-mkdir-command#htoc-how-to-create-multiple-directories-with-mkdir)
Other than those issues, it was pretty smooth! Just sharing in case anyone else looking at this tripped up in similar points on macOS.
@King-of-Spades Looks like (stat -f %z $file)
is not cross-platform and only works on mac. I quickly run this in an ubuntu docker container and it gave me this:
stat: cannot read file system information for '%z': No such file or directory
I fixed this by replacing all occurrences of stat --printf="%s" ...
with $(wc -c $file | awk '{print $1}')
(line 23) and $(wc -c $f | awk '{print $1}')
(line 43).
@hffmnn thanks for the tip! Your approach works for me too.
Thank you for the script.
I added this script, but with a lot of modifications, to the App Center sample here: https://github.com/microsoft/appcenter-Xamarin.UITest-Demo/blob/main/ac-distribute.sh
I modified the script substantially to make it cross-platform & more configurable by initial variables. I also updated the doc to detail the new API approach.
Hi Adam, just wanted to say thanks for the work you did - this helped me get our ruby scripts working with the new API.
One additional item you may want to add at the end is a loop to check on the "upload_status", basically using the same endpoint as the commit_url, but called with a -X GET, the status changes from "uploadFinished" to "readyToBePublished" when the backend is ready for any further steps, like adding distribution groups or release notes.
https://openapi.appcenter.ms/#/distribute/releases_getReleaseUploadStatus
Once status changes to "readyToBePublished ", the payload includes a "release_distinct_id" which is used as the "release_id" in subsequent calls to add app to groups or add release notes.
For our purposes (iOS), we also had to make the mime type in the block uploads = "Content-Type: application/octet-stream". I was unable to find a suitable mime type in the CLI source for iOS's "ipa" file types, maybe that just my lack of TypeScript skills.
Thanks again.