-
-
Save lukechilds/a83e1d7127b78fef38c2914c4ececc3c to your computer and use it in GitHub Desktop.
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 |
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! 👍
In MacOS, the built-in grep
command has not -P
option.
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
❯
Example Link: https://github.com/valinet/ExplorerPatcher/releases/latest/download/ep_setup.exe
Replace "ep_setup.exe" with whatever object name you want.
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.
With the last update, the above breaks for me. I'm now using this:
latest_version_raw="$(curl -s https://api.github.com/repos/$owner_repo/releases | grep -m 1 "html_url" | rev | cut - d/ -f1 | rev )"
latest_version="${latest_version_raw%??}" # remove last 2 characters
Here's an example with wget & jq:
REPO="..."
VERSION=$(wget -q -O- https://api.github.com/repos/${REPO}/releases/latest | jq -r '.name')
Here's an example with wget & jq:
REPO="..." VERSION=$(wget -q -O- https://api.github.com/repos/${REPO}/releases/latest | jq -r '.name')
that works great! but if prefer tag name instead of release name, use:
.tag_name
for how todo this on GitLab site, see my gist here:
https://gist.github.com/roelds/b2cd9cc2ba6c7887ddaf6bde2ef7ef50
One-liner using only curl + grep:
curl --silent "https://api.github.com/repos/${REPO}/releases/latest" | grep -Po "(?<=\"tag_name\": \").*(?=\")"
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. Sinceuname -a
showsx86_64
on 64 bit installs I've often struggled with how to detect 32/64 bit and use the correctxxx_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.