-
Star
(141)
You must be signed in to star a gist -
Fork
(43)
You must be signed in to fork a gist
-
-
Save stefanbuck/ce788fee19ab6eb0b4447a85fc99f447 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| # | |
| # Author: Stefan Buck | |
| # License: MIT | |
| # https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447 | |
| # | |
| # | |
| # This script accepts the following parameters: | |
| # | |
| # * owner | |
| # * repo | |
| # * tag | |
| # * filename | |
| # * github_api_token | |
| # | |
| # Script to upload a release asset using the GitHub API v3. | |
| # | |
| # Example: | |
| # | |
| # upload-github-release-asset.sh github_api_token=TOKEN owner=stefanbuck repo=playground tag=v0.1.0 filename=./build.zip | |
| # | |
| # Check dependencies. | |
| set -e | |
| xargs=$(which gxargs || which xargs) | |
| # Validate settings. | |
| [ "$TRACE" ] && set -x | |
| CONFIG=$@ | |
| for line in $CONFIG; do | |
| eval "$line" | |
| done | |
| # Define variables. | |
| GH_API="https://api.github.com" | |
| GH_REPO="$GH_API/repos/$owner/$repo" | |
| GH_TAGS="$GH_REPO/releases/tags/$tag" | |
| AUTH="Authorization: token $github_api_token" | |
| WGET_ARGS="--content-disposition --auth-no-challenge --no-cookie" | |
| CURL_ARGS="-LJO#" | |
| if [[ "$tag" == 'LATEST' ]]; then | |
| GH_TAGS="$GH_REPO/releases/latest" | |
| fi | |
| # Validate token. | |
| curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; } | |
| # Read asset tags. | |
| response=$(curl -sH "$AUTH" $GH_TAGS) | |
| # Get ID of the asset based on given filename. | |
| eval $(echo "$response" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=') | |
| [ "$id" ] || { echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2; exit 1; } | |
| # Upload asset | |
| echo "Uploading asset... " | |
| # Construct url | |
| GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$id/assets?name=$(basename $filename)" | |
| curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET |
Delete asset if exists using jq
sudo apt install jq
# Read asset tags.
response=$(curl -sH "$AUTH" $GH_TAGS)
# Get ID of the release.
eval $(echo "$response" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=')
[ "$id" ] || { echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2; exit 1; }
release_id="$id"
# ------New Code starts Here------
# Get ID of the asset based on given filename.
id=""
for row in $(echo $response | jq '.assets | map({name: .name, id: .id})' | jq -c '.[]'); do
name=$(echo ${row} | jq -r '.name')
if [ $name == $filename ]; then
asset_id=$(echo ${row} | jq -r '.id')
echo "Deleting asset($asset_id)... "
DELETE_URL="https://api.github.com/repos/${owner}/${repo}/releases/assets/${asset_id}"
curl -X "DELETE" -H "Authorization: token $github_api_token" "${DELETE_URL}"
fi
done
# Upload asset
echo "Uploading asset... "
# Construct url
GH_ASSET="https://uploads.github.com/repos/${owner}/${repo}/releases/${release_id}/assets?name=$(basename ${filename})"
echo $GH_ASSET
curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET
echoone little correction:
(...)
for row in $(echo $response | jq '.assets | map({name: .name, id: .id})' | jq -c '.[]'); do
name=$(echo ${row} | jq -r '.name')
if [ $name == basename $filename ]; then
asset_id=$(echo ${row} | jq -r '.id')
echo "Deleting asset($asset_id)... "
DELETE_URL="https://api.github.com/repos/${owner}/${repo}/releases/assets/${asset_id}"
curl -X "DELETE" -H "Authorization: token $github_api_token" "${DELETE_URL}"
fi
done
(...)
@awais786327 I recommend using GitHub Actions for this task https://github.com/actions/upload-release-asset nowadays.
Github Actions is not available on our enterprise server.
This script is still quite useful, thanks.
Got a curl: (3) URL using bad/illegal format or missing URL error, but this script seems to be working!
just quick 2c:
if jq is available, then it's much easier, faster and less error-prone to extract IDs and URLs via it.
Here is a response example:
$ curl https://api.github.com/repos/hashicorp/packer/releases/latest
{
"url": "https://api.github.com/repos/hashicorp/packer/releases/68048553",
"assets_url": "https://api.github.com/repos/hashicorp/packer/releases/68048553/assets",
"upload_url": "https://uploads.github.com/repos/hashicorp/packer/releases/68048553/assets{?name,label}",
"html_url": "https://github.com/hashicorp/packer/releases/tag/v1.8.1",
"id": 68048553,
...Then an upload URL and its usage transforms to:
UPLOAD_URL=$(curl -sH "${GH_AUTH}" "$(GITHUB_REPO)/releases/tags/$(VERSION_FULL)" \
| jq -r '.upload_url' | cut -d'{' -f1)
curl -X POST \
-H "${GH_AUTH}" \
-H "Accept: application/vnd.github.v3+json" \
-H "Content-Type: $(file -b --mime-type ${FILE})" \
-H "Content-Length: $(wc -c <${FILE} | xargs)" \
-T "${FILE}" \
"${UPLOAD_URL}?name=$(basename ${FILE})" | catAlso, it automatically works for enterprise environments with custom URLs, e.g. in our environment uploads.github.<corp FQDN> is not available and github.<corp FQDN>/api/uploads/ is used instead.
Oh never mind, I see, it's if you want to add your actual username and password as an option