-
-
Save maxim/6e15aa45ba010ab030c4 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
# | |
# gh-dl-release! It works! | |
# | |
# This script downloads an asset from latest or specific Github release of a | |
# private repo. Feel free to extract more of the variables into command line | |
# parameters. | |
# | |
# PREREQUISITES | |
# | |
# curl, wget, jq | |
# | |
# USAGE | |
# | |
# Set all the variables inside the script, make sure you chmod +x it, then | |
# to download specific version to my_app.tar.gz: | |
# | |
# gh-dl-release 2.1.1 my_app.tar.gz | |
# | |
# to download latest version: | |
# | |
# gh-dl-release latest latest.tar.gz | |
# | |
# If your version/tag doesn't match, the script will exit with error. | |
TOKEN="<github_access_token>" | |
REPO="<user_or_org>/<repo_name>" | |
FILE="<name_of_asset_file>" # the name of your release asset file, e.g. build.tar.gz | |
VERSION=$1 # tag name or the word "latest" | |
GITHUB="https://api.github.com" | |
alias errcho='>&2 echo' | |
function gh_curl() { | |
curl -H "Authorization: token $TOKEN" \ | |
-H "Accept: application/vnd.github.v3.raw" \ | |
$@ | |
} | |
if [ "$VERSION" = "latest" ]; then | |
# Github should return the latest release first. | |
parser=".[0].assets | map(select(.name == \"$FILE\"))[0].id" | |
else | |
parser=". | map(select(.tag_name == \"$VERSION\"))[0].assets | map(select(.name == \"$FILE\"))[0].id" | |
fi; | |
asset_id=`gh_curl -s $GITHUB/repos/$REPO/releases | jq "$parser"` | |
if [ "$asset_id" = "null" ]; then | |
errcho "ERROR: version not found $VERSION" | |
exit 1 | |
fi; | |
wget -q --auth-no-challenge --header='Accept:application/octet-stream' \ | |
https://$TOKEN:@api.github.com/repos/$REPO/releases/assets/$asset_id \ | |
-O $2 |
Can I download a release asset from a private github repo without creating a personal token and only using the github token provided by github in action workflows?
If anyone interest, give a try: https://github.com/zero88/gh-release-downloader
@faisalkhanani-ih Yes if GitHub token is in workflow within this private Github repo
Thank you so much for making this snippet, it is a real lifesaver!
In my workflow, I had a beta and release feature, but it always gave me back the latest general release, no matter if it was a prerelease or not.
This shouldn't be a big problem if you automate it because there shouldn't be concurent build and release processes at the same time anyway, but I like to be safe, so I made a little improvement to get the latest prerelease or release, what you want:
Replace line 42 with this:
parser=".[] | select(.prerelease == SHOULD_BE_PRERELEASE) | .assets | map(select(.name == \"$FILE\"))[0].id"
If you replace SHOULD_BE_PRERELEASE with true it gives you back the asset id of the latest prerelease,
if you replace it with false, it gives you the asset id of the latest full release.
You can do the same thing for body or draft and stuff, that is just the way you have to filter it.
Hope this helps!
awesome
As we needed some releases that were in the 5th page (so per_page=100 didn't help), I rewrote the query to query latest (it gives latest released) and tag. also needed some more information in the error reporting:
#!/usr/bin/env bash
#
# gh-dl-release! It works!
#
# This script downloads an asset from latest or specific Github release of a
# private repo. Feel free to extract more of the variables into command line
# parameters.
#
# PREREQUISITES
#
# curl, wget, jq
#
# USAGE
#
# Set all the variables inside the script, make sure you chmod +x it, then
# to download specific version to my_app.tar.gz:
#
# gh-dl-release 2.1.1 my_app.tar.gz
#
# to download latest version:
#
# gh-dl-release latest latest.tar.gz
#
# If your version/tag doesn't match, the script will exit with error.
TOKEN="$3"
REPO="$4"
FILE="$2" # the name of your release asset file, e.g. build.tar.gz
VERSION="$1" # tag name or the word "latest"
GITHUB="https://api.github.com"
alias errcho='>&2 echo'
function gh_curl() {
curl -H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3.raw" \
$@
}
parser=".assets | map(select(.name == \"$FILE\"))[0].id"
if [ "$VERSION" = "latest" ]; then
# Github should return the latest release first.
asset_id=`gh_curl -s $GITHUB/repos/$REPO/releases/latest | jq "$parser"`
else
asset_id=`gh_curl -s $GITHUB/repos/$REPO/releases/tags/$VERSION | jq "$parser"`
fi;
if [ -z "$asset_id" ]; then
errcho "ERROR: version not found $VERSION"
exit 1
fi;
if [ "$asset_id" = "null" ]; then
errcho "ERROR: file $FILE not found in version $VERSION"
exit 2
fi;
wget -q --auth-no-challenge --header='Accept:application/octet-stream' \
https://$TOKEN:@api.github.com/repos/$REPO/releases/assets/$asset_id \
-O $2
For Windows users, I made a PowerShell equivalent
https://gist.github.com/sonibla/a60fc31b244ceba3220b9bb33316798c
I have updated the code for the latest github api and changed it to supporting for multiple files download. User can set only necessary file names in the array.
TOKEN="<PAT>"
REPO="<REPO>"
VERSION="<RELEASED-VERSION>"
GITHUB="https://api.github.com"
function gh_curl() {
curl -H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
$@
}
# assets list you want to download
AseertsList=(
asset1.zip asset2.zip
)
assets=$(gh_curl -s $GITHUB/repos/$REPO/releases/tags/$VERSION)
for row in $(echo "${assets}" | jq -c '.assets[]'); do
name=$( jq -r '.name' <<< "${row}" )
echo ${name}
if [[ ${AseertsList[*]} =~ ${name} ]] ; then
id=$( jq -r '.id' <<< "${row}" )
wget -q --auth-no-challenge --header='Accept:application/octet-stream' \
https://$TOKEN:@api.github.com/repos/$REPO/releases/assets/$asset_id \
-O test/${name}
fi
done
using application/octet-stream
as Accept
header did the trick for me to download from a private repo
Using wget
didn't fit my vanilla GH-Hosted-Runners, so I'm dropping here a curl version of that download that worked for me:
curl -L -s -H "Authorization: token $TOKEN" -H 'Accept:application/octet-stream' \
"https://api.github.com/repos/$REPO/releases/assets/$asset_id" \
-o $asset_name
For releases, uses gh release download
instead.
gh release download -R MyOrg/MyRepo --pattern 'myproject-*.tar.gz'
for example.
Here are the official docs for anyone else who stumbles on this thread which say to do (note octet-stream
here bc I was downloading a binary):
curl -L \
-H "Accept: application/octet-stream" \
-H "Authorization: Bearer <YOUR-TOKEN>"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/OWNER/REPO/releases/assets/ASSET_ID
If (like me) you're confused about the best way to find out ASSET_ID
I'd suggest looking at the json output for the latest release, see the docs here and the code here:
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/OWNER/REPO/releases/latest
Dont' forget to enable repo permission (yes, exactly root permission, enabling all nested permissions does not work) for the token