Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Shell - Get latest release from GitHub
get_latest_release() {
curl --silent "https://api.github.com/repos/$1/releases/latest" | # Get latest release from GitHub api
grep '"tag_name":' | # Get tag line
sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value
}
# Usage
# $ get_latest_release "creationix/nvm"
# v0.31.4
@hiulit

This comment has been minimized.

Copy link

commented Dec 18, 2017

Nice one! Thanks!

@santimendoza

This comment has been minimized.

Copy link

commented Jan 16, 2018

If you are in the repo, you can simply use: git tag | tail -1. Maybe you need to do a git fetch --tags before :).

But your approach is a good trick.

@peschu123

This comment has been minimized.

Copy link

commented Apr 11, 2018

Hi,
I made a version without sed, only using grep.
Maybe its useful...

curl --silent "https://api.github.com/repos/$1/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")'

Thanks, for sharing the great idea! 👍

@jbelloncastro

This comment has been minimized.

Copy link

commented Apr 30, 2018

Another alternative:
curl --silent "https://api.github.com/repos/$1/releases/latest" | jq -r .tag_name

You can also get the download link directly:
jq -r '.assets[0].browser_download_url
or by name:
jq -r '.assets[] | select(.name == "nameofobject").browser_download_url')
(replace nameofobject with whatever you want to get).

@robwithhair

This comment has been minimized.

Copy link

commented Jul 17, 2018

To get latest tag, for example if the repo doesn't utilise GitHub releases.

function get_latest_release() {
    curl --silent "https://api.github.com/repos/certbot/certbot/tags" | jq -r '.[0].name'
}
@espoelstra

This comment has been minimized.

Copy link

commented Jul 19, 2018

I combined all the resources I found on the subject to come up with a one-liner to grab docker-compose assuming you have jq installed.

curl --silent "https://api.github.com/repos/docker/compose/releases/latest" | jq --arg PLATFORM_ARCH "$(echo `uname -s`-`uname -m`)" -r '.assets[] | select(.name | endswith($PLATFORM_ARCH)).browser_download_url' | xargs sudo curl -L -o /usr/local/bin/docker-compose --url

This could easily be put into a function where you pass the name of the repository and the platform or architecture you want to download. Sadly for a lot of releases it could be anything, ie amd64, x86_64, i386, i586, i686, or others depending on the packaging tool they used. You can use select(.name | test "Linux*64") or some similar regex in that case to get pretty close, or just return a list of releases and have the user select the one they want via ncurses/zenity/etc.

@haruo31

This comment has been minimized.

Copy link

commented Sep 25, 2018

Thanks a lot!! It worked perfectly on my problem!! I made a shell function to find assets of latest release that will work with python 3.x.

getLatest() {
  REPO=$1
  SUFFIX=$2
  curl --silent https://api.github.com/repos/$REPO/releases/latest | \
    python -c "import sys; from json import loads as l; x = l(sys.stdin.read()); print(''.join(s['browser_download_url'] for s in x['assets'] if s['name'].endswith('.$SUFFIX')))"
}
@HaleTom

This comment has been minimized.

Copy link

commented Oct 15, 2018

Can be done with git ls-remote and sed too.

@chrcoluk

This comment has been minimized.

Copy link

commented Nov 2, 2018

only the original is valid

if I try all the others I get "jq not found", jq is more bloated than sed so I dont see the logic in replacing sed with jq

-P is invalid flag for grep

The problem with the original is it outputs with v at the start which needs removing, otherwise its perfect.

append this to end cut -c 2-

curl --silent "https://api.github.com/repos/$1/releases/latest" | # Get latest release from GitHub api grep '"tag_name":' | # Get tag line sed -E 's/.*"([^"]+)".*/\1/' | # Pluck JSON value cut -c 2- # Remove v

@NathanUrwin

This comment has been minimized.

Copy link

commented Nov 13, 2018

See https://stackoverflow.com/questions/3074288/get-url-after-curl-is-redirected

An easier way:

$ curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/hadolint/hadolint/releases/latest && echo
https://github.com/hadolint/hadolint/releases/tag/v1.15.0
@mathieu-aubin

This comment has been minimized.

Copy link

commented Nov 16, 2018

@chrcoluk

if I try all the others I get "jq not found" ....

That's because it's not installed or in your $PATH

... jq is more bloated than sed so I dont see the logic in replacing sed with jq

jq is BY FAR alot more efficient than anything else at processing JSON.

-P is invalid flag for grep

From grep --help:

  -P, --perl-regexp         PATTERN is a Perl regular expression

PCRE - Perl Compatible Regular Expressions

The problem with the original is it outputs with v at the start which needs removing, otherwise its perfect.

How would that be a problem? Im curious.

append this to end cut -c 2-

Using cut makes alot less sense than the above quotes

From @peschu123 Post's

grep -Po '"tag_name": "\K.*?(?=")'

to

grep -Po '"tag_name": "v\K.*?(?=")'

A single character gets rid of your ennemy.

curl --silent "https://api.github.com/repos/$1/releases/latest" | # Get latest release from GitHub api grep '"tag_name":' | # Get tag line sed -E 's/.*"([^"]+)".*/\1/' | # Pluck JSON value cut -c 2- # Remove v

By the looks of this one, it also seems you could use a Markdown syntax refresher course, dear sysadmin

@oslivan

This comment has been minimized.

Copy link

commented Nov 30, 2018

Very nice.

@hoto

This comment has been minimized.

Copy link

commented Dec 14, 2018

Perfect. Thanks.

@Zeka13

This comment has been minimized.

Copy link

commented Dec 24, 2018

awesome

@paulequilibrio

This comment has been minimized.

Copy link

commented Dec 24, 2018

See https://stackoverflow.com/questions/3074288/get-url-after-curl-is-redirected

An easier way:

$ curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/hadolint/hadolint/releases/latest && echo
https://github.com/hadolint/hadolint/releases/tag/v1.15.0

Thanks a lot for that!

@wweir

This comment has been minimized.

Copy link

commented Jan 19, 2019

curl -s "https://api.github.com/repos/$REPO/releases/latest" | awk -F '"' '/tag_name/{print $4}'

@vwal

This comment has been minimized.

Copy link

commented Jan 30, 2019

Anyone know why this doesn't work on aws/aws-cli releases? It has releases, but

curl "https://api.github.com/repos/aws/aws-cli/releases/"

produces:

{
  "message": "Not Found",
  "documentation_url": "https://developer.github.com/v3/repos/releases/#get-the-latest-release"
}
@dan-compton

This comment has been minimized.

Copy link

commented Feb 3, 2019

@wval

curl "https://api.github.com/repos/aws/aws-cli/tags" | jq '.[].name'          
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--100 12643  100 12643    0     0  17366      0 --:--:-- --:--:-- --:--:-- 17366
"2.0.0dev0"
"1.16.96"
"1.16.95"
"1.16.94"
"1.16.93"
"1.16.92"
"1.16.91"
"1.16.90"
"1.16.89"
"1.16.88"
"1.16.87"
"1.16.86"
"1.16.85"
"1.16.84"
"1.16.83"
"1.16.82"
"1.16.81"
"1.16.80"
"1.16.79"
"1.16.78"
"1.16.77"
"1.16.76"
"1.16.75"
"1.16.74"
"1.16.73"
"1.16.72"
"1.16.71"
"1.16.70"
"1.16.69"
"1.16.68"
@nouchka

This comment has been minimized.

Copy link

commented Feb 4, 2019

@maboloshi

This comment has been minimized.

Copy link

commented Feb 17, 2019

get_latest_release_number() {
  curl --silent "https://github.com/$1/releases/latest" | sed 's#.*tag/\(.*\)\".*#\1#'
}

# Usage
# $ get_latest_release_number "creationix/nvm"
# v0.34.0
@michaeltryby

This comment has been minimized.

Copy link

commented Mar 5, 2019

Windows cmd no dependencies ...

FOR /F delims^=^"^ tokens^=2 %%g IN ('curl --silent %LATEST_URL%') DO ( set "LATEST_TAG=%%~nxg" )

@bitmvr

This comment has been minimized.

Copy link

commented Mar 6, 2019

A more pure approach with no dependencies on jq.

Replace ${user} with the user/organization name and ${repository} with the project name in the one-liner below.

