Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gvenzl/1386755861fb42db492276d3864a378c to your computer and use it in GitHub Desktop.
Save gvenzl/1386755861fb42db492276d3864a378c to your computer and use it in GitHub Desktop.
One Liner to download the latest release from your GitHub repo
LOCATION=$(curl -s https://api.github.com/repos/<YOUR ORGANIZTION>/<YOUR REPO>/releases/latest \
| grep "zipball_url" \
| awk '{ print $2 }' \
| sed 's/,$//'       \
| sed 's/"//g' )     \
; curl -L -o <OUTPUT FILE NAME> $LOCATION

for example:

LOCATION=$(curl -s https://api.github.com/repos/csv2db/csv2db/releases/latest \
| grep "zipball_url" \
| awk '{ print $2 }' \
| sed 's/,$//'       \
| sed 's/"//g' )     \
; curl -L -o csv2db.zip $LOCATION

Here is how it goes:

LOCATION=$(...)

stores the output of all the commands in the brackets in the variable $LOCATION

curl -s https://api.github.com/repos/csv2db/csv2db/releases/latest

gets the latest release from your repository, in my case github.com/csv2db/csv2db

grep "zipball_url"

grabs the line for the zipball URL of the file --> "zipball_url": "https://api.github.com/repos/csv2db/csv2db/zipball/v1.5.1",
Note, there is also a tarball_url if you prefer the .tar.gz file instead.

awk '{ print $2 }'

prints just the URL part of the zipball_url line --> "https://api.github.com/repos/csv2db/csv2db/zipball/v1.5.1",

sed 's/,$//'

removes the comma , at the end of the line --> "https://api.github.com/repos/csv2db/csv2db/zipball/v1.5.1"

sed 's/"//g'

removes the double quotes " from the previous output --> https://api.github.com/repos/csv2db/csv2db/zipball/v1.5.1

Once all these commands are executed, the string is stored in the $LOCATION variable due to the surrounding $(...). The next step is to download the file from that location (or, at this stage you can do anything else you like with $LOCATION).

curl -L -o csv2db.zip $LOCATION

invokes cURL and downloads $LOCATION into a file called csv2db.zip. The -L parameter is important so that cURL follows the URL, i.e. redirects on the web page, in case that the URL gets forwarded to https or another location on the server. cURL also has an option to just store the file name under the remove file name. This can be done via -O (uppercase O) rather than -o. If you are using -O you are also advised to use -J which tells the -O option to use the server-specified Content-Disposition filename instead of extracting a filename from the URL.

@crpb
Copy link

crpb commented Jul 18, 2024

fwiw, curl -s https://api.github.com/repos/someones/something/releases/latest |jq -r '..| .browser_download_url? // empty'

@gvenzl
Copy link
Author

gvenzl commented Jul 21, 2024

Cool, thanks @crpb!

@calvinvette
Copy link

calvinvette commented May 31, 2025

If there are updates to older versions more recent than a newer version, you may get the much older version - like when an older version that gets a retrofitted security patch that a newer version just found.

Here's an ugly-but-effective one-liner to sort through the versions by semver (replace cert-manager/cert-manager with your project/repo and zipball_url with the appropriate package type):

# curl the releases JSON, use jq to find every zipball_url, exclude alpha and beta products, get just the trailing part of the URL as version number, sort it ASCIIbetically in reverse order (which should be semver-compliant), pop off the top version number as the latest
FOUND_LATEST_VERSION=$(curl -s https://api.github.com/repos/cert-manager/cert-manager/releases | jq --raw-output .[].zipball_url  | grep -ve alpha -ve beta | awk -F"/" '{print $8}' | sort -r | head -1)

# If $FOUND_LATEST_VERSION doesn't exist, fall back to version v1.0.0
VERSION=${FOUND_LATEST_VERSION:-"v1.0.0"}

echo Downloading version: ${VERSION} from "https://github.com/cert-manager/cert-manager/releases/download/${VERSION}/cert-manager.crds.yaml"
# Use -L with curl to follow redirects
curl -O -L https://github.com/cert-manager/cert-manager/releases/download/${VERSION}/cert-manager.crds.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment