Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
One Liner to Download the Latest Release from Github Repo
  • Use curl to get the JSON response for the latest release
  • Use grep to find the line containing file URL
  • Use cut and tr to extract the URL
  • Use wget to download it
curl -s https://api.github.com/repos/jgm/pandoc/releases/latest \
| grep "browser_download_url.*deb" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi -
@qiwihui

This comment has been minimized.

Copy link

@qiwihui qiwihui commented Jul 30, 2017

可以只用 cut 分割:

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest \
| grep "browser_download_url.*deb" \
| cut -d '"' -f 4 \
| wget -qi -
@aaronnguyen

This comment has been minimized.

Copy link

@aaronnguyen aaronnguyen commented Aug 9, 2017

Wildcard didn't work on Docker ubuntu:latest
But this did. just broke out the greps.

curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest \
  | grep browser_download_url \
  | grep linux64 \
  | cut -d '"' -f 4 \
  | wget -qi -
@ozbillwang

This comment has been minimized.

Copy link

@ozbillwang ozbillwang commented Mar 1, 2018

why some repos supports releases, some not?

 curl -s https://api.github.com/repos/PyCQA/flake8/releases/latest
{
  "message": "Not Found",
  "documentation_url": "https://developer.github.com/v3/repos/releases/#get-the-latest-release"
}

@rlewkowicz

This comment has been minimized.

Copy link

@rlewkowicz rlewkowicz commented Mar 1, 2018

@ozbillwang I've noticed this when a repo is mirrored vs native to github

@w0rd-driven

This comment has been minimized.

Copy link

@w0rd-driven w0rd-driven commented Apr 18, 2018

In case anyone else stumbles upon this stupidly useful technique, the one thing that varies between projects is the grep line. browser_download_url.*deb looks for files ending in .deb. You likely need to tailor just this line for most repositories.

@JedMeister

This comment has been minimized.

Copy link

@JedMeister JedMeister commented May 28, 2018

This looks really cool, but as noted by @ozbillwang and @rlewkowicz it's not always reliable. It appears that it depends on how the Dev creates their "releases".

From what I can gather it should always be reliable for projects which provide specific binary file formats (e.g. .deb as per the OP). But may not be reliable for repos which just provide a source code tarball/zipball (and even if it is now, may not be in the future).

FWIW it seems that the difference is whether or not the dev explicitly creates a "Release" via GH (which is required to include specific binary formats). Everytime a repo is tagged, a new source code bundle will automagically show up on the GH "Releases" page. However, these automagic "releases" will not appear via the API, nor via the https://github.com/:owner/:repo/releases/latest URL. They will only be visible via the projects Release webpage and/or via the API under repos/:owner/:repo/tags. And unfortunately, it can't be assumed that the tags are in chronological order... 😢

@dsifford

This comment has been minimized.

Copy link

@dsifford dsifford commented Jun 28, 2018