latest_tag_url=$(curl -sI https://github.com/${user}/${repository}/releases/latest | grep -iE "^Location:"); echo "${latest_tag_url##*/}"

What is it doing?

That "location url" is a part of the header, so I pass -I to get the headers and then grep for Location:. This provides the url for the latest tag. I wrapped the entire curl and grep operations to perform command substitution and assign it with a variable of latest_tag_url. I then echo the latest_tag_url variable and perform substring removal to show only the tag at the end of the url.

Real Example:

> latest_tag_url=$(curl -sI https://github.com/stedolan/jq/releases/latest | grep -iE "^Location:"); echo "${latest_tag_url##*/}"
jq-1.6
@michaeltryby

This comment has been minimized.

Copy link

commented Mar 7, 2019

This is a bit cleaner ...
LATEST_TAG="$(curl -sI "${LATEST_URL}" | grep -Po 'tag\/\K(v\S+)')"

@randygrolemund

This comment has been minimized.

Copy link

commented Mar 31, 2019

How about getting the release date information? I am trying to get version, and release date. I've got the version number parsed and cleaned up. Can someone please point me in the right direction?

@dvershinin

This comment has been minimized.

Copy link

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! :)

@3Dcube

This comment has been minimized.

Copy link

commented Jun 12, 2019

# Get final URL after curl is redirected
RELEASE_URL=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/docker/compose/releases/latest)
# Extract tag after the last forward slash 
TAG="${RELEASE_URL##*/}"
@Firedrops

This comment has been minimized.

Copy link

commented Jun 25, 2019

Thanks a lot!! It worked perfectly on my problem!! I made a shell function to find assets of latest release that will work with python 3.x.

getLatest() {
  REPO=$1
  SUFFIX=$2
  curl --silent https://api.github.com/repos/$REPO/releases/latest | \
    python -c "import sys; from json import loads as l; x = l(sys.stdin.read()); print(''.join(s['browser_download_url'] for s in x['assets'] if s['name'].endswith('.$SUFFIX')))"
}

I have adapted this code for one of my use cases, in which the criteria to select for is the ".tgz" extension (as opposed to .zip etc for windows).

curl -s "https://api.github.com/repos/beast-dev/beast-mcmc/releases/latest" | jq --arg PLATFORM_ARCH "tgz" -r '.assets[] | select(.name | endswith($PLATFORM_ARCH)).browser_download_url' | xargs curl -L -o /beast1.tgz

This works as expected and downloads the release as beast1.tgz.

However, another use case is more complicated, its releases have many versions, separated by format (e.g. .tgz .zip) and inclusion of JRE. I'm trying to select for the .tgz WITHOUT JRE, which is denoted in the middle of the string (BEAST_with_JRE.v2.5.2.Linux.tgz vs BEAST.v2.5.2.Linux.tgz). I've attempted to use the wildcard, i.e. PLATFORM_ARCH "BEAST.v*.tgz" but this does not work. I've tried Googling "curl select endswith" to try and find the 'language' to find alternatives to 'endswith', but all I get are java methods which don't fit with this format.

Could anyone please give me a little hand here and point me in the right direction?

@andrew-aladev

This comment has been minimized.

Copy link

commented Aug 22, 2019

Another variant that helps to install last version of dxvk before running Steam:

#!/bin/sh

archive_path="/tmp/dxvk"
mkdir -p "$archive_path"

curl -s "https://api.github.com/repos/doitsujin/dxvk/releases/latest" | \
  grep -Po "['\"]browser_download_url['\"]\s*:\s*['\"]\K(.*)(?=['\"])" | \
  xargs -n1 curl -sL | \
  tar xvfz - -C "$archive_path" --strip 1 > /dev/null

sh "$archive_path/setup_dxvk.sh" install

wine Steam.exe -no-cef-sandbox
@dvershinin

This comment has been minimized.

Copy link

commented Aug 22, 2019

@andrew-aladev or, using lastversion

#!/bin/sh

archive_path="/tmp/dxvk"
mkdir -p "$archive_path"

curl -sL $(lastversion --source doitsujin/dxvk) | \
  tar xvfz - -C "$archive_path" --strip 1 > /dev/null

sh "$archive_path/setup_dxvk.sh" install

wine Steam.exe -no-cef-sandbox

which will take care of things if repo maintainer forgets to tag a formal release.

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.