Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save steinwaywhw/a4cd19cda655b8249d908261a62687f8 to your computer and use it in GitHub Desktop.
Save steinwaywhw/a4cd19cda655b8249d908261a62687f8 to your computer and use it in GitHub Desktop.
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 -
@graphik55
Copy link

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()  

@MostHated
Copy link

MostHated commented Apr 9, 2021

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

Exactly what I was hoping to find. 👍

I made a slight adjustment to it for my needs.

$githubLatestReleases = 'https://api.github.com/repos/microsoft/winget-cli/releases/latest'   
$githubLatestRelease = (((Invoke-WebRequest $gitHubLatestReleases) | ConvertFrom-Json).assets.browser_download_url | select-string -Pattern 'appxbundle').Line
Invoke-WebRequest $githubLatestRelease -OutFile 'Microsoft.DesktopAppInstaller.appxbundle'

@alerque
Copy link

alerque commented Apr 14, 2021

The cut/tr shenanigans in the original post dodging the colon in the URL drives me crazy. This snippet has propogated everywhere, very few people that copy / paste it know how it works, and it leaves so much room for improvement. @dsifford was on the same track but stopped short of passing the result to the final download. (Edit At first pass I missed @mando7's similar solution, the extra grep -w flag is a nice touch but not required.)

Lets start with swapping grep | cut | tr for grep -o. If you're already searching for a string, why not just print the bit that matches your search instead of searching for it with context then stripping away the context? No good reason. Since the ".deb" from the original post happens to be ambiguous for this project now I'm including a match.

Also, why use two tools curl then wget when curl is arguably more capable than the latter for both jobs. wget - can be curl -fsSLJO.

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest |
	grep -o "https://.*\.amd64\.deb" |
	xargs curl -fsLJO

If the grep doesn't suit you and you have jq handy you can swap in the equivalent:

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest |
	jq -r '.assets[].browser_download_url | select(test("arm64.deb"))' |
	xargs curl -fsLJO

@flightlesstux
Copy link

flightlesstux commented May 6, 2021

I don't understand why there are so many comments here. It's really easy with bash. Here is the example, I did it for you.

if [ "${OSTYPE}" = "x86_64" ]; then
    BIN="amd64"
else
    BIN="arm64"
fi

LATEST=$(curl -s https://api.github.com/repos/prometheus/node_exporter/releases/latest | grep "linux-${BIN}.tar.gz" | cut -d '"' -f 4 | tail -1)

cd /tmp/
curl -s -LJO $LATEST

@Sy3Omda
Copy link

Sy3Omda commented May 7, 2021

easy and fast
curl -s https://api.github.com/repos/user/reponame/releases/latest | grep -E 'browser_download_url' | grep linux_amd64 | cut -d '"' -f 4 | wget -qi -

@Frikster
Copy link

Frikster commented May 18, 2021

To download the latest tarball for a repo I was able to just do this:

curl https://api.github.com/repos/user/reponame/releases/latest | grep "browser_download_url" | grep -Eo 'https://[^\"]*' | xargs wget

I think if you are on Windows you have to change it to:

curl https://api.github.com/repos/user/reponame/releases/latest | grep "browser_download_url" | grep -Eo 'https://[^/"]*' | xargs wget

If you want to download the latest tar and immediately extract what was downloaded:

curl https://api.github.com/repos/user/reponame/releases/latest | grep "browser_download_url" | grep -Eo 'https://[^\"]*' | xargs wget -O - | tar -xz

@vithalreddy
Copy link

i have developed a small bash function which will take git repo as fn argument and has an option to define install methods. and cleans the data after instalation is complete.

ghInstall author/repo
function ghInstall(){
    local loc="/tmp/gh-downloads/$1"
    local repo="https://api.github.com/repos/$1/releases/latest"
    local URL=`curl -s "${repo}" | grep "browser_download_url" | cut -d '"' -f 4 | fzf`
    echo "Repo: $repo Temp Dir: $loc"

    mkdir -p $loc
    curl -sOL --output-dir $loc  ${URL}
    local tarfilename="$(find $loc  -name "*.tar.gz")"
    tar xvzf $tarfilename -C $loc
    ls $loc -al

    local PS3='Please choose the Installing Method: '
    local gh_options=("Move to Bin Dir" "Make install" "Quit")
    select opt in "${gh_options[@]}"
    do
        case $opt in
            "Move to Bin Dir")
                rm -rf $tarfilename
                sudo mv $loc/* /usr/local/bin/
                break
                ;;
            "Make install")
                make install
                break
                ;;
            "Quit")
                break
                ;;
            *) echo "invalid option $REPLY";;
        esac
    done

    rm -rf $loc
}

@SuperJC710e
Copy link

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

"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

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

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

@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

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

#!/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

Copy link

ghost 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

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

it can be done using AWK. In this case I'm matching against a deb 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

@NotoriousPyro
Copy link

I prefer to use jq to parse the output (e.g. for Vale)

    package=$(curl -s https://api.github.com/repos/errata-ai/vale/releases/latest \
    | jq -r ' .assets[] | select(.name | contains("Linux"))'); output=$(mktemp -d); \
    echo $package | jq -r '.browser_download_url' | xargs curl -L --output-dir $output -O; \
    echo $package | jq -r '.name' | sed -r "s#(.*)#$output/\1#g" | xargs cat \
    | tar xzf - -C $output; cp $output/vale $HOME/bin

@necros2k7
Copy link

Can we get latest release from Windows? What would command line look like?

@oshliaer
Copy link

@necros2k7, you have to learn the cmd of your OS.

@graphik55
Copy link

Can we get latest release from Windows? What would command line look like?

@necros2k7
Checkout my previous answer:
https://gist.github.com/steinwaywhw/a4cd19cda655b8249d908261a62687f8?permalink_comment_id=3668287#gistcomment-3668287

@XedinUnknown
Copy link

@necros2k7, why not WSL2?

@redraw, thanks, looks really good!

@Ritesh007
Copy link

Ritesh007 commented May 19, 2022

  • for the latest package download - curl -fsSL github.com/<user>/<repo>/releases/latest/download/<asset_name> -O
  • for a specific tagged release package download -
    curl -fsSL github.com/<user>/<repo>/releases/download/<tag_name>/<asset_name> -O

@joaovitor
Copy link

@sebma
Copy link

sebma commented May 19, 2022

@joaovitor 👍

@wmacevoy
Copy link

wmacevoy commented May 20, 2022

Python3 instead of jq (grep is bad because it assumes json will be formatted in certain ways)

curl -LJO `curl -s https://api.github.com/repos/wmacevoy/facts/releases/latest | python3  -c 'import sys, json; print(json.load(sys.stdin)["tarball_url"])'`

You can extract the latest into the current directory with:

curl -LJ `curl -s https://api.github.com/repos/wmacevoy/facts/releases/latest | python3  -c 'import sys, json; print(json.load(sys.stdin)["tarball_url"])'` | tar zxf - --strip=1

In either case, if you have jq, then you can replace

python3  -c 'import sys, json; print(json.load(sys.stdin)["tarball_url"])'

with

jq -r .tarball_url

@jreybert
Copy link

jreybert commented May 31, 2022

To select an asset based on a regex on the asset name, for example .*linux_amd64.tar.gz, and get the donwload url:

curl -s https://api.github.com/repos/username/projectname/releases/latest | jq '.assets[] | select(.name|match("linux_amd64.tar.gz$")) | .browser_download_url'

@jreisinger
Copy link

jreisinger commented Jun 4, 2022

I wrote a CLI tool in Go named ghrel to list, concurrently download and verify assets of the latest release.

@liudonghua123
Copy link

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

COOL! 👍

@robertpatrick
Copy link

robertpatrick commented Sep 15, 2022

Hmm... https://github.com/<org-name>/<repo-name>/releases/latest/download/<artifact-file-name> should work without having to rely on the GitHub REST API, no?

@derekm
Copy link

derekm commented Sep 16, 2022

Download all assets in the latest release:

#!/bin/bash
IFS=$' \t\r\n'

assets=$(curl https://api.github.com/repos/$ORG/$REPO/releases | jq -r '.[0].assets[].browser_download_url')

for asset in $assets; do
    curl -OL $asset
done

... or ...

Download all assets in a specific release:

#!/bin/bash
IFS=$' \t\r\n'

assets=$(curl https://api.github.com/repos/$ORG/$REPO/releases | jq -r ".[] | select(.tag_name == \"$TAG\") | .assets[].browser_download_url")

for asset in $assets; do
    curl -OL $asset
done

@nicman23
Copy link

nicman23 commented Sep 28, 2022

curl -sL https://github.com/revanced/revanced-integrations/releases/ | 
   xmllint -html -xpath '//a[contains(@href, "releases")]/text()' - 2> /dev/null | 
   grep -P '^v' | head -n1

@cobalt2727
Copy link

Hello! Every now and then this function fails seemingly at random, and I haven't been able to successfully determine why.

From a script to automatically update WebCord:

Downloading the most recent .deb from SpacingBat3 repository...
--2022-10-18 19:51:55--  https://api.github.com/repos/SpacingBat3/WebCord/releases/79464711,assets_url
Resolving api.github.com (api.github.com)... 140.82.113.5
Connecting to api.github.com (api.github.com)|140.82.113.5|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/json]
Saving to: ‘79464711,assets_url’

     0K .......... .......... .......                          1.35M=0.02s

2022-10-18 19:51:55 (1.35 MB/s) - ‘79464711,assets_url’ saved [28644]

FINISHED --2022-10-18 19:51:55--
Total wall clock time: 0.3s
Downloaded: 1 files, 28K in 0.02s (1.35 MB/s)
Done! Installing the package...
Waiting until APT locks are released... 

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
E: Unsupported file /tmp/*arm64.deb given on commandline
Webcord install failed

Would anyone be able to help me debug this and figure out why I'm getting whatever 79464711,assets_url is supposed to be instead of the release file?
The exact commands I'm running are

cd /tmp
curl -s https://api.github.com/repos/SpacingBat3/WebCord/releases/latest |
  grep "browser_download_url.*arm64.deb" |
  cut -d : -f 2,3 |
  tr -d \" |
  wget -i -

echo "Done! Installing the package..."
sudo apt install -y /tmp/*arm64.deb || error "Webcord install failed"

@antofthy
Copy link

antofthy commented Oct 21, 2022

While all this USED to be easy... I am now finding the returned URL for the project I am interested in has a return of
"message": "Moved Permanently"
But without a HTTP redirection, which curl could handle transparently.

Seems the owner of the project had changed on me!

As such you may have to check for this condition and adjust accordingly!

"The pain. The pain!" -- Doctor Smith, "Lost in Space"

@surfzoid
Copy link

surfzoid commented Nov 8, 2022

Hi, you should add point betwen * and deb , because, as you can see curl -s https://api.github.com/repos/surfzoid/QtVsPlayer/releases/latest
| grep "browser_download_url.*deb"

By the way, i thank you for time win

@surfzoid
Copy link

surfzoid commented Nov 8, 2022

unlucky it is not enough, why curl/grep catch debuginfo as .deb?

@NotoriousPyro
Copy link

Hello! Every now and then this function fails seemingly at random, and I haven't been able to successfully determine why.

From a script to automatically update WebCord:

Downloading the most recent .deb from SpacingBat3 repository...
--2022-10-18 19:51:55--  https://api.github.com/repos/SpacingBat3/WebCord/releases/79464711,assets_url
Resolving api.github.com (api.github.com)... 140.82.113.5
Connecting to api.github.com (api.github.com)|140.82.113.5|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/json]
Saving to: ‘79464711,assets_url’

     0K .......... .......... .......                          1.35M=0.02s

2022-10-18 19:51:55 (1.35 MB/s) - ‘79464711,assets_url’ saved [28644]

FINISHED --2022-10-18 19:51:55--
Total wall clock time: 0.3s
Downloaded: 1 files, 28K in 0.02s (1.35 MB/s)
Done! Installing the package...
Waiting until APT locks are released... 

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
E: Unsupported file /tmp/*arm64.deb given on commandline
Webcord install failed

Would anyone be able to help me debug this and figure out why I'm getting whatever 79464711,assets_url is supposed to be instead of the release file? The exact commands I'm running are

cd /tmp
curl -s https://api.github.com/repos/SpacingBat3/WebCord/releases/latest |
  grep "browser_download_url.*arm64.deb" |
  cut -d : -f 2,3 |
  tr -d \" |
  wget -i -

echo "Done! Installing the package..."
sudo apt install -y /tmp/*arm64.deb || error "Webcord install failed"

The problem is you're trying to use grep, cut and trim on json. None of which are designed for handing json in a reliable way. Use jq for reliability, as per my example above.

@NotoriousPyro
Copy link

While all this USED to be easy... I am now finding the returned URL for the project I am interested in has a return of "message": "Moved Permanently" But without a HTTP redirection, which curl could handle transparently.

Seems the owner of the project had changed on me!

As such you may have to check for this condition and adjust accordingly!

"The pain. The pain!" -- Doctor Smith, "Lost in Space"

You can use -L with curl to make it follow redirects.

@dvershinin
Copy link

Would anyone be able to help me debug this and figure out why I'm getting whatever 79464711,assets_url is supposed to be instead of the release file?

Just use lastversion. It's pretty powerful:

lastversion --assets --filter arm64.deb download https://github.com/SpacingBat3/WebCord

Downloaded webcord_3.9.2_arm64.deb: : 72872.0KB [00:18, 3860.60KB/s]

@antofthy
Copy link

antofthy commented Nov 8, 2022

While all this USED to be easy... I am now finding the returned URL for the project I am interested in has a return of "message": "Moved Permanently" But without a HTTP redirection, which curl could handle transparently.
Seems the owner of the project had changed on me!
As such you may have to check for this condition and adjust accordingly!
"The pain. The pain!" -- Doctor Smith, "Lost in Space"

You can use -L with curl to make it follow redirects.

That was the point... there were no redirects! Not in the HTTP protocol header, only in the JSON data returned.

@solbu
Copy link

solbu commented Nov 20, 2022

Just remember that this only works for repos that do a Release.
Many projects only use Tags as the release mechanism. I am one of them. :-)

@NotoriousPyro
Copy link

Well then it's not a release and those repos are not releasing anything.

@NotoriousPyro
Copy link

Tags are not releases, but releases reference a tag.

@dvershinin
Copy link

Tags are not releases. But the tags that resemble version numbers in all likelihood are releases 🫡

@NotoriousPyro
Copy link

True, but then it creates the problem you mention. Using a repo in this way creates the limitation of not being able to grab the releases... Without doing some grepping and whatnot on the tag name.

@solbu
Copy link

solbu commented Nov 20, 2022

My reason for Not doing a Release on Github (in the /username/foo-bar/releases/ page) is that I have to interact with the webgui,
as in I have to login to Github in a browser, upload whatever is part of the release and so on – just to do a release,
whereas on SourceForge I only have to do an rsync command in the terminal to do a Release, which is often automated in a script or a target in a Makefile.

@robertpatrick
Copy link

@solbu well…. There are mechanisms to create releases via the REST api. I wrote a little github-maven-plug-in that currently supports creating draft releases, uploading any binaries needed, and pushing release notes. It could easily be extended to publish the release…

@cobalt2727
Copy link

Would anyone be able to help me debug this and figure out why I'm getting whatever 79464711,assets_url is supposed to be instead of the release file?

Just use lastversion. It's pretty powerful:

lastversion --assets --filter arm64.deb download https://github.com/SpacingBat3/WebCord

Downloaded webcord_3.9.2_arm64.deb: : 72872.0KB [00:18, 3860.60KB/s]

I'll definitely look into this, thank you!

@eortegaz
Copy link

eortegaz commented Dec 9, 2022

Love a good one-liner.

If you must use wget, to make your life easier you should search for your architecture by matching uname -m from the JSON response. Don't forget to add head -1 though, otherwise you're (silently) downloading packages for all available archs.

Totally up to you, but you may want to show progress too (albeit omitting everything else) with -q --show-progress instead of suppressing all output.

The one-liner would look something like this:

    REPO="jgm/pandoc"; \
    curl -s https://api.github.com/repos/${REPO}/releases/latest | grep "browser_download_url.*$(uname -m).deb" \
    | head -1 \
    | cut -d : -f 2,3 \
    | tr -d \" \
    | wget --show-progress -qi - \
    || echo "-> Could not download the latest version of '${REPO}' for your architecture." # if you're polite

Note: Setting a variable with the user/repo should decrease the risk of messing up the url :)

@fanuch
Copy link

fanuch commented Dec 23, 2022

My hat in the ring.

VER=$(curl --silent -qI https://github.com/bakito/adguardhome-sync/releases/latest | awk -F '/' '/^location/ {print  substr($NF, 1, length($NF)-1)}'); \
wget https://github.com/bakito/adguardhome-sync/releases/download/$VER/adguardhome-sync_${VER#v}_linux_x86_64.tar.gz 

Technically two lines because I needed to use the version number both in the URL path and in the filename

Retrieve latest version using curl

curl -I https://github.com/bakito/adguardhome-sync/releases/latest

returns

HTTP/2 302 
...
location: https://github.com/bakito/adguardhome-sync/releases/tag/v0.4.10
...

So strip it out (minus the carriage return):

curl -I https://github.com/bakito/adguardhome-sync/releases/latest | awk -F '/' '/^location/ {print  substr($NF, 1, length($NF)-1)}'

returns

v0.4.10

Attach to a variable and get annoyed when filename doesn't have a leading 'v'

${VER#v}

This strips the leading v from the version number

Note

Doesn't handle different architectures but that would be the use of uname -m at the least

Thanks for the inspo in this thread - really should be easier than this ...

@bluebrown
Copy link

@robertpatrick

Hmm... https://github.com///releases/latest/download/ should work without having to rely on the GitHub REST API, no?

That works only if the publisher doesn't put the version in the artifact file name, which is more often than not the case. The api.github.com, tells you the version and download URL in the response.

@bluebrown
Copy link

My script looks pretty much like this, but you need to be careful with mono repos that publish different artifacts with different tags. Latest is useless on those.

@cinderblock
Copy link

One liner to download and pipe it to tar for extraction directly:

curl -sL $(curl -s https://api.github.com/repos/actions/runner/releases/latest | grep browser_download_url | cut -d\" -f4 | egrep 'linux-arm64-[0-9.]+tar.gz$') | tar zx

@notorand-it
Copy link

notorand-it commented Feb 9, 2023

Why on Earth would you use two different tools for the same task and put curl and wget in the same script/1-liner ?
Why fiddling with grep/tr/cut when the only reliable JSON parsing tool is jq ?

This is from my own stuff (different URL):

wget -q -O /usr/bin $(wget -q -O - 'https://api.github.com/repos/mikefarah/yq/releases/latest' | jq -r '.assets[] | select(.name=="yq_linux_amd64").browser_download_url'')

2 tools is better than 5 IMHO.
Adapting it to other needs is left to the keen reader. ;-)

@joshjohanning
Copy link

joshjohanning commented Feb 15, 2023

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

COOL! 👍

This is it

wget https://github.com/aquasecurity/tfsec/releases/latest/download/tfsec-linux-amd64

@NLZ
Copy link

NLZ commented Apr 4, 2023

Exactly what I was hoping to find. 👍

I made a slight adjustment to it for my needs.

$githubLatestReleases = 'https://api.github.com/repos/microsoft/winget-cli/releases/latest'   
$githubLatestRelease = (((Invoke-WebRequest $gitHubLatestReleases) | ConvertFrom-Json).assets.browser_download_url | select-string -Pattern 'appxbundle').Line
Invoke-WebRequest $githubLatestRelease -OutFile 'Microsoft.DesktopAppInstaller.appxbundle'

Powershell can be further simplified with invoke-restmethod's auto-parsing and then exploring the objects in the pipe

Invoke-RestMethod 'https://api.github.com/repos/microsoft/winget-cli/releases/latest' | % assets | ? name -like "*.msixbundle" | % { Invoke-WebRequest $_.browser_download_url -OutFile $_.name }

@bruteforks
Copy link

bruteforks commented Apr 19, 2023

Hmm... https://github.com/<org-name>/<repo-name>/releases/latest/download/<artifact-file-name> should work without having to rely on the GitHub REST API, no?

literally the easiest way i've found. Thank you! example

edit: here's what i ended up with

echo "Check for watchman"
if ! [ -x "$(command -v watchman)" ]; then
echo "downloading and installing latest github release"
wget $(curl -L -s https://api.github.com/repos/facebook/watchman/releases/latest | grep -o -E "https://(.*)watchman-(.*).rpm") && sudo dnf localinstall watchman-*.rpm
watchman version
else
  echo "watchman exists."	
fi

@vavavr00m
Copy link

Nothing for Windows worked for me.

The below Windows batch script sort of worked but it's downloading all latest releases. Anyone knows how to modify it to select only the *-x64.exe release?

  set repo=owner/name
  for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do ( curl -kOL %%B )

@flightlesstux
Copy link

flightlesstux commented Jun 1, 2023

Nothing for Windows worked for me.

The below Windows batch script sort of worked but it's downloading all latest releases. Anyone knows how to modify it to select only the *-x64.exe release?

  set repo=owner/name
  for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do ( curl -kOL %%B )

@vavavr00m could you try this?

set repo=owner/name
for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do (
    set url=%%B
    set "filename=%url:*\=%"
    if "%filename:~-9%"=="-x64.exe" (
        curl -kOL %url%
    )
)

@vavavr00m
Copy link

vavavr00m commented Jun 1, 2023

@flightlesstux Thanks for your response. The %url% stored the -x86.exe release and also the script doesn't also download that file. How do I change it to pick up -x64.exe and download it?

@flightlesstux
Copy link

@vavavr00m You're welcome! This script calls a :download subroutine from the loop. The subroutine sets url and filename variables, then checks the filename and downloads the file if it matches -x64.exe.

@echo off
setlocal enabledelayedexpansion
set repo=owner/name
for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do (
    call :download "%%B"
)
goto :eof

:download
set "url=%~1"
for %%i in (%url%) do set "filename=%%~nxi"
if "%filename:~-9%"=="-x64.exe" (
    curl -kOL %url%
)
goto :eof

@vavavr00m
Copy link

@flightlesstux I tried this on PowerToys. It doesn't download the -x64.exe release(s) for me and %url% output is all the browser_download_url from the PowerToys repo but nothing was downloaded:

image

Would it help to say the .bat is getting the links from a JSON? Should the script echo the URL(s) without the double quotes?

test.bat on W10:

 @echo off

 setlocal enabledelayedexpansion
 set repo=microsoft/PowerToys
 for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do (
      call :download "%%B"
 )
 goto :eof

 :download
 set "url=%~1"
 for %%i in (%url%) do set "filename=%%~nxi"
 if "%filename:~-9%"=="-x64.exe" (
     curl -kOL %url%
)
goto :eof

@antofthy
Copy link

antofthy commented Jun 2, 2023

The problem is that what to search for VARIES from repo to repo.
MOST repos seem to use browser_download_url but I have also have seen repos that does not have that entry, but use tarball_url, zipball_url instead.

@si618
Copy link

si618 commented Sep 13, 2023

@fanuch

My hat in the ring.

VER=$(curl --silent -qI https://github.com/bakito/adguardhome-sync/releases/latest | awk -F '/' '/^location/ {print  substr($NF, 1, length($NF)-1)}'); \
wget https://github.com/bakito/adguardhome-sync/releases/download/$VER/adguardhome-sync_${VER#v}_linux_x86_64.tar.gz 

Thanks for the inspo in this thread - really should be easier than this ...

Agreed, and thanks for putting your hat in the ring; it was very close to what I needed 🙇‍♂️

@codelinx
Copy link

codelinx commented Sep 21, 2023

Using jq, i think this should work with most repos and allow you to saerch different values or fields as needed.

wget $(curl -s https://api.github.com/repos/bitwarden/clients/releases/latest  | \
 jq -r '.assets[] | select(.name | contains ("deb")) | .browser_download_url')
  • jq -r raw search
  • select( .name select the field to refine your download
  • | contains ("deb")) search criteria to get the download url
  • . browser_download_url' return string

NOTE: '--raw-output/-r' With this option, if the filter's result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes

@notorand-it
Copy link

But why using wget and curl? Why not just wget or curl?

@codelinx
Copy link

But why using wget and curl? Why not just wget or curl?

This is a programmatic discussion for downloading the file(s). You cant wget/curl get the file because of links and internet things. Other issues are that the file name may change, the version, or the file you may need for your OS may change etc.

@codelinx
Copy link

But why using wget and curl? Why not just wget or curl?

you are just trolling.

@notorand-it
Copy link

notorand-it commented Sep 22, 2023

wget $(wget -q -O - https://api.github.com/repos/bitwarden/clients/releases/latest | jq -r '.assets[] | select(.name | contains ("deb")) | .browser_download_url')

I would say this is NOT trolling.
Just like this, IMHO.

@jrichardsz
Copy link

It worked at first attempt :)
Thank you so much !!

@NiceGuyIT
Copy link

dra is making huge strides in simplifying the download process.

dra helps you download release assets more easily:

  • no authentication for public repository (you cannot use gh without authentication)
  • Built-in generation of pattern to select an asset to download (with gh you need to provide glob pattern that you need to create manually).

@panscher
Copy link

@flightlesstux

The download with NotpadPlus x64.exe does not work.

`
@echo off

setlocal enabledelayedexpansion
set repo=notepad-plus-plus/notepad-plus-plus
for /f "tokens=1,* delims=:" %%A in ('curl -ks https://api.github.com/repos/%repo%/releases/latest ^| find "browser_download_url"') do (
call :download "%%B"
)
goto :eof

:download
set "url=%~1"
for %%i in (%url%) do set "filename=%%nxi"
if "%filename:
-9%"==".x64.exe" (
curl -kOL %url%
)
goto :eof
`

@notorand-it
Copy link

I am not unsubscribing because I actually want to see how far we get, and how long this conversation lasts with all these comments that everyone keeps adding. There are hundreds of ways and different languages to achieve the same result. But do we need the rosetta stone with all the programming languages on earth, and all the different approaches, or can we move on, after having received so many comments? OMG.

" different languages"?

The title reads "One Liner to Download the Latest Release from Github Repo".
I would say that the original thing aimed at using a single line command or pipeline.
So I would say it is aimed at a shell (bash/zsh/PowerShell) not any language.
Still on a single line.

IMHO, a few comments actually hit spot.
All the rest is either multi-line scripts (no. of lines > 1) or just not working.

@antofthy
Copy link

antofthy commented Dec 7, 2023

The title reads "One Liner to Download the Latest Release from Github Repo". I would say that the original thing aimed at using a single line command or pipeline. So I would say it is aimed at a shell (bash/zsh/PowerShell) not any language. Still on a single line.
IMHO, a few comments actually hit spot. All the rest is either multi-line scripts (no. of lines > 1) or just not working.

For a specific repository a single line to do the task can be created. BUT for a general repository, well, what is needed is next to impossible to do in one line, or even in a small script. There are always weird exceptions. I have seen many of them!

The general request that was made, was so general, it is also impossible to achieve. No one answer, or one simple line is itself a complete answer. So you get a multitude of answers, each of which will work for specific cases.

"Simplicity has a habit of expanding into catastrophe."
-- Anne McCaffrey, "The Ship who Sang"

In seeking the unattainable, simplicity only gets in the way.
-- Alan J. Perlis

@notorand-it
Copy link

notorand-it commented Dec 12, 2023

Fair.
A general 1-liner, even to a specific git repo, is quite difficult to achieve.
But a 1-liner that can be easily adapted to a number of cases is a different thing and is something much easier to do.
The type of things you can look for here and in any other question-and-answers web sites.

The original 1st post here, was already a Unix shell-based solution, not a question, using 5 different commands, none aimed at JSON parsing and with inexplicably replicated functions between wget and curl. If the output from GitHub were moved to "compact JSON" (no newlines at all) by GitHub itself, then most of those JSON-unaware scripts would stop working.
The original solution, as most of the subsequent replies, has likely been created by merging 2 different sources.

I have shared my (rather limited) knowledge about scripting to get a simple, minimal and reliable 1-liner that can be easily adapted to a large number of cases.
It only uses 2 tools (wget and jq) aimed exactly at their goals (downloading via HTTP and reliably parsing JSON strings).
This is according to the Unix command line art of simplicity, IMHO.

"Life is really simple, but we insist on making it complicated."
-- Confucius

"It is not a daily increase, but a daily decrease. Hack away at the inessentials."
-- Bruce Lee

"If you can't explain it to a six year old, you don't understand it yourself."
-- Albert Einstein

@TheRealMrWicked
Copy link

Here is a solution for Windows, you need to put the repo owner and name, as well as a string to identify the download, the generic version of the command is below.

for /f "tokens=1,* delims=:" %a in ('curl -s https://api.github.com/repos/<Put repo owner and repo name here>/releases/latest ^| findstr "browser_download_url" ^| findstr "<Put identifying string here>"') do (curl -kOL %b)

Example
Putting the repo as notepad-plus-plus/notepad-plus-plus and the identifying string as .x64.exe we get this command:

for /f "tokens=1,* delims=:" %a in ('curl -s https://api.github.com/repos/notepad-plus-plus/notepad-plus-plus/releases/latest ^| findstr "browser_download_url" ^| findstr ".x64.exe"') do (curl -kOL %b)

Which downloads the latest x64 installer of Notepad++ to the current directory.

@Chuckame
Copy link

Chuckame commented Jan 22, 2024

Here is the simplest way of getting the latest version with only curl and basename: Using the Forwarded url by github when accessing /latest:

basename $(curl -Ls -o /dev/null -w %{url_effective} https://github.com/<user>/<repo>/releases/latest)

Here another variant of it with only curl and a pure bash feature:

version=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/<user>/<repo>/releases/latest)
version=${version##*/}

@ivomarino
Copy link

Here is the simplest way of getting the latest version with only curl and basename: Using the Forwarded url by github when accessing /latest:

basename $(curl -Ls -o /dev/null -w %{url_effective} https://github.com/<user>/<repo>/releases/latest)

Here another variant of it with only curl and a pure bash feature:

version=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/<user>/<repo>/releases/latest)
version=${version##*/}

works great

@jessp01
Copy link

jessp01 commented Mar 12, 2024

Using jq to match a release file pattern (modsecurity-v.*.tar.gz$ in this example):

curl -sL https://api.github.com/repos/owasp-modsecurity/ModSecurity/releases/latest| \
jq -r '.assets[] | select(.name? | match("modsecurity-v.*.tar.gz$")) | .browser_download_url'

@healBvdb
Copy link

Another simple command using the fantastic Nushell
http get https://api.github.com/repos/<user>/<repo>/releases/latest | get tag_name

@JonnieCache
Copy link

JonnieCache commented May 22, 2024

here's one for getting the tag name of the latest release:

curl -s https://api.github.com/repos/<REPO>/releases/latest | jq -r '.tag_name'

this is useful for cloning the latest release, eg. with asdf:

local asdf_version=$(curl -s https://api.github.com/repos/asdf-vm/asdf/releases/latest | jq -r '.tag_name')
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch $asdf_version

@spvkgn
Copy link

spvkgn commented Jun 1, 2024

wget one-liner to get release tarball and extract its contents:

wget -qO- 'https://api.github.com/repos/<REPO>/releases/latest' | jq -r '.assets[] | select(.name | match("tar.(gz|xz)")) | .browser_download_url' | xargs wget -qO- | bsdtar -xf -

@Samueru-sama
Copy link

Better alternative that will work even if the json is pretty or not:

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | sed 's/[()",{}]/ /g; s/ /\n/g' | grep "https.*releases/download.*deb"

Using jq -c to turn the json compact and this is what happens:

Old:

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest \
| grep "browser_download_url.*deb" \
| cut -d : -f 2,3 \
| tr -d \"
 https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-amd64.deb
 https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-arm64.deb


curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | jq -c \
| grep "browser_download_url.*deb" \
| cut -d : -f 2,3 \
| tr -d \"
https://api.github.com/repos/jgm/pandoc/releases/155373146,assets_url

Alternative:

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | sed 's/[()",{}]/ /g; s/ /\n/g' | grep "https.*releases/download.*deb"         
https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-amd64.deb
https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-arm64.deb

curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | jq -c | sed 's/[()",{}]/ /g; s/ /\n/g' | grep "https.*releases/download.*deb"
https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-amd64.deb
https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-arm64.deb

Fedora 40 recently changed wget for wget2, and this causes github the send the json compact breaking scripts that were parsing it with grep.

I use gron when it is available, otherwise the sed tricks should work most of the time.

@motdotla
Copy link

This is it

wget https://github.com/aquasecurity/tfsec/releases/latest/download/tfsec-linux-amd64

this is the best solution. thank you @joshjohanning. everything else is unnecessarily complicated for users and could trip them up because of different shell versions and lack of installed libs like jq.

add in a bit of uname magic and all your users are good to go.

curl -L -o dotenvx.tar.gz "https://github.com/dotenvx/dotenvx/releases/latest/download/dotenvx-$(uname -s)-$(uname -m).tar.gz"
tar -xzf dotenvx.tar.gz
./dotenvx help

@bruteforks
Copy link

Since this gist is still very active, here's one I've made recently:

#!/usr/bin/env bash

# Fetch the latest release version
latest_version=$(curl -s https://api.github.com/repos/microsoft/vscode-js-debug/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')

# Remove the 'v' prefix from the version number
version=${latest_version#v}

# Construct the download URL
download_url="https://github.com/microsoft/vscode-js-debug/releases/download/${latest_version}/js-debug-dap-${latest_version}.tar.gz"

# Download the tar.gz file
curl -L -o "js-debug-dap-${version}.tar.gz" "$download_url"

@initiateit
Copy link

initiateit commented Jul 17, 2024

Just curl and grep:

curl -s https://api.github.com/repos/caddyserver/xcaddy/releases/latest | grep '"browser_download_url":' | grep 'amd64.deb' | grep -vE '(\.pem|\.sig)' | grep -o 'https://[^"]*'

https://github.com/caddyserver/xcaddy/releases/download/v0.4.2/xcaddy_0.4.2_linux_amd64.deb

curl -s https://api.github.com/repos/aptly-dev/aptly/releases/latest | grep '"browser_download_url":' | grep 'amd64.deb' | grep -o 'https://[^"]*'

https://github.com/aptly-dev/aptly/releases/download/v1.5.0/aptly_1.5.0_amd64.deb

My apologies if it borrows from other answers.

@adriangalilea
Copy link

dra is making huge strides in simplifying the download process.

@NiceGuyIT thanks for bringing it up.

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