-
-
Save josh-padnick/fdae42c07e648c798fc27dec2367da21 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
# | |
# This is an adaptation of code I wrote to download a private binary from GitHub. Such...pain. | |
# Why can't GitHub just offer a standardized URL you can download a release binary from and attach | |
# your Github Personal Access Token as a header? | |
# | |
# Since this code is an adaptation it hasn't been directly tested, but the code it was adapted from works | |
# and hopefully you can get the missing piece you're after by looking here. | |
# | |
set -e | |
# Parse CLI args | |
readonly github_oauth_token="$1" | |
readonly git_tag="$2" | |
readonly github_repo_owner="$3" | |
readonly github_repo_name="$4" | |
readonly release_asset_filename="$5" | |
readonly output_path="$6" | |
# Get the "github tag id" of this release | |
github_tag_id=$(curl --silent --show-error \ | |
--header "Authorization: token $github_oauth_token" \ | |
--request GET \ | |
"https://api.github.com/repos/$github_repo_owner/$github_repo_name/releases" \ | |
| jq --raw-output ".[] | select(.tag_name==\"$git_tag\").id") | |
# Get the download URL of our desired asset | |
download_url=$(curl --silent --show-error \ | |
--header "Authorization: token $github_oauth_token" \ | |
--header "Accept: application/vnd.github.v3.raw" \ | |
--location \ | |
--request GET \ | |
"https://api.github.com/repos/$github_repo_owner/$github_repo_name/releases/$github_tag_id" \ | |
| jq --raw-output ".assets[] | select(.name==\"$release_asset_filename\").url") | |
# Get GitHub's S3 redirect URL | |
# Why not just curl's built-in "--location" option to auto-redirect? Because curl then wants to include all the original | |
# headers we added for the GitHub request, which makes AWS complain that we're trying strange things to authenticate. | |
redirect_url=$(curl --silent --show-error \ | |
--header "Authorization: token $github_oauth_token" \ | |
--header "Accept: application/octet-stream" \ | |
--request GET \ | |
--write-out "%{redirect_url}" \ | |
"$download_url") | |
# Finally download the actual binary | |
sudo curl --silent --show-error \ | |
--header "Accept: application/octet-stream" \ | |
--output "$output_path" \ | |
--request GET \ | |
"$redirect_url" |
ok. sorry. I have found another optimization. If you pass the filename via xargs, you can bypass that redirect problem. Other than defining the variable names, it becomes a one-liner and it'd look something like this:
curl -sL -H "Authorization: token $github_oauth_token" "https://api.github.com/repos/$github_repo_owner/$github_repo_name/releases/tags/$git_tag" | jq -r '.assets[] | select(.name == "'$release_asset_filename'").url' | xargs -I {} curl -sL -H "Authorization: token $github_oauth_token" -H 'Accept:application/octet-stream' -o $output_path {}
I made a new gist using this method here:
https://gist.github.com/mathew-fleisch/f2e0308eefe974701370f569027a7cfe
If anyone interest, give a try: https://github.com/zero88/gh-release-downloader
Actually, I can't believe I forgot to share here, but we wrote a first-class CLI tool in Go at https://github.com/gruntwork-io/fetch to do exactly what this script does and much more. It's worked well for us so far and seems to have a small, but active community of users.
also, the first curl is paged by 30 releases per page. so if the
$git_tag
isn't found in the first page, that curl will return a jq error like thisjq: error (at <stdin>:4): Cannot index string with string "tag_name" jq: error (at <stdin>:4): Cannot iterate over null (null) curl: (3) <url> malformed curl: (3) <url> malformed