4

Shell - Get latest release from GitHub · GitHub

 2 years ago
source link: https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

lestofante commented on May 15, 2020

edited

if you need a more universal answer, you can use git ls-remote --tags https://github.com/rust-lang/rust.git to get the list of all the tags from the remote without need to clone.

artheus commented on May 17, 2020

edited

@lestofante That is also a very good suggestion! But this solution will only work if there are no more tags than just the release version tags. And as long as release versions are tracked as tags in the repository.

**edit** It would probably not differantiate between pre-releases and stable releases either.

From what I can tell, the github. com/github/hub command line command will help us a lot with these things in the near future!

@artheus yes I focus on be able to support any git repo more than specific github functionality.

Just some little correction

will only work if there are no more tags

in that case you can add some grep/awk to extrapolate only what you need.
Yes it will break if upstream change naming scheme, but on the other hand it work with any git repo, not only github

And as long as release versions are tracked as tags in the repository

i am pretty sure github (and others) create a tag for every release automatically and you cant opt-out

It would probably not differantiate between pre-releases and stable releases either.

yes you are right!
(My suggestion is to keep thin info in your naming scheme of release, so even just looking at that you know what is going on, or if you move to different service or working offline you still have those info, but of course everyone is king of its own repo)

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.

Good tip, thx! but...

might not work as git tag sorts alphabetically by default:

$ git tag
v12.6
v12.6.1
v12.7
v12.8
v2.5
v2.5.1
v2.5.2
v2.5.3

I'm using git tag --sort=committerdate | tail -1 to have it sorted by the date of the commit they're tagged to.

ackbyte commented on Aug 17, 2020

edited

Probably not Pythonic but Python way:

import requests
url = 'https://github.com/roundcube/roundcubemail/releases/latest'
r = requests.get(url)
version = r.url.split('/')[-1]

print(version)

Source: https://gist.github.com/zeldor/604a7817f9d142e908335e041ece0718

Very nice.
Good job !
Thanks

if you need a more universal answer, you can use git ls-remote --tags https://github.com/rust-lang/rust.git to get the list of all the tags from the remote without need to clone.

Nice! This is the one that works best for me (I prefer not depending on jq and the curl <url>/releases/latest based answers only yield <url>/releases but not the tag - maybe because I didn't explicitly create releases?).

Anyway, just to make it even a little bit easier to use:

lastrelease() { git ls-remote --tags "$1" | cut -d/ -f3- | tail -n1; }

lastrelease https://github.com/USER/REPO

You may also want to add another | grep or | sed to the pipe to filter for desired tagname patterns (e.g. exclude prereleases).

git ls-remote --refs --sort="version:refname" --tags $repo | cut -d/ -f3-|tail -n1

Must say I heart the github community!
There are always people who takes the challenge to make something better, and shares their findings!
Keep up the great work everyone!

In Fish you can use string manipulation that is native, so no other dependencies than curl:

function get_latest_release_version \
    --argument-names user_repo

    curl \
        --silent \
        "https://api.github.com/repos/$user_repo/releases/latest" \
    | string match --regex  '"tag_name": "\K.*?(?=")'
end

Usage:

❯ get_latest_release_version "rafaelrinaldi/pure"
v3.0.0

Why not use jq?

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

CybotTM commented on Jan 20, 2021

edited

Example to get highest version, not just latest - because an LTS bugfix 1.2.3 could be released after a new major 3.x version

curl https://api.github.com/repos/mautic/mautic/releases -s | jq -r .[].tag_name | grep '^[0-9]\.[0-9]*\.[0-9]*$' | sort -nr | head -n
1

or find latest version for a specific major version:

curl https://api.github.com/repos/mautic/mautic/releases -s | jq -r .[].tag_name | grep '^2\.[0-9]*\.[0-9]*$' -m1
curl https://api.github.com/repos/mautic/mautic/releases -s | jq -r .[].tag_name | grep '^3\.[0-9]*\.[0-9]*$' -m1

Hi,
I made a version without sed, only using grep.
Maybe it's useful...

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

Thanks, for sharing the great idea!

Thanks!

oneliner to get link to the source archive of latest release

curl -s https://github.com/USER/REPO/releases | 
    grep -m1 -Eo "archive/refs/tags/[^/]+\.tar\.gz" | 
        xargs printf "https://github.com/USER/REPO/%s"

command to clone the source of latest release to the current folder w/o downloading archive to local disk

ghRepoCloneLatestRelease ()
{
    [[ ${1} =~ / ]] &&
        wget -qO- https://github.com/${1}/$(curl -s https://github.com/${1}/releases |
            grep -m1 -Eo "archive/refs/tags/[^/]+\.tar\.gz") |
                tar --strip-components=1 -xzv >/dev/null
}

usage: ghRepoCloneLatestRelease user/repo

@juliy V. Chirkov Thanks a lot!

@Ishidres, you're welcome tipping_hand_woman

$ get_latest_release "ipfs/go-ipfs"
v0.8.0

nice. Thanks a lot.

@juliyvchirkov hi, How can i get the all latest release (including windows or linux etc.) and download it to a folder?
i mean i want to write a script to check releases,if they does not exist or they are older, my script will download update it; and if they are not change, not download?

curl -s https://api.github.com/repos/user/reop/releases/latest |  /root/jq-linux64 --raw-output '.assets[] | .browser_download_url' | xargs wget 

pwillis-els commented on Jun 17, 2021

edited

If you don't want to get just the last release, but all releases with pagination, try this. It's very ugly, I hope somebody can simplify it with awk or something smile

next_url="https://api.github.com/repos/Versent/saml2aws/releases"
while [ -n "$next_url" ] ; do
    out="$(curl -ifsSL "$next_url")" ; echo "$out" | awk -F '"' '/"tag_name":/{print $4}' | sed -e 's/^v//'
    next_url="$(echo "$out" | grep '^link:' \
        | sed -e 's/link: //; s/, /\n/g; s/[<>]//g; s/; rel/ rel/g; s/\(https:\/\/[^ ]\+\) rel="\([a-z]\+\)"/\2 \1/g' \
        | awk '/next / { print $2}')"
done

If you do use pagination, you might prefer to use the /tags API endpoint. The data returned is about 100x smaller than /releases, and for the most part the tag name and release names are the same. Same code here, just a different URI, and use "name": instead of "tag_name": above.

Anyone have a GraphQL query for this?

I've used a couple of the above snippets/tools for the initial download of the GitHub CLI, but with the GitHub CLI, you can use gh release download to download releases from a specific tag, or if you don't supply a tag at all it will use the latest release (and no, latest as the tag criteria doesn't work unless it actually exists in the repository).

https://cli.github.com/manual/gh_release_download

My favorite practical example might be using gh to download the latest version of itself. I also learned a new trick for Debian/Ubuntu at least. Since uname -a shows x86_64 on 64 bit installs I've often struggled with how to detect 32/64 bit and use the correct xxx_linux_amd64.deb where since it is a deb file we can pretty safely assume we are installing on Linux, but for a .tar.gz it might be for Solaris or BSD or Linux, so we really only care about the arch.

You can see I don't supply a tag before or after the repo, and I don't quote the * otherwise it triggers the shell to try and parse it.

gh release download -D /tmp -R cli/cli --pattern *$(dpkg --print-architecture).deb
sudo apt install /tmp/gh_*

For PowerShell/Windows users, a better approach:

((Invoke-WebRequest -Uri https://api.github.com/repos/USER/REPO/releases/latest).Content | ConvertFrom-Json).tag_name

+1 for @spoelstraethan's suggestion! gh is easy to use & makes downloading the latest release asset an absolute breeze.

Would suggest using that instead of reinventing the wheel & using hacky Shell scripts on any day! And the best part it's available on Homebrew & on Windows so no worries about cross-platform support.

Indeed gh is easier to use with no work-around, but I found this gist is useful for lightweight purposes such as Docker and CIs. Thanks!

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! +1

In MacOS, the built-in grep command has not -P option.

meramsey commented on Apr 14

Another mostly reusable one if you just want the latest deb

owner_repo='igniterealtime/Spark'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \")"; echo $latest_version_url; basename $latest_version_url ; wget --content-disposition $latest_version_url

Example:

❯ owner_repo='igniterealtime/Spark'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \")"; echo $latest_version_url; basename $latest_version_url ; wget -q --content-disposition $latest_version_url
https://github.com/igniterealtime/Spark/releases/download/v3.0.0-beta/spark_3_0_0-beta.deb
spark_3_0_0-beta.deb
~  took 1m46s  at 20:14:43 

❯ 

meramsey commented on Jun 3

Probably not Pythonic but Python way:

import requests
url = 'https://github.com/roundcube/roundcubemail/releases/latest'
r = requests.get(url)
version = r.url.split('/')[-1]

print(version)

Source: https://gist.github.com/zeldor/604a7817f9d142e908335e041ece0718

Made into a function and returns empty for the ones without it.

def get_github_latest_release(repo_path):
    import requests

    url = f"https://github.com/{repo_path}/releases/latest"
    r = requests.get(url, headers={"Content-Type": "application/vnd.github.v3+json"})
    release = r.url.split("/")[-1]
    if release in ["releases", "latest"]:
        release = ""

    return release

works nicely for ones with releases

github_repos = [
    "https://github.com/OpenVPN/openvpn",
    "https://github.com/atom/atom",
    "https://github.com/eneshecan/whatsapp-for-linux",
    "https://github.com/igniterealtime/Openfire",
    "https://github.com/igniterealtime/Spark",
    "https://github.com/jitsi/jitsi-meet",
    "https://github.com/jitsi/jitsi-meet-prosody",
    "https://github.com/jitsi/jitsi-meet-turnserver",
    "https://github.com/jitsi/jitsi-meet-web-config",
    "https://github.com/jitsi/jitsi-videobridge2",
    "https://github.com/mumble-voip/mumble",
    "https://github.com/pjsip/pjproject/",
    "https://github.com/pydio/pydio-core",
    "https://github.com/signalapp/Signal-Desktop",
    "https://github.com/sleuthkit/autopsy",
    "https://github.com/sleuthkit/sleuthkit",
    "https://github.com/ultravnc/ultravnc",
]


def get_repo_path(link):
    return link.replace("https://github.com/", "").strip().rstrip("/")


def get_repo_pkg(repo):
    return repo.split("/")[-1]


def get_repos_dict_from_urls(urls):
    packages = {}
    for repo in github_repos:
        pkg_name = get_repo_pkg(get_repo_path(repo))
        pkg_path = get_repo_path(repo)
        packages[pkg_name] = {
            "name": pkg_name,
            "repo_path": pkg_path,
            "url": repo,
            "latest_release": get_github_latest_release(pkg_path),
        }
    return packages


packages = get_repos_dict_from_urls(github_repos)
pprint(packages)

Result:

{'Openfire': {'latest_release': 'v4.7.1',
              'name': 'Openfire',
              'repo_path': 'igniterealtime/Openfire',
              'url': 'https://github.com/igniterealtime/Openfire'},
 'Signal-Desktop': {'latest_release': 'v5.45.0',
                    'name': 'Signal-Desktop',
                    'repo_path': 'signalapp/Signal-Desktop',
                    'url': 'https://github.com/signalapp/Signal-Desktop'},
 'Spark': {'latest_release': 'v3.0.0-beta',
           'name': 'Spark',
           'repo_path': 'igniterealtime/Spark',
           'url': 'https://github.com/igniterealtime/Spark'},
 'atom': {'latest_release': 'v1.60.0',
          'name': 'atom',
          'repo_path': 'atom/atom',
          'url': 'https://github.com/atom/atom'},
 'autopsy': {'latest_release': 'autopsy-4.19.3',
             'name': 'autopsy',
             'repo_path': 'sleuthkit/autopsy',
             'url': 'https://github.com/sleuthkit/autopsy'},
 'jitsi-meet': {'latest_release': 'jitsi-meet_7287',
                'name': 'jitsi-meet',
                'repo_path': 'jitsi/jitsi-meet',
                'url': 'https://github.com/jitsi/jitsi-meet'},
 'jitsi-meet-prosody': {'latest_release': '',
                        'name': 'jitsi-meet-prosody',
                        'repo_path': 'jitsi/jitsi-meet-prosody',
                        'url': 'https://github.com/jitsi/jitsi-meet-prosody'},
 'jitsi-meet-turnserver': {'latest_release': '',
                           'name': 'jitsi-meet-turnserver',
                           'repo_path': 'jitsi/jitsi-meet-turnserver',
                           'url': 'https://github.com/jitsi/jitsi-meet-turnserver'},
 'jitsi-meet-web-config': {'latest_release': '',
                           'name': 'jitsi-meet-web-config',
                           'repo_path': 'jitsi/jitsi-meet-web-config',
                           'url': 'https://github.com/jitsi/jitsi-meet-web-config'},
 'jitsi-videobridge2': {'latest_release': '',
                        'name': 'jitsi-videobridge2',
                        'repo_path': 'jitsi/jitsi-videobridge2',
                        'url': 'https://github.com/jitsi/jitsi-videobridge2'},
 'mumble': {'latest_release': 'v1.4.230',
            'name': 'mumble',
            'repo_path': 'mumble-voip/mumble',
            'url': 'https://github.com/mumble-voip/mumble'},
 'openvpn': {'latest_release': '',
             'name': 'openvpn',
             'repo_path': 'OpenVPN/openvpn',
             'url': 'https://github.com/OpenVPN/openvpn'},
 'pjproject': {'latest_release': '2.12.1',
               'name': 'pjproject',
               'repo_path': 'pjsip/pjproject',
               'url': 'https://github.com/pjsip/pjproject/'},
 'pydio-core': {'latest_release': '',
                'name': 'pydio-core',
                'repo_path': 'pydio/pydio-core',
                'url': 'https://github.com/pydio/pydio-core'},
 'sleuthkit': {'latest_release': 'sleuthkit-4.11.1',
               'name': 'sleuthkit',
               'repo_path': 'sleuthkit/sleuthkit',
               'url': 'https://github.com/sleuthkit/sleuthkit'},
 'ultravnc': {'latest_release': '',
              'name': 'ultravnc',
              'repo_path': 'ultravnc/ultravnc',
              'url': 'https://github.com/ultravnc/ultravnc'},
 'whatsapp-for-linux': {'latest_release': 'v1.4.3',
                        'name': 'whatsapp-for-linux',
                        'repo_path': 'eneshecan/whatsapp-for-linux',
                        'url': 'https://github.com/eneshecan/whatsapp-for-linux'}}

owner_repo='igniterealtime/Spark'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d ")"; echo $latest_version_url; basename $latest_version_url ; wget --content-disposition $latest_version_url

Thanks a lot! Although it's possible to just use curl instead of wget:
owner_repo='owner/name'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest| grep "browser_download_url.*extension" | cut -d : -f 2,3 | tr -d \")"; echo $latest_version_url; basename $latest_version_url ; curl -X GET $latest_version_url -LO or -Lo name.extension

owner_repo='igniterealtime/Spark'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d ")"; echo $latest_version_url; basename $latest_version_url ; wget --content-disposition $latest_version_url

Thanks a lot! Although it's possible to just use curl instead of wget: owner_repo='owner/name'; latest_version_url="$(curl -s https://api.github.com/repos/$owner_repo/releases/latest| grep "browser_download_url.*extensions" | cut -d : -f 2,3 | tr -d \")"; echo $latest_version_url; basename $latest_version_url ; curl -X GET $latest_version_url -LO or -Lo name.extension

Awesome thanks for sharing. That is cool always wondered how to do that in curl but never bothered to look. Appreciate the share and explanation.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK