GitHub et la dernière release

Vous avez déjà essayé de récupérer la dernière release (version) d’un outil sur GitHub en ligne de commande ? Aujourd’hui c’est ce qu’on va tenter, aiguisez votre CLI, sortez votre chapeau d’explorateur, prévoyez des bandages ça va crapahuter dur (mais restez chez vous 😁️).

La carte

Dans toute chasse aux trésors, il y a une carte, la nôtre est l’API GitHub. On a même l’endroit exact où est le trésor. Dans un monde parfait tous les développeurs sur GitHub feraient ainsi.

Un magnifique « Latest release » et surtout **aucun numéro de version dans Assets**, à partir de là pour télécharger « toujours » la dernière release :
wget https://github.com/cheat/cheat/releases/latest/download/cheat-linux-amd64.gz

Vous venez de découvrir votre premier trésor, un kinder surprise. Vous sentez pas encore la sueur.

Les coordonnées

Pour récupérer un trésor, il faut connaître son emplacement, ici le numéro de version. On va prendre 3 exemples : ripgrep (api), fd (api), fzf-bin (api).

curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' # v8.0.0
curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | grep -Po '"tag_name": "\K.*?(?=")' # v8.0.0
curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | sed -n 's/.*tag_name":\s"\(.*\)".*/\1/p' | head -1 # v8.0.0
basename $(curl -Ls -o /dev/null -w %{url_effective} https://github.com/sharkdp/fd/releases/latest) # v8.0.0
curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | jq -r '.tag_name' # v8.0.0
curl -s https://api.github.com/repos/junegunn/fzf-bin/releases/latest | jq -r '.tag_name' # 0.21.1
curl -s https://api.github.com/repos/BurntSushi/ripgrep/releases/latest | jq -r '.tag_name' # 12.0.1

Ouais mon gars on bourlingue et on croise les premiers obstacles, quel est le con qui a mis un v (pour version) dans v8.0.0 bordel ! Bon un coup de sed 's/^[[:alpha:]]//' et terminé mais heureusement qu’on est outillé.

L’Aventure

De nombreux aventuriers, débrouillards, casse-cous ont déjà tenté l’aventure. Tous ont laissé une trace, une idée à suivre. Évidemment on se plante, on arrive dans des culs-de-sac, les voyages forment la jeunesse.

curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | jq -r '.assets[0].browser_download_url' # https://github.com/sharkdp/fd/releases/download/v8.0.0/fd-musl_8.0.0_amd64.deb
curl -fsSLI -o /dev/null -w %{url_effective} https://github.com/sharkdp/fd/releases/latest && echo # https://github.com/sharkdp/fd/releases/tag/v8.0.0

Plusieurs chemins, un même trésor. On peut le trouver de nombreuses manières et justement on va débroussailler à coup de grep, sed, awk, cut, jq, curl, wget. Pas que ce soit nécessaire de connaître tous les chemins mais un aventurier sans cicatrice c’est Dora l’exploratrice.

curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | jq -r '.assets[] | select(.name | contains("fd_") and contains("amd64.deb")) | .browser_download_url' | wget -qi -
curl -s https://api.github.com/repos/BurntSushi/ripgrep/releases/latest | awk -F'["]' '/browser_download_url.*ripgrep_.*_amd64.deb/{print $(NF-1)}' | wget -qi -
curl -s https://api.github.com/repos/BurntSushi/ripgrep/releases/latest | grep "browser_download_url.*ripgrep_.*_amd64.deb" | cut -d '"' -f 4 | wget -qi -
curl -s https://api.github.com/repos/junegunn/fzf-bin/releases/latest | grep "browser_download_url.*fzf.*linux_amd64.tgz" | cut -d '"' -f 4 | wget -qi -
curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | grep "browser_download_url.*fd_.*amd64.deb" | cut -d '"' -f 4 | wget -qi -

Le mieux est peut-être encore d’avoir une carte interactive avec livraison à la maison… non je déconne, on veut en baver, pas de repos pour les braves.

curl -s https://api.github.com/repos/sharkdp/fd/releases/latest | grep "browser_download_url" | cut -d '"' -f 4 | fzf | wget -qi -

Exploration

Je vous apprends rien en disant que les purs partent sans carte et sans coordonnées, seulement avec leur bite et leur couteau.

wget -q https://github.com"$(curl -s https://github.com/sharkdp/fd/releases | sed -n 's/.*href="\([^"]*\).*/\1/p' | grep -m1 'fd_.*_amd64.deb')"
wget -q https://github.com"$(curl -s https://github.com/sharkdp/fd/releases | sed -n 's/.*href="\(.*fd_.*_amd64.deb\).*/\1/p' | head -1)"
wget -q https://github.com"$(curl -s https://github.com/sharkdp/fd/releases | awk -F'"' '/fd_.*_amd64.deb/{print $2;exit}')"
wget -q https://github.com"$(curl -s https://github.com/sharkdp/fd/releases | grep -m1 'fd_.*_amd64.deb' | cut -d '"' -f 2)"

Un sudo apt install lynx et on est prêts à chevaucher un animal sauvage qui s’apprivoise aisément toutefois. Lynx est un navigateur web en mode texte. lynx -dump -listonly affiche la liste des liens (par défaut numérotés) d’une page, pour désactiver la numérotation des liens -nonumbers.

lynx -dump -listonly https://github.com/sharkdp/fd/releases | awk '/fd_.*_amd64.deb/{print $2;exit}'
lynx -dump -listonly -nonumbers https://github.com/junegunn/fzf-bin/releases | grep -m1 'fzf.*linux_amd64.tgz'
wget -q $(lynx -dump -listonly -nonumbers https://github.com/BurntSushi/ripgrep/releases | grep -m1 'ripgrep_.*_amd64.deb')

Magie blanche

grep -m1 # On sort de la recherche au premier résultat, sur les pages releases la version la plus récente est la première en partant du haut de la page
cut -d '"' -f 4 # On récupère le 4ème champ, le délimiteur est "
wget -qi - # On télécharge silencieusement -q depuis l’entrée standard -i -
awk -F'"' '/fd_.*_amd64.deb/{print $2;exit}' # On récupère le second champ print $2 des lignes matchant fd_.*_amd64.deb (fd_nimportequoi_amd64.deb), on sort de la recherche au premier résultat exit, le délimiteur est "
jq -r '.assets[] | select(.name | contains("fd_") and contains("amd64.deb")) | .browser_download_url' # Certains mystères ne doivent pas être dévoilés

La fin du voyage

Perso j’ai une préférence pour lynx (clair, simple, court et efficace avec le grep) donc j’utilise ces one-liners.

wget -q $(lynx -dump -listonly -nonumbers https://github.com/BurntSushi/ripgrep/releases | grep -m1 'ripgrep_.*_amd64.deb') && sudo dpkg -i ripgrep*.deb && rm ripgrep*.deb
wget -q $(lynx -dump -listonly -nonumbers https://github.com/sharkdp/fd/releases | grep -m1 'fd_.*_amd64.deb') && sudo dpkg -i fd*.deb && rm fd*.deb
wget -q $(lynx -dump -listonly -nonumbers https://github.com/junegunn/fzf-bin/releases | grep -m1 'fzf.*linux_amd64.tgz') && tar -xzf fzf*.tgz && rm fzf*.tgz && sudo mv fzf /usr/bin/fzf && sudo chown root: /usr/bin/fzf

À noter que parfois la release la plus récente peut être une alpha, beta, rc (release candidate)…, il suffit de rajouter | grep -v 'alpha\|beta\|rc' par exemple si on désire la dernière release stable.

Vous me direz pourquoi tout ça ? Pour l’aventure, pour s’amuser et apprendre, parce que je me demandais comment faire depuis un moment.

Déjà 6 avis pertinents dans GitHub et la dernière release

Les commentaires sont fermés.