Shorter PCRE grep: (just get's the version number)

curl -s https://api.github.com/repos/USER/REPO/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")'
@blockloop

This comment has been minimized.

Copy link

@blockloop blockloop commented Oct 5, 2018

I use jq

curl -sL https://api.github.com/repos/USER/REPO/releases/latest | jq -r '.assets[].browser_download_url'
@PizzaLovingNerd

This comment has been minimized.

Copy link

@PizzaLovingNerd PizzaLovingNerd commented Oct 11, 2018

Thanks

@Arezhik

This comment has been minimized.

Copy link

@Arezhik Arezhik commented Oct 12, 2018

curl -s https://api.github.com/repos/USER/REPO/releases/latest | jq -r ".assets[] | select(.name | contains(\"search param for specific download url\")) | .browser_download_url" | wget -i -

Then pass into wget also to download it.

@TaChao

This comment has been minimized.

Copy link

@TaChao TaChao commented Oct 19, 2018

curl --silent "https://api.github.com/repos/USER/REPO/releases/latest" | # Get latest release from GitHub api
    grep '"tag_name":' |                                                 # Get tag line
    sed -E 's/.*"([^"]+)".*/\1/' |
    xargs -I {} curl -sOL "https://github.com/USER/REPO/archive/"{}'.tar.gz'
@zwbetz-gh

This comment has been minimized.

Copy link

@zwbetz-gh zwbetz-gh commented Oct 21, 2018

Thanks for this @steinwaywhw. I used it to write a script to install the latest release of the Hugo binary.
See https://zwbetz.com/script-to-install-latest-hugo-release-on-linux-and-mac/ for the write-up.

#!/bin/bash

pushd /tmp/

curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest \
| grep "browser_download_url.*hugo_[^extended].*_Linux-64bit\.tar\.gz" \
| cut -d ":" -f 2,3 \
| tr -d \" \
| wget -qi -

tarball="$(find . -name "*Linux-64bit.tar.gz")"
tar -xzf $tarball

chmod +x hugo

mv hugo /usr/local/bin/

popd

location="$(which hugo)"
echo "Hugo binary location: $location"

version="$(hugo version)"
echo "Hugo binary version: $version"
@Inkimar

This comment has been minimized.

Copy link

@Inkimar Inkimar commented Oct 23, 2018

Glad to see the activity here.
I have a question, which more has to do with releases and 'the latest release'
Checking the mozilla/geckodriver-repo (thanks @aaronnguyen ) , https://github.com/mozilla/geckodriver/releases , which makes the following request possible : https://api.github.com/repos/mozilla/geckodriver/releases/latest
and comparing it to one of my own projects , https://github.com/Inkimar/cp_dina-collections/releases , where I cannot request the latest using https://api.github.com/repos/inkimar/cp_dina-collections/releases/latest
I can see that the the mozilla/geckodriver-repo has the tag 'latest release' on the left hand side in https://github.com/mozilla/geckodriver/releases where my repos does not have it https://github.com/Inkimar/cp_dina-collections/releases .
I am pushing to my repo using the following 'git push && git push --tags && rm -rf build/temp ' and I get asked a question on the release ( patch, minor or major) ....
My Q: how can I get the tag 'latest release' so that I can use the same request as to the mozilla/geckodriver ?

-i

@dkebler

This comment has been minimized.

Copy link

@dkebler dkebler commented Nov 8, 2018

@zwbetz-gh thx. Set it up so one can run it without preface of sudo and included a check of current version vs installed first and then proceed on new release. One could do this as a daily cron job and one would always be running the latest release (if that was the goal).

Another improvement would be the check the system architecture and install the correct one (not just the amd 64)

Looks like u already post this to hugo discourse https://discourse.gohugo.io/t/script-to-install-latest-hugo-release-on-macos-and-ubuntu/14774/8 :-)

#!/bin/bash

CUR_VERSION="$(hugo version | cut -d'v' -f2 | cut -c 3-5)"
NEW_VERSION="$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name | cut -d'.' -f2 | cut -d'"' -f1)"
echo "Current Version: $CUR_VERSION => New Version: $NEW_VERSION"

if [ "$NEW_VERSION" -ne "$CUR_VERSION" ]; then

  echo "Installing version $NEW_VERSION"

  pushd /tmp/

  curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest \
  | grep "browser_download_url.*hugo_[^extended].*_Linux-64bit\.tar\.gz" \
  | cut -d ":" -f 2,3 \
  | tr -d \" \
  | wget -qi -

  tarball="$(find . -name "*Linux-64bit.tar.gz" 2>/dev/null)"
  tar -xzf $tarball

  chmod +x hugo

  sudo mv hugo /usr/local/bin/

  popd

  location="$(which hugo)"
  echo "Hugo binary location: $location"

  version="$(hugo version)"
  echo "New Hugo binary version installed!: $version"

else
  echo Latest version already installed
fi

@zwbetz-gh

This comment has been minimized.

Copy link

@zwbetz-gh zwbetz-gh commented Nov 8, 2018

@dkebler 👍

@drmikecrowe

This comment has been minimized.

Copy link

@drmikecrowe drmikecrowe commented Nov 13, 2018

Thanks to @blockloop for the jq hint. Here's what I came up with (checks for binary with linux-amd64 in the name):

function get_download_url {
	wget -q -nv -O- https://api.github.com/repos/$1/$2/releases/latest 2>/dev/null |  jq -r '.assets[] | select(.browser_download_url | contains("linux-amd64")) | .browser_download_url'
}

Usage: get_download_url 99designs aws-vault

Followed with:

function install_binary {
	URL=$(get_download_url $1 $2)
	mkdir -p ~/bin
	BASE=$(basename $URL)
	wget -q -nv -O $BASE $URL 
	if [ ! -f $BASE ]; then
		echo "Didn't download $URL properly.  Where is $BASE?"
		exit 1	
	fi
	mv $BASE ~/bin
	chmod +x ~/bin/$BASE
}

Usage: install_binary 99designs aws-vault

@evankanderson

This comment has been minimized.

Copy link

@evankanderson evankanderson commented Jan 7, 2019

Note that "latest release" will only work if the release is not tagged as a "draft" or "prerelease". For repos which are still under development, you might want to fetch /releases and then use the most recent one:

curl -s https://api.github.com/repos/$1/$2/releases | \
  jq ".[0].assets | map(select(.name == \"$3\")) | .[0].browser_download_url"
@oddlots

This comment has been minimized.

Copy link

@oddlots oddlots commented Jan 9, 2019

Thanks @TaChao

It's a little beyond the scope of this but I have also added a | tar -xz --strip-components=1 -C target/dir in order to facilitate a one liner update of a library.

@agustif

This comment has been minimized.

Copy link

@agustif agustif commented Feb 9, 2019

curl -s https://api.github.com/repos/user/repo/releases/latest |
grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d '"' | wget -qi -

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Feb 21, 2019

curl -s https://api.github.com/repos/user/repo/releases | jq ".[0].assets | .[].browser_download_url" | grep $(lsb_release -cs) | grep $([[ $(arch) == x86_64 ]] && echo amd64 || echo i386) | sed 's/"//g'

note: trying to find better solution for arch.

@josh

This comment has been minimized.

Copy link

@josh josh commented Feb 22, 2019

Heh, this was bugging me how tricky it was to do as well. I just added a new redirect so https://github.com/user/repo/releases/latest/download/foo.zip redirects to the latest tagged asset. Hope it's handy!

@derekbekoe

This comment has been minimized.

Copy link

@derekbekoe derekbekoe commented Feb 24, 2019

Thanks @josh!

@aaronliu0130

This comment has been minimized.

Copy link

@aaronliu0130 aaronliu0130 commented Mar 10, 2019

how do I find a specific link when there are multiple releases?

@bgokden

This comment has been minimized.

Copy link

@bgokden bgokden commented Mar 13, 2019

Heh, this was bugging me how tricky it was to do as well. I just added a new redirect so https://github.com/user/repo/releases/latest/download/foo.zip redirects to the latest tagged asset. Hope it's handy!

This works for us. I wrote a small script to install binary locally:

base=https://github.com/magneticio/forklift/releases/latest/download &&
  curl -L $base/forklift-$(uname -s)-$(uname -m) >/usr/local/bin/forklift &&
  chmod +x /usr/local/bin/forklift
@ReSearchITEng

This comment has been minimized.

Copy link

@ReSearchITEng ReSearchITEng commented Mar 15, 2019

For anyone interested how to do that with ansible, see below.

  vars:
    k8s_ver: "v1.13.1"
  tasks:
    - name: limit k8s_ver to vMajor.Minor
      set_fact:
        k8s_ver_major_minor: "{{k8s_ver | regex_replace('^v([0-9])\\.([0-9]*).*', 'v\\1.\\2') }}"

    - name: get all releases as json file
      get_url:
        url: "https://api.github.com/repos/ReSearchITEng/kubeadm-playbook/releases"
        dest: /tmp/all.releases.json
        force: yes

    - name: parse releases json
      command: cat /tmp/all.releases.json
      register: allreleases

    - name: download the targz
      get_url:
        url: '{{allreleases.stdout_lines[0] | from_json | json_query(query) | join ("") }}'
        dest: /tmp/sourcesofthedesiredrelease.tar.gz
        force: yes
      vars:
        query: "[?name=='{{k8s_ver_major_minor}}'].tarball_url"

For getting the tar.gz of the latest release, the above would become more simple.

@mweibel

This comment has been minimized.

Copy link

@mweibel mweibel commented Mar 19, 2019

I just released https://gitreleases.dev/ which solves this issue with a simple URL.

@rpdelaney

This comment has been minimized.

Copy link

@rpdelaney rpdelaney commented Mar 25, 2019

@mweibel Very cool, but what if the release asset has an unpredictable name? For instance, have a look at https://github.com/funtoo/keychain/releases/latest

@coocheenin

This comment has been minimized.

Copy link

@coocheenin coocheenin commented Mar 27, 2019

Everytime a repo is tagged, a new source code bundle will automagically show up on the GH "Releases" page. However, these automagic "releases" will not appear via the API

@JedMeister I can confirm this. Sad, but true.

@mweibel

This comment has been minimized.

Copy link

@mweibel mweibel commented Mar 28, 2019

@rpdelaney (sorry, somehow I didn't get a notification for this comment?)

@mweibel Very cool, but what if the release asset has an unpredictable name? For instance, have a look at https://github.com/funtoo/keychain/releases/latest

There are two possible things here:
a) Release doesn't contain a release asset but only the automatically generated one by GitHub (tarball, zipball)
b) Release contains a release asset which contains the version in the filename again (e.g. in the linked example a possibility would be keychain_2.8.5.zip)

