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 -
@SuperJC710e
Copy link

SuperJC710e commented May 27, 2021

If someone needs a PowerShell only version (example for Microsofts vsts agent):

$githubLatestReleases = "https://api.github.com/repos/microsoft/azure-pipelines-agent/releases/latest"   
$githubLatestReleasesJson = ((Invoke-WebRequest $gitHubLatestReleases) | ConvertFrom-Json).assets.browser_download_url  
$Uri = (((Invoke-WebRequest $githubLatestReleasesJson | ConvertFrom-Json).downloadUrl) | Select-String "vsts-agent-win-x64").ToString()  

Perfect! Thank you!

@majick777
Copy link

majick777 commented May 31, 2021

"To link directly to a download of your latest release asset, link to /owner/name/releases/latest/download/asset-name.zip."
Source: https://docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/linking-to-releases

This means you can just download the asset URL directly without the API?
So I'm not sure why this is still a thing? (Tho my guess is maybe this redirect was added in 2019 but this thread started in 2017.)

@alerque
Copy link

alerque commented May 31, 2021

@majick777 That only works for projects that post assets with simple filenames that don't have any changing version data in the asset name itself. Some projects do that, but not all can be downloaded that way and while it makes this easy doing that makes other things hard (like keeping multiple versions of something in a directory). Hence these solutions are still useful in 2021. If the project you are downloading from doesn't have version info in the asset name by all means use those "latest" links.


As for the proliferation of comments here:

  1. The majority of people posting clearly aren't proficient shell coders. There are a number of gems above, but many of the solutions are overly complex, spawn more processes than necessary, make shell quoting blunders, etc. Some claim to be "bash" but are actually "sh" and vise versa. Many of the examples here using 2 greps and a cut could be simplified to a single grep if you pay attention to the URL scheme to match. Many examples above make the mistake of using xargs, then only handling one possible output. These will fail badly if more than one match is found.
  2. Half the comments seem to be unaware that the exact syntax will need to be adjusted based on the upstream project's asset naming schemes. There is no 1-size-fits-all command for this because almost all of these rely on some form of pattern matching or assumptions about the naming scheme. We don't need 20 more "this is the one that works" posts! Sure you had to adjust your syntax for the project you were downloading from, but that doesn't mean it will work best for everyone.
  3. Different tools are used and some situations might call for that. I posted examples with jq and with grep above to illustrate how different tooling could be used to advantage. Likewise swapping wget -qi and curl -fsLJO can be a matter of system tooling choice.
  4. Some of these are better for scripting, some are better for interactive use.

Before posting more, please seriously consider whether your solution offers something more in the way of a better implementation or more explanation than existing options. If you just copied and tweaked an existing one to match some other project URL scheme, please refrain since that won't add anything.

@yaneony
Copy link

yaneony commented Jun 17, 2021

Shameless self-promotion, but i did that for community as well. https://ghd.one
Enter repository URL, filter down the list to only one single file, get your permanent link for download.

Example for Gitea repository: https://ghd.one/go-gitea/gitea
Filtered to Linux binary 64bit without extension: https://ghd.one/go-gitea/gitea?includes=linux+amd64&excludes=amd64.
Filtered to Windows 64bit executable file: https://ghd.one/go-gitea/gitea?includes=windows+amd64&excludes=gogit+.exe.

More about it on reddit: https://www.reddit.com/r/programming/comments/o1yit0/ghd_get_github_direct_links_without_pain_wip/

@alerque
Copy link

alerque commented Jun 17, 2021

@yaneony That’s kinda spiffy to help people that can't write match expressions for grep come up with something useful, but it would be cooler if the UI gave out a shell command with the appropriate way to get the original URL rather than bouncing everybody’s downloads through a 3rd party service!

@yaneony
Copy link

yaneony commented Jun 17, 2021

@alerque you've right, the only problem is: different platforms - different methods.
Some people using bash, some wget, other nodejs or even php... I went thru all of them. It did a lot of pain changing regular expressions every time developer change naming pattern. That's how i came to idea of making that website.

@psychowood
Copy link

psychowood commented Jul 14, 2021

Just in case this could be useful for anyone, I'm using this oneliner from an alpine docker image, to pull the latest tarball from a github release and extract it in the current folder, skipping the original root folder:

curl -s https://api.github.com/repos/ghostfolio/ghostfolio/releases/latest | sed -n 's/.*"tarball_url": "\(.*\)",.*/\1/p' | xargs -n1 wget -O - -q | tar -xz --strip-components=1

@minlaxz
Copy link

minlaxz commented Aug 1, 2021

How I do in bash,

tarballLink=$(curl -s https://api.github.com/repos/minlaxz/cra-by-noob/releases/latest \
| grep "browser_download_url.*tar.xz"  \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs)

@pogossian
Copy link

pogossian commented Aug 18, 2021

To link directly to a download of your latest release asset, link to /owner/name/releases/latest/download/asset-name.zip.

https://docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/linking-to-releases

@minlaxz
Copy link

minlaxz commented Aug 19, 2021

@pogossian thanks.
Now I can simply curl it

curl -fsSL github.com/owner/repo/releases/latest/download/asset-name.zip -O

@knadh
Copy link

knadh commented Aug 22, 2021

Download the latest release where the release filename is dynamic, for example, with version strings.

# Get the URL of the latest release.
# Leave https://(.*) as is and adjust the second (.*) in the URL to match the dynamic bits in the project filename.
URL=$(curl -L -s https://api.github.com/repos/username/projectname/releases/latest | grep -o -E "https://(.*)projectname_(.*)_linux_amd64.tar.gz")

# Download and extract the release to the build dir.
curl -L -s $URL | tar xvz -C ./extract-dir

@yaneony
Copy link

yaneony commented Aug 23, 2021

The only problem by the code you're sharing here is, you can only get the release source code, but not the released asset which name might change from version to version. And that is why i did that here: https://gist.github.com/steinwaywhw/a4cd19cda655b8249d908261a62687f8#gistcomment-3783983

@SOOS-Pchen
Copy link

SOOS-Pchen commented Sep 2, 2021

@yaneony when i try it, the assets show up but when hovering over the download button it says "not available".

@yaneony
Copy link

yaneony commented Sep 3, 2021

@SOOS-Pchen which repository?

@redraw
Copy link

redraw commented Sep 22, 2021

I've written a snippet that usually works https://gist.github.com/redraw/13ff169741d502b6616dd05dccaa5554

@XedinUnknown
Copy link

XedinUnknown commented Sep 29, 2021

To link directly to a download of your latest release asset, link to /owner/name/releases/latest/download/asset-name.zip.

docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/linking-to-releases

@pogossian, the point of this whole thread seems to be that the asset-name.zip part is different for automatic source tarballs. Have you found a convenient way to go around this?

@yaneony
Copy link

yaneony commented Sep 29, 2021

To link directly to a download of your latest release asset, link to /owner/name/releases/latest/download/asset-name.zip.
docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/linking-to-releases

@pogossian, the point of this whole thread seems to be that the asset-name.zip part is different for automatic source tarballs. Have you found a convenient way to go around this?

There is no easy way to do that. If you use only few repos you can handle the whole with some regular expressions. The thing can get ugly if released assets get different names from version to version, like codename in file name or other things. Handling different repos is really hard, since you also have rate limits. I've solved that by my website, but you have to rely on third party service. It's just doing redirect in background.

@Strykar
Copy link

Strykar commented Sep 30, 2021

@Karmakstylez
Copy link

Karmakstylez commented Oct 12, 2021

URL=$(curl -v https://api.github.com/repos/user/repo/releases/latest 2>&1 | grep -v ant | grep browser_download_url | grep -v .asc | cut -d '"' -f 4) && wget $URL && ZIP="$(find . -maxdepth 1 -name "namebefore-*-release.zip")" && unzip -qq $ZIP

Dockerfile tested and works perfectly. In case there are multiple files you can try with WSL to see which file you need and do multiple grep pipelines to get the file you need. Such as .asc files. If there are none you can simply ignore that.

@jasonbrianhall
Copy link

jasonbrianhall commented Oct 21, 2021

#!/bin/bash

export HTTPS_PROXY=servername:port

for x in curl -s https://api.github.com/repos/aquasecurity/trivy/releases/latest | jq -r '.assets[] | select(.content_type == "application/x-rpm") | {url} | .url'; do
RPM=curl $x | jq -r .browser_download_url
curl -L $RPM -O

done

@eladkarako
Copy link

eladkarako commented Oct 22, 2021

a note (for your repositories)

I advise using consistent file-names. I.E. don't include a versioning in the filename.

I know it sounds weird, but bear with me* for a second.

You know the .../releases/latest syntax right?
did you know you can also use it to download files as well? (and not just to redirect to the latest release on Github?)

Here, try this URL for example:
https://github.com/ytdl-org/youtube-dl/releases/latest/download/youtube-dl.exe.

this reduces the need to walk through Github-Releases API entirely! and simplify stuff for users and also web-services that crawls your repository (in-case you have a somewhat popular product :] ).
You don't to maintain any kind of backend or domain at all and relink to to the latest binaries (for example: http://youtube-dl.org/downloads/latest/youtube-dl.exe). it is handled by github releases!

you can always include the version in a file named version.txt,
or any meta-data, really. keep a consistent file-name here too.

got the idea from https://github.com/yt-dlp/yt-dlp#update

@yucongo
Copy link

yucongo commented Oct 24, 2021

curl --silent "https://api.github.com/repos/USER/REPO/releases/latest" | jq ".. .tag_name? // empty"

delivers the latest release string, e.g., "v1.0.0-beta7-fix2", provided tag_name is so set I suppose.

@blafasel42
Copy link

blafasel42 commented Oct 25, 2021

curl -o filename.tgz -L `curl -s https://api.github.com/repos/USER/REPO/releases/latest | grep -oP '"tarball_url": "\K(.*)(?=")'`

there will be a container directory inside this. You can find its name like:

export hash=`curl -s https://api.github.com/repos/ImageMagick/ImageMagick/releases/latest | grep -oP '"target_commitish": "\K(.*)(?=")'`
export dir = USER-REPO-${hash::7}

so if you tar -zxf filename.tgz after the first curl, you can then cd $dir and then work with the files...

@maelstrom256
Copy link

maelstrom256 commented Dec 9, 2021

Not a oneliner, but…
Sample for VictoriaMetrics vmutils package

REPO=VictoriaMetrics/VictoriaMetrics
IMASK='vmutils.*amd64.*gz'
EMASK='(enterprise|windows)'
curl --silent https://api.github.com/repos/${REPO}/releases | \
jq -r "sort_by(.tag_name) | [ .[] | select(.draft | not) | select(.prerelease | not) ] | .[-1].assets[].browser_download_url | select(test(\".*${IMASK}.*\")) | select(test(\"${EMASK}\") | not)"

@maxadamo
Copy link

maxadamo commented Dec 14, 2021

some of you made it quite difficult with AWK, while it was quite easy.
In my case I search for the Ubuntu package:

REPO='jgraph/drawio-desktop'
curl -s https://api.github.com/repos/${REPO}/releases/latest | awk -F\" '/browser_download_url.*.deb/{print $(NF-1)}'

@redraw
Copy link

redraw commented Dec 16, 2021

I've made a Github extension

Installation: gh extension install redraw/gh-install

Usage: gh install <user>/<repo>

@sebma
Copy link

sebma commented Dec 16, 2021

👍

@b2az
Copy link

b2az commented Feb 22, 2022

@yucongo i had to laugh so much - as i found this searching for a way to download the latest release of the jq tool itself 🧨

@xaratustrah
Copy link

xaratustrah commented Mar 3, 2022

thanks @Frikster ! here is a modified version for getting the newest tag from a repository and unpack it immediately:

curl https://api.github.com/repos/<USER>/<REPO>/tags | grep "tarball_url" | grep -Eo 'https://[^\"]*' | sed -n '1p' | xargs wget -O - | tar -xz

@maxadamo
Copy link

maxadamo commented Mar 3, 2022

@xaratustrah 5 pipes! You are the winner 😺

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