How to download the latest GitHub repo release via command line

I just fiddled around a bit to find out how to download the latest GitHub release via the command line. Turns out that GitHub doesn’t provide a universal download URL to release binaries like it does for the release browser page itself. The latest release page can always be reached via https://github.com/ORGANIZATION/REPO/releases/latest, e.g. https://github.com/gvenzl/csv2db/releases/latest. Unfortunately that is not true for the binaries, which are available under https://github.com/ORGANIZATION/REPO/archive/RELEASE_TAG.zip and https://github.com/ORGANIZATION/REPO/archive/RELEASE_TAG.tar.gz but not under something generic like https://github.com/ORGANIZATION/REPO/archive/latest.zip and https://github.com/ORGANIZATION/REPO/archive/latest.tar.gz

The issue here is that GitHub only provides the release binaries under their actual release tag, e.g. v1.0.0, but that tag is entirely up to the user to define and changes as more releases are added, of course. It’s therefore hard to guess what the release tag would be and what to download. Nevertheless, thanks to the GitHub developer APIs it’s not that tricky to figure out the release tag for the latest release and instruct a utility like curl to download the binary. I’ve written a little one-liner for the UNIX command line to do exactly that. It took me a bit to get it right and so I thought it might come handy to you, rather than trying to reinvent the wheel. it It’s also available as a public Gist but I thought for visibility purposes it makes sense to blog it here, too.

LOCATION=$(curl -s https://api.github.com/repos/YOUR_ORGANIZTION/YOUR_REPO/releases/latest \
| grep "tag_name" \
| awk '{print "https://github.com/YOUR_ORGANIZATION/YOUR_REPO/archive/" substr($2, 2, length($2)-3) ".zip"}') \
; curl -L -o OUTPUT_FILE_NAME $LOCATION

For example:

LOCATION=$(curl -s https://api.github.com/repos/gvenzl/csv2db/releases/latest \
| grep "tag_name" \
| awk '{print "https://github.com/gvenzl/csv2db/archive/" substr($2, 2, length($2)-3) ".zip"}') \
; 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/gvenzl/csv2db/releases/latest

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

grep "tag_name"

grabs the tag name of the latest release (e.g. v1.0.0),

awk '{print "https://github.com/gvenzl/csv2db/archive/" substr($2, 2, length($2)-3) ".zip"}'

prints https://github.com/gvenzl/csv2db/archive/ + v1.0.0.zip
–>
https://github.com/gvenzl/csv2db/archive/v1.0.0.zip.

Now the $LOCATION environment variable is set to that string. From that point on you can do with that variable whatever you like, in case you have another use than downloading the binary. Or, just like below, you can complete the download process:

curl -L -o csv2db.zip $LOCATION

invokes cURL and downloads $LOCATION into csv2db.zip. The -L parameter is important so that cURL follows the URL, i.e. redirect.

Hope this helps.