Both are currently not well supported by gitreleases, but I plan to support them: mweibel/gitreleases#2 and mweibel/gitreleases#3.
Feel free to comment on those issues or open new issues 👍

@jhuckaby

This comment has been minimized.

Copy link

@jhuckaby jhuckaby commented Apr 17, 2019

For those that may have missed it above, @josh from GitHub released an official fix for this:

https://gist.github.com/steinwaywhw/a4cd19cda655b8249d908261a62687f8#gistcomment-2845270

Heh, this was bugging me how tricky it was to do as well. I just added a new redirect so https://github.com/USER/REPO/releases/latest/download/FILENAME.zip redirects to the latest tagged asset. Hope it's handy!

This works perfectly for me. Just replace USER, REPO and FILENAME with your own stuff.

@loganmarchione

This comment has been minimized.

Copy link

@loganmarchione loganmarchione commented Apr 17, 2019

@josh thank you! This works perfectly!

@hartmannr76

This comment has been minimized.

Copy link

@hartmannr76 hartmannr76 commented Apr 18, 2019

@josh Doesn't seem to work if the repo is private. I've tried providing Basic and Token as an auth header and keep getting a 404. Would love to use this though!!

@kurtroberts

This comment has been minimized.

Copy link

@kurtroberts kurtroberts commented Apr 30, 2019

