Question

I'd like to have "Download Latest Version" button on my website which would represent the link to the latest release (stored at GitHub Releases). I tried to create release tag named "latest", but it became complicated when I tried to load new release (confusion with tag creation date, tag interchanging, etc.). Updating download links on my website manually is also a time-consuming and scrupulous task. I see the only way - redirect all download buttons to some html, which in turn will redirect to the actual latest release.

Note that my website is hosted at GitHub Pages (static hosting), so I simply can't use server-side scripting to generate links. Any ideas?

Was it helpful?

Solution 2

Github now provides a "Latest release" button on the release page of a project, after you have created your first release.

In the example you gave, this button links to https://github.com/reactiveui/ReactiveUI/releases/latest

OTHER TIPS

You don't need any scripting to generate a download link for the latest release. Simply use this format:

https://github.com/:owner/:repo/zipball/:branch

Examples:

https://github.com/webix-hub/tracker/zipball/master
https://github.com/iDoRecall/selection-menu/zipball/gh-pages

If for some reason you want to obtain a link to the latest release download, including its version number, you can obtain that from the get latest release API:

GET /repos/:owner/:repo/releases/latest

Example:

$.get('https://api.github.com/repos/idorecall/selection-menu/releases/latest', function (data) {
  $('#result').attr('href', data.zipball_url);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="result">Download latest release (.ZIP)</a>

Since February 18th, 2015, the GitHUb V3 release API has a get latest release API.

GET /repos/:owner/:repo/releases/latest

See also "Linking to releases".


Still, the name of the asset can be tricky.

Git-for-Windows, for instance, requires a command like:

curl -IkLs -o NUL -w %{url_effective} \
   https://github.com/git-for-windows/git/releases/latest|\
grep -o "[^/]*$"| sed "s/v//g"|\
xargs -I T echo \
  https://github.com/git-for-windows/git/releases/download/vT/PortableGit-T-64-bit.7z.exe \
  -o PortableGit-T-64-bit.7z.exe| \
sed "s/.windows.1-64/-64/g"|sed "s/.windows.\(.\)-64/.\1-64/g"|\
xargs curl -kL

The first 3 lines extract the latest version 2.35.1.windows.2
The rest will build the right URL

https://github.com/git-for-windows/git/releases/download/
        v2.35.1.windows.2/PortableGit-2.35.1.2-64-bit.7z.exe
        ^^^^^^^^^^^^^^^^^             ^^^^^^^^^

Maybe could you use some client-side scripting and dynamically generate the target of the link by invoking the GitHub api, through some JQuery magic?

The Releases API exposes a way to retrieve the list of all the releases from a repository. For instance, this link return a Json formatted list of all the releases of the ReactiveUI project.

Extracting the first one would return the latest release.

Within this payload:

  • The html_url attribute will hold the first part of the url to build (ie. https://github.com/{owner}/{repository}/releases/{version}).

  • The assets array will list of the downloadable archives. Each asset will bear a name attribute

Building the target download url is only a few string operations away.

  • Insert the download/ keyword between the releases/ segment from the html_url and the version number
  • Append the name of the asset to download

Resulting url will be of the following format: https://github.com/{owner}/{repository}/releases/download/{version}/name_of_asset

For instance, regarding the Json payload from the link ReactiveUI link above, we've got html_url: "https://github.com/reactiveui/ReactiveUI/releases/5.99.0" and one asset with name: "ReactiveUI.6.0.Preview.1.zip".

As such, the download url is https://github.com/reactiveui/ReactiveUI/releases/download/5.99.0/ReactiveUI.6.0.Preview.1.zip

You can use the following where:

  • ${Organization} as the GitHub user or organization
  • ${Repository} is the repository name

curl -L https://api.github.com/repos/${Organization}/${Repository}/tarball > ${Repository}.tar.gz

The top level directory in the .tar.gz file has the sha hash of the commit in the directory name which can be a problem if you need an automated way to change into the resulting directory and do something.

The method below will strip this out, and leave the files in a folder with a predictable name.

mkdir ${Repository} curl -L https://api.github.com/repos/${Organization}/${Repository}/tarball | tar -zxv -C ${Repository} --strip-components=1

If you using PHP try follow code:

function getLatestTagUrl($repository, $default = 'master') {
    $file = @json_decode(@file_get_contents("https://api.github.com/repos/$repository/tags", false,
        stream_context_create(['http' => ['header' => "User-Agent: Vestibulum\r\n"]])
    ));

    return sprintf("https://github.com/$repository/archive/%s.zip", $file ? reset($file)->name : $default);
}

Function usage example

echo '<a href="' .getLatestTagUrl('OzzyCzech/vestibulum') .'">Download</a>';

As I didn't see the answer here, but it was quite helpful for me while running continuous integration tests, this one-liner that only requires you to have curl will allow to search the Github repo's releases to download the latest version

https://gist.github.com/steinwaywhw/a4cd19cda655b8249d908261a62687f8

I use it to run PHPSTan on our repository using the following script

https://gist.github.com/rvanlaak/7491f2c4f0c456a93f90e31774300b62

If you are trying to download form any linux — even old or tiny versions — or are trying to download from a bash script then the failproof way is using this command:

wget https://api.github.com/repos/$OWNER/$REPO/releases/latest -O - | awk -F \" -v RS="," '/browser_download_url/ {print $(NF-1)}' | xargs wget

do not forget to replace $OWNER and $REPO with the right owner and repository names. The command downloads a json page with the data of the latest release. then awk gets the value from the browser_download_url key.

If you are in a really old linux or a tiny embedded system with a small wget, the download name can be a problem. In such case you can always use the ultra-reliable:

URL=$(wget https://api.github.com/repos/$OWNER/$REPO/releases/latest -O - | awk -F \" -v RS="," '/browser_download_url/ {print $(NF-1)}'); wget $URL -O $(basename "$URL")

As noted by @Dan Dascalescu in a comment to accepted answer, there are some projects (roughly 30%) which do not bother to file formal releases, so neither "Latest release" button nor /releases/latest API call would return useful data.

To reliably fetch the latest release for a GitHub project, you can use lastversion.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top