#!/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 |
This comment has been minimized.
This comment has been minimized.
That's a very cool script, can you add a license to it so I could reuse it on other projects? Thanks in advance |
This comment has been minimized.
This comment has been minimized.
@babelouest License added, thanks for the hint. @WesleyBatista Good spot. I removed |
This comment has been minimized.
This comment has been minimized.
Thanks @stefanbuck, very convenient script. And for those who want overwrite the asset with the same filename:
|
This comment has been minimized.
This comment has been minimized.
I tried uploading the file using
Any idea what is going sour here? |
This comment has been minimized.
This comment has been minimized.
Brilliant! This is just what I needed. Thanks. I do get a message saying "curl: (3) malformed" whenever I run it, but that doesn't seem to interfere with its functioning. |
This comment has been minimized.
This comment has been minimized.
What is Edit: Nevermind, basename reduced the full path of the file to just filename. Update: Note to self, if switching to gh-actions to publish to gh-pages, refer this simple yml and don't forget to generate a PAT (Personal Access Tokens) here and add it into your repo -> settings -> secrets under key: |
This comment has been minimized.
This comment has been minimized.
@stefanbuck what in that case if we need to upload more then 1 zip file ? |
This comment has been minimized.
This comment has been minimized.
@awais786327 I recommend using GitHub Actions for this task https://github.com/actions/upload-release-asset nowadays. |
This comment has been minimized.
This comment has been minimized.
Thanks! This script is really useful when working under cli ! @stefanbuck I followed the hint from @huxingyi and added some improvement with my fork |
This comment has been minimized.
This comment has been minimized.
Hello! When i run this command: ./upload-github-release-asset.sh github_api_token=xxx owner=night repo=moon tag=4.4 filename=./artifact.zip I receive this message:
I have a release 4.4 and use github enterprise. Can you help me? |
This comment has been minimized.
This comment has been minimized.
Enterprise has it's own server, looks like your token is not valid for |
This comment has been minimized.
This comment has been minimized.
@typebrook, thanks!
I change my url to Error: Invalid repo, token or network issue! I think this repo and token it's okay:
|
This comment has been minimized.
This comment has been minimized.
This block is failing to retrieve my asset id - returns "".
jq did the trick however - with a lot less code and complexity:
Cheers, |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
Good job!! |
This comment has been minimized.
This comment has been minimized.
What is the variable $GITHUB_OAUTH_BASIC supposed to be? |
This comment has been minimized.
This comment has been minimized.
Oh never mind, I see, it's if you want to add your actual username and password as an option |
This comment has been minimized.
This comment has been minimized.
Delete asset if exists using
# 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
echo |
This comment has been minimized.
Didn't tried your snippet, but
$localAssetPath
is not defined. It should work? maybe you meant$filename