Here's a version that uses python to parse the JSON, in case you don't have jq available (like working with tools installed by default on macOS):

curl -s https://api.github.com/repos/sheagcraig/yo/releases/latest |  python -c 'import json,sys;obj=json.load(sys.stdin);print obj["assets"][0]["browser_download_url"];'
@joaovitor

This comment has been minimized.

Copy link

@joaovitor joaovitor commented May 14, 2019

curl -sL https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/latest | \
grep "releases/download.*linux_amd64" | \
cut -d \" -f 2 | \
tr -d \" | \
sed -e 's#.*download/v\(.*\)/aws-iam-authenticator.*#\1#g'
@dvershinin

This comment has been minimized.

Copy link

@dvershinin dvershinin commented May 17, 2019

This is all too weak you guys. As mentioned by many - GitHub API won't return actual Releases in many cases when releases were not filed formally. Those releases that don't appear are not less releases than the others :)

Thus I have created lastversion CLI tool.

How about this one liner:

lastversion user/repo 

Will give you the version of latest release even if it's not present in the API response! :)

@Contextualist

This comment has been minimized.

Copy link

@Contextualist Contextualist commented May 23, 2019

For anyone who don't bother installing extra dependencies or crafting multi-line commands, try my handy service get latest release:

curl -fLO https://glare.now.sh/<user>/<repo>/<asset_regex>

e.g.

curl -fLO https://glare.now.sh/jgm/pandoc/deb

Why?

  • Succinct and maintainable
  • Match asset names containing version numbers with regex
@vojtech2

This comment has been minimized.

Copy link

@vojtech2 vojtech2 commented May 27, 2019

Possibly also an option:

git ls-remote --tags https://github.com/jgm/pandoc.git | sed -nE 's#.*refs/tags/(v?[0-9]+(\.[0-9]+)*)$#\1#p' | sort -Vr | head -n 1

See https://stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning

@Puvipavan

This comment has been minimized.

Copy link

@Puvipavan Puvipavan commented Jul 10, 2019

curl -s https://api.github.com/repos/cloud-custodian/cloud-custodian/releases/latest | sed -n 's/.*tag_name":\s"\(.*\)".*/\1/p' | head -1

@steinwaywhw

This comment has been minimized.

Copy link
Owner Author

@steinwaywhw steinwaywhw commented Jul 10, 2019

Wow, thank you so much for all the comments/tips/improvements. I didn't even notice until today. You're awesome ❤️

@evandrix

This comment has been minimized.

Copy link

@evandrix evandrix commented Jul 13, 2019

wget -c $(curl -ksL "https://api.github.com/repos/x64dbg/x64dbg/releases/latest" | jq -r ".assets[0].browser_download_url")

@fakuivan

This comment has been minimized.

Copy link

@fakuivan fakuivan commented Aug 2, 2019

Expanding on @evandrix's answer

curl -s https://api.github.com/repos/pyrovski/wrtbwmon/releases | \
  jq -r '[[.[] |
    select(.draft != true) |
    select(.prerelease != true)][0] |
    .assets |
    .[] |
    select(.name | endswith(".ipk")) |
    .browser_download_url][0]'
@xerus2000

This comment has been minimized.

Copy link

@xerus2000 xerus2000 commented Aug 4, 2019

Much simpler: curl -s https://api.github.com/repos/user/repo/releases/latest | grep -o "http.*deb"

Now in my .zshrc (works just as well with bash):

# Gets the download url for the latest release of a package provided via GitHub Releases
# Usage: ghrelease USER REPO [PATTERN]
ghrelease() {
	curl -s "https://api.github.com/repos/$1/$2/releases/latest" | grep -o "http.*${3:-deb}"
}

Perfect pair with:

# Installs a local or remote(http/https) deb package and removes it after installation
installdeb() {
	set -e
	loc="/tmp/install.deb"
	case $1 in 
	http*) sudo wget -O "$loc" $1;;
	*) loc="$1"
	esac
	sudo dpkg -i "$loc"
	sudo apt -f install
	sudo rm -f "$loc"
}

Example use: installdeb $(ghrelease sharkdp bat "bat_.*_amd64.deb")
Perfect 👌

@koddsson

This comment has been minimized.

Copy link

@koddsson koddsson commented Aug 28, 2019

Hey hey!

This feature has been added to github, see https://help.github.com/en/articles/linking-to-releases#linking-to-the-latest-release

If you'd like to link directly to a download of your latest release asset you can link to /owner/name/releases/latest/download/asset-name.zip.

Example: curl -L https://github.com/primer/octicons/releases/latest/download/svg.zip

@archf

This comment has been minimized.

Copy link

@archf archf commented Oct 8, 2019

My attempt to solve this: ghi.

It aims to be the reverse operation of ghr CLI tool. More improvements can be done of course. Let me know what you think!

@jaekyeom

This comment has been minimized.

Copy link

@jaekyeom jaekyeom commented Oct 12, 2019

Hey hey!

This feature has been added to github, see https://help.github.com/en/articles/linking-to-releases#linking-to-the-latest-release

If you'd like to link directly to a download of your latest release asset you can link to /owner/name/releases/latest/download/asset-name.zip.

Example: curl -L https://github.com/primer/octicons/releases/latest/download/svg.zip

That's great, but can we get the link to the tarball/zipball of the latest release, too?

@yngvark

This comment has been minimized.

Copy link

@yngvark yngvark commented Nov 8, 2019

VERSION=$(curl -s https://github.com/Versent/saml2aws/releases/latest/download 2>&1 | grep -Po [0-9]+\.[0-9]+\.[0-9]+)
echo version: $VERSION
wget https://github.com/Versent/saml2aws/releases/latest/download/saml2aws_$VERSION\_linux_amd64.tar.gz
@contributorpw

This comment has been minimized.

Copy link

@contributorpw contributorpw commented Nov 22, 2019

bazelbuild/bazel .sh for linux

curl -s https://api.github.com/repos/bazelbuild/bazel/releases/latest \
| grep "browser_download_url.*linux.*sh\"" \                               
| cut -d : -f 2,3 \                 
| tr -d \" \       
| wget -qi - 
@ryuta69

This comment has been minimized.

Copy link

@ryuta69 ryuta69 commented Mar 2, 2020

For those who installed fzf, I use this alias every time. It's quick and clear.

function dlgr() {
	URL=`curl -s "${@}" | grep "browser_download_url" | cut -d '"' -f 4 | fzf`
	curl -O ${URL}
}

It's same as this one liner.

curl -s https://api.github.com/repos/bazelbuild/bazel/releases/latest \
	| grep "browser_download_url" \       
	| cut -d '"' -f 4 \                 
	| fzf \       
	| curl -O
@gmolveau

This comment has been minimized.

Copy link

@gmolveau gmolveau commented Mar 4, 2020

To download the latest .tar.gz release using only curl :

curl -s https://api.github.com/repos/<user>/<repo>/releases/latest \
| grep 'browser_download_url.*tar.gz"' \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -n 1 curl -O -sSL

and if you want to download + extract in the current folder :

curl -s https://api.github.com/repos/<user>/<repo>/releases/latest \
| grep 'browser_download_url.*tar.gz"' \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -n 1 curl -sSL \
| tar -xz --strip-components=1
@miguelslemos

This comment has been minimized.

Copy link

@miguelslemos miguelslemos commented Mar 9, 2020

curl -s "https://api.github.com/repos/<user>/<repo>/releases/latest?access_token=$GITHUB_TOKEN" \
    | jq '.assets[] | select(.name == "mob-macos.tar.gz") | .url' \
    | xargs -I {} curl -sSL -H 'Accept: application/octet-stream' "{}?access_token=$GITHUB_TOKEN" \
    | tar -xzf -
@x5engine

This comment has been minimized.

Copy link

@x5engine x5engine commented Apr 5, 2020

just send the release to ipfs and download it instead of adding the accesstoken..

@skillfr

This comment has been minimized.

Copy link

@skillfr skillfr commented Apr 19, 2020

In case there are multiple files

v=$(wget -q https://api.github.com/repos/<user>/<repo>/releases/latest -O - | grep -E tag_name | awk -F '[""]' '{print $4}') wget https://github.com/<user>/<repo>/releases/download/$v/file.linuxAMDx64.tar.gz

or

wget https://github.com/<user>/<repo>/releases/download/$v/file.linuxARMx32.tar.gz

@aslafy-z

This comment has been minimized.

Copy link

@aslafy-z aslafy-z commented Apr 23, 2020

My 2 cents

wget -q -O - --header "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/<user>/<repo>/releases/latest" \
    | python -c 'import sys, json; print(json.load(sys.stdin)["tarball_url"])' \
    | xargs -I {} wget -q -O - --header "Authorization: token $GITHUB_TOKEN"  "{}" \
    | tar -xz --strip-components=1

Comes with a bonus:

sudo tar --strip=1 --transform "s/original_folder/new_name_folder/" --wildcards -C /usr/local/share/ca-certificates -xzf - "*/original_folder"
# outputs to /usr/local/share/ca-certificates/new_name_folder
@chris-gillatt

This comment has been minimized.

Copy link

@chris-gillatt chris-gillatt commented Apr 30, 2020

For anyone else who lands on this thread wanting to solve this problem for either this app or others, I've resorted to using a one/two-liner consisting of a simple grep and a not-so-simple (but robust) perl expression to extract semvers. If you really wanted to expand this, you could use positional parameters for the asset type.

#!/bin/bash -e

LATEST=$(curl -sL --fail https://api.github.com/repos/jgm/pandoc/releases/latest | grep "tag_name" | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}') ; curl -vsL "https://github.com/jgm/pandoc/releases/download/$LATEST/pandoc-$LATEST-macOS.zip" -O
@Evidlo

This comment has been minimized.

Copy link

@Evidlo Evidlo commented May 1, 2020

This isn't necessary anymore as Github has a direct link to the latest release:

https://github.com/[user]/[repo]/releases/latest/download/[asset-name.zip]

https://help.github.com/en/github/administering-a-repository/linking-to-releases

@chris-gillatt

This comment has been minimized.

Copy link

@chris-gillatt chris-gillatt commented May 4, 2020

@Evidlo - Did you actually try following that? It only works if you do it manually. This entire thread is about automating the problem.

@Evidlo

This comment has been minimized.

Copy link

@Evidlo Evidlo commented May 6, 2020

@chris-gill

Yes, it works for me. E.g. https://github.com/evidlo/remarkable_news/releases/latest/download/release.zip

I'm not sure what you mean by 'do it manually'.

Of course it doesn't work if the asset name changes between releases, so I guess it's not useful for Pandoc.

@chris-gillatt

This comment has been minimized.

Copy link

@chris-gillatt chris-gillatt commented May 7, 2020

@Evidlo Ahh - that's the thing then - with many project releases including some of my own, the assets are named with the version in the filename string, meaning that the name changes with each release like can be seen here:
https://github.com/jgm/pandoc/releases/

The automation problem arises there, meaning we need 1/2 lines of bash to get $latest of those files.
What I mean by manually, is that you can still do this by following the steps on the page you provided, but only manually through the GUI and clicking the link to the file to download it.

@codedge

This comment has been minimized.

Copy link

@codedge codedge commented May 26, 2020

This one works for me:

curl -LJO https://github.com/[user]/[repo]/tarball/[tag]
@MaluNoPeleke

This comment has been minimized.

Copy link

@MaluNoPeleke MaluNoPeleke commented Jun 5, 2020

How to handle cases where the latest release is for an older version (e.g. v2.x maintenance update) but you always want to get latest release of the current version (highest version number).
One example is this repository (2.38.2 has been released lately but 3.18.1 is the latest): https://github.com/TryGhost/Ghost/releases

@Contextualist

This comment has been minimized.

Copy link

@Contextualist Contextualist commented Jun 5, 2020

@MaluNoPeleke Shamelessly promoting my own project https://github.com/Contextualist/glare . You can use semver matching for releases.

# To get the latest 3.x:
curl -L https://glare.now.sh/TryGhost/Ghost@3.x/Ghost -o ghost.zip
# To get the latest 2.x:
curl -L https://glare.now.sh/TryGhost/Ghost@2.x/Ghost -o ghost.zip
# Highest version, whatever:
curl -L https://glare.now.sh/TryGhost/Ghost@x/Ghost -o ghost.zip
@eggbean

This comment has been minimized.

Copy link

@eggbean eggbean commented Jun 5, 2020

For those who installed fzf, I use this alias every time. It's quick and clear.

function dlgr() {
	URL=`curl -s "${@}" | grep "browser_download_url" | cut -d '"' -f 4 | fzf`
	curl -O ${URL}
}

I like that, but it doesn't download the correct file when I try. It seems you need to add the -L switch, due to redirects. This is what I am using, only requiring USER/REPO.

dlgr ()
{
    URL=$(curl -s https://api.github.com/repos/"${@}"/releases/latest   | jq -r '.assets[].browser_download_url' | fzf);
    curl -LO ${URL}
}
@MaluNoPeleke

This comment has been minimized.

Copy link

@MaluNoPeleke MaluNoPeleke commented Jun 5, 2020

@Contextualist I would rather use direct features of shell and GitHub instead of relying on another service and if possible have also a generic solution instead of a hard-coded version number but thanks for your quick support.

@iofirag

This comment has been minimized.

Copy link

@iofirag iofirag commented Aug 31, 2020

  curl -s https://api.github.com/repos/<user-name>/<repo-name>/releases/latest \
    | grep browser_download_url \
    | cut -d '"' -f 4 \
    | wget -qi-
  tarfilename="$(find . -name "*.tar.gz")"
  tar -xzf $tarfilename
  sudo rm $tarfilename
@jwillikers

This comment has been minimized.

Copy link

@jwillikers jwillikers commented Sep 17, 2020

Long live awk! 😉

$ curl -s https://api.github.com/repos/<user>/<repo>/releases/latest \
    | awk -F': '  '/browser_download_url/ && /\.<extension>/ {gsub(/"/, "", $(NF)); system("curl -LO " $(NF))}'

Just substitute in the user or organization name, the project's name, and the desired file extension for the <user>, <repo>, and <extension> fields respectively.
It's also easy enough to modify the match pattern for the file extension to make it more specific if need be.

@unfor19

This comment has been minimized.

Copy link

@unfor19 unfor19 commented Sep 19, 2020

No dependencies are needed, plain simple Bash and curl

  1. Get the latest version - Assuming the versioning format is - "v0.0.1"
    If the version format is different from "v0.0.1" then change the cut -d'v' -f2 section
ORG_NAME=hashicorp
REPO_NAME=terraform
LATEST_VERSION=$(curl -s https://api.github.com/repos/${ORG_NAME}/${REPO_NAME}/releases/latest | grep "tag_name" | cut -d'v' -f2 | cut -d'"' -f1)

# Output: 0.13.3
  1. Download the latest version
curl -L -o ${REPO_NAME}.tar.gz https://github.com/${ORG_NAME}/${REPO_NAME}/archive/v${LATEST_VERSION}.tar.gz

It's not a oneliner, but it's how I use it in a Dockerfile, I hope it helps

@maggie0002

This comment has been minimized.

Copy link

@maggie0002 maggie0002 commented Sep 27, 2020

So many ways to skin a cat.

Retrieving source files:

A shell script, incorporating authentication in order to access private repositories and use tag-name based retrieval to fetch a .tar from the latest release for when browser_download_url isn't available (browser_download_url won't be in the api output if only the standard tar and zip archives are available in your release).

Ensure jq is installed on the system running the script:

#!/usr/bin/env bash
USER_NAME=your-user-name
REPO_NAME=your-repo-name
TOKEN=your-token # To generate a token see: https://docs.github.com/en/enterprise/2.15/user/articles/creating-a-personal-access-token-for-the-command-line

curl -H "Authorization: token ${TOKEN}" https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/releases/latest | jq -r .tag_name |
xargs -I {} curl -H "Authorization: token ${TOKEN}" -sSL https://github.com/${USER_NAME}/${REPO_NAME}/archive/{}.tar.gz |
tar -xzf - --strip-components=1

Retrieve binaries:

A shell script to fetch the latest release when binary files are available, in a private repository.

Ensure jq is installed.

Script may need modification if there is more than one binary file as at the moment it will only fetch the first.

#!/usr/bin/env bash

USER_NAME=your-user-name
REPO_NAME=your-repo-name
TOKEN=your-token # To generate a token see: https://docs.github.com/en/enterprise/2.15/user/articles/creating-a-personal-access-token-for-the-command-line

ASSET_ID=$(curl -H "Authorization: token ${TOKEN}" https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/releases/latest | jq .assets[0].id); \
curl -H "Authorization: token ${TOKEN}" https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/releases/assets/${ASSET_ID} -LJOH 'Accept: application/octet-stream'
@sebma

This comment has been minimized.

Copy link

@sebma sebma commented Oct 2, 2020

@ryuta69

This comment has been minimized.

Copy link

@ryuta69 ryuta69 commented Oct 2, 2020

@sebma
yes

@hongkongkiwi

This comment has been minimized.

Copy link

@hongkongkiwi hongkongkiwi commented Oct 19, 2020

I needed something one liner with no external tools but also cross platform this works:
VERSION=$(curl -s "https://github.com/cloudposse/tfmask/releases/latest/download" 2>&1 | sed "s/^.*download\/\([^\"]*\).*/\1/")

For those using this in a docker to download files, here's a nice snippet which can handle either setting the version manually via build argument or if blank will auto find the latest version:

ARG TFMASK_VERSION=
ARG PLATFORM_ARCH=amd64

RUN if [ -z $TFMASK_VERSION ]; then echo "Finding latest TFMask Version..."; TFMASK_VERSION=$(curl -s "https://github.com/cloudposse/tfmask/releases/latest/download" 2>&1 | sed "s/^.*download\/\([^\"]*\).*/\1/"); else echo "TFMask version passed in build argument v${TFMASK_VERSION}"; fi && \
    echo "Downloading TFMask v${TFMASK_VERSION}..." && \
    curl -sLo "/usr/bin/tfmask" "https://github.com/cloudposse/tfmask/releases/download/${TFMASK_VERSION}/tfmask_linux_${PLATFORM_ARCH}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.