Noms de release lisibles, et incompatibles avec l'updater 0.7

ajean-linux, ajean-linux-arm, ajean-macos, ajean-macos-arm,
ajean-windows.exe, ajean-windows-arm.exe.

Le schema ne correspond plus a ajean-<GOOS>-<GOARCH> que cherchent les 0.7 :
leur mise a jour automatique ne trouve aucun asset et echoue sans rien
remplacer. C'est voulu — sinon elle installait le binaire 0.8 sans migrer, le
service de lien repartait en boucle d'echec sur « link serve » disparu et le
moteur perdait sa configuration.

assetNameFor est isolee pour etre testee sur les six plateformes, plus un test
qui verifie explicitement l'absence de collision avec le schema 0.7.
This commit is contained in:
nathaninline committed 2026-08-07 19:30:26 +02:00
1 parent 664b13753b
commit 071caea516
6 files changed
+92 -35

No files matched your search

+5 -5
View File
@@ -17,7 +17,7 @@ jobs:
run: |
mkdir -p dist
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -trimpath -ldflags="-s -w" -o dist/ajean-darwin-arm64 ./cmd/ajean
go build -trimpath -ldflags="-s -w" -o dist/ajean-macos-arm ./cmd/ajean
mkdir -p /tmp/ajean.iconset
sips -s format png 'cmd/ajean/icon.ico' --out /tmp/icon.png >/dev/null 2>&1 || true
for s in 16 32 128 256 512; do
@@ -26,7 +26,7 @@ jobs:
iconutil -c icns /tmp/ajean.iconset -o /tmp/ajean.icns >/dev/null 2>&1 || true
app="dist/AJEAN.app"
mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources"
cp dist/ajean-darwin-arm64 "$app/Contents/MacOS/ajean"
cp dist/ajean-macos-arm "$app/Contents/MacOS/ajean"
chmod +x "$app/Contents/MacOS/ajean"
cp /tmp/ajean.icns "$app/Contents/Resources/ajean.icns" 2>/dev/null || true
printf '%s\n' \
@@ -44,9 +44,9 @@ jobs:
'<key>NSHighResolutionCapable</key><true/>' \
'</dict></plist>' > "$app/Contents/Info.plist"
codesign --force --deep -s - "$app" || true
(cd dist && zip -qry AJEAN-macos-arm64.zip AJEAN.app && rm -rf AJEAN.app)
(cd dist && zip -qry AJEAN-macos-arm.zip AJEAN.app && rm -rf AJEAN.app)
ls -l dist
- uses: actions/upload-artifact@v4
with:
name: AJEAN-macos-arm64
path: dist/AJEAN-macos-arm64.zip
name: AJEAN-macos-arm
path: dist/AJEAN-macos-arm.zip
+20 -17
View File
@@ -29,11 +29,11 @@ jobs:
mkdir -p dist
# arm64 = natif ; amd64 = cross avec le SDK universel (-arch x86_64).
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -trimpath -ldflags="-s -w" -o dist/ajean-darwin-arm64 ./cmd/ajean
go build -trimpath -ldflags="-s -w" -o dist/ajean-macos-arm ./cmd/ajean
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
CGO_CFLAGS="-arch x86_64" CGO_LDFLAGS="-arch x86_64" \
go build -trimpath -ldflags="-s -w" -o dist/ajean-darwin-amd64 ./cmd/ajean
file dist/ajean-darwin-*
go build -trimpath -ldflags="-s -w" -o dist/ajean-macos ./cmd/ajean
file dist/ajean-macos*
- name: bundles AJEAN.app
run: |
# Un binaire nu double-cliqué ouvrirait le Terminal. On publie donc
@@ -51,10 +51,10 @@ jobs:
done
iconutil -c icns /tmp/ajean.iconset -o /tmp/ajean.icns
v="${GITHUB_REF_NAME#v}"
for arch in amd64 arm64; do
app="dist/mac-$arch/AJEAN.app"
for bin in ajean-macos ajean-macos-arm; do
app="dist/bundle-$bin/AJEAN.app"
mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources"
cp "dist/ajean-darwin-$arch" "$app/Contents/MacOS/ajean"
cp "dist/$bin" "$app/Contents/MacOS/ajean"
chmod +x "$app/Contents/MacOS/ajean"
cp /tmp/ajean.icns "$app/Contents/Resources/ajean.icns" 2>/dev/null || true
printf '%s\n' \
@@ -76,12 +76,8 @@ jobs:
# Signature ad-hoc : sans elle, macOS refuse purement et simplement
# de lancer un binaire arm64 non signé (pas juste un avertissement).
codesign --force --deep -s - "$app" || true
(cd "dist/mac-$arch" && zip -qry "../AJEAN-macos-$arch.zip" AJEAN.app)
# Nom hérité conservé : les liens de téléchargement déjà publiés
# (site, mails, messages) pointent dessus et doivent continuer de
# fonctionner. Même contenu, deux noms.
cp "dist/AJEAN-macos-$arch.zip" "dist/AJEAN-macos-$arch.zip"
rm -rf "dist/mac-$arch"
(cd "dist/bundle-$bin" && zip -qry "../AJEAN-${bin#ajean-}.zip" AJEAN.app)
rm -rf "dist/bundle-$bin"
done
ls -l dist
- uses: actions/upload-artifact@v4
@@ -100,13 +96,20 @@ jobs:
- name: build Linux + Windows
run: |
mkdir -p dist
for t in linux/amd64 linux/arm64 windows/amd64 windows/arm64; do
os=${t%/*}; arch=${t#*/}; ext=""; ldflags="-s -w"
# Noms d'asset : ajean-<os>[-arm][.exe]. Volontairement lisibles, et
# volontairement DIFFÉRENTS du schéma ajean-<GOOS>-<GOARCH> des 0.7 :
# leur mise à jour automatique ne trouve alors aucun asset et échoue
# sans rien remplacer, au lieu d'installer un binaire 0.8 sur une
# machine encore agencée en 0.7 (voir updateAssetName, sys_update.go).
for t in linux/amd64:ajean-linux linux/arm64:ajean-linux-arm \
windows/amd64:ajean-windows.exe windows/arm64:ajean-windows-arm.exe; do
target=${t%%:*}; name=${t#*:}
os=${target%/*}; arch=${target#*/}; ldflags="-s -w"
# Windows : sous-système GUI → aucune console noire au double-clic
# (l'app se rattache à la console du terminal parent si lancée en CLI).
[ "$os" = windows ] && { ext=".exe"; ldflags="$ldflags -H=windowsgui"; }
[ "$os" = windows ] && ldflags="$ldflags -H=windowsgui"
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
go build -trimpath -ldflags="$ldflags" -o "dist/ajean-$os-$arch$ext" ./cmd/ajean
go build -trimpath -ldflags="$ldflags" -o "dist/$name" ./cmd/ajean
done
- uses: actions/download-artifact@v4
with:
@@ -114,7 +117,7 @@ jobs:
path: dist
- name: SHA256SUMS
run: |
chmod +x dist/ajean-darwin-*
chmod +x dist/ajean-macos*
(cd dist && sha256sum ajean-* *.zip > SHA256SUMS)
ls -l dist && cat dist/SHA256SUMS
- name: publier la release
+4 -4
View File
@@ -41,12 +41,12 @@ Aucune dépendance à l'exécution, aucun flag CMake à retenir, aucun conteneur
### 1. Le binaire
```bash
curl -L -o ajean https://github.com/nathaninline/ajean/releases/latest/download/ajean-linux-amd64
curl -L -o ajean https://github.com/nathaninline/ajean/releases/latest/download/ajean-linux
chmod +x ajean
sudo mv ajean /usr/local/bin/ajean
```
(Autres cibles sur la page [Releases](../../releases) : Linux, macOS et Windows, en amd64 et arm64.)
Les binaires publiés : `ajean-linux`, `ajean-linux-arm`, `ajean-macos`, `ajean-macos-arm`, `ajean-windows.exe`, `ajean-windows-arm.exe` — le suffixe `-arm` désigne l'arm64, l'absence de suffixe l'x86-64.
### 2. Installation et compilation du moteur
@@ -231,11 +231,11 @@ ajean status
## macOS
La page [Releases](../../releases) publie `AJEAN-macos-arm64.zip` / `AJEAN-macos-amd64.zip`, un bundle **`AJEAN.app`**. Dézipper, glisser dans *Applications*, ouvrir : l'interface démarre sur `http://localhost:8090`, s'ouvre dans le navigateur, et l'icône se pose dans la **barre de menus**. Pas de fenêtre de Terminal, pas d'icône dans le Dock.
La page [Releases](../../releases) publie `AJEAN-macos-arm.zip` (Apple Silicon) et `AJEAN-macos.zip` (Intel), un bundle **`AJEAN.app`**. Dézipper, glisser dans *Applications*, ouvrir : l'interface démarre sur `http://localhost:8090`, s'ouvre dans le navigateur, et l'icône se pose dans la **barre de menus**. Pas de fenêtre de Terminal, pas d'icône dans le Dock.
L'application n'est signée qu'en ad-hoc : au premier lancement, faire **clic droit → Ouvrir**.
Pour un usage en ligne de commande, prendre le binaire nu `ajean-darwin-arm64` : hors bundle, il conserve son comportement CLI. Les services passent par **launchd**.
Pour un usage en ligne de commande, prendre le binaire nu `ajean-macos-arm` : hors bundle, il conserve son comportement CLI. Les services passent par **launchd**.
## Accès distant via ajean.link
+4 -2
View File
@@ -1,6 +1,6 @@
Le renommage est terminé. Plus rien ne s'appelle jean : ni le binaire, ni les services, ni les variables, ni les dossiers. Et le dossier de données, qui s'était couvert d'une douzaine de petits fichiers d'état, tient désormais dans six dossiers et une base.
**La reprise d'une installation 0.7 tient en une commande : `sudo ajean install`.** Il déplace les dossiers, reprend les réglages en base, désactive les anciens services et installe les nouveaux. Rien n'est supprimé : presets, mémoire et modèles sont déplacés, les anciens fichiers d'état rangés dans `avant-0.8/`. C'est le seul code de compatibilité de la version, isolé dans un fichier prévu pour être supprimé.
**Une installation 0.7 doit être RÉINSTALLÉE : ne passez pas par le bouton de mise à jour.** Téléchargez le binaire 0.8, puis `sudo ajean install` — il fait la reprise complète. Il déplace les dossiers, reprend les réglages en base, désactive les anciens services et installe les nouveaux. Rien n'est supprimé : presets, mémoire et modèles sont déplacés, les anciens fichiers d'état rangés dans `avant-0.8/`. C'est le seul code de compatibilité de la version, isolé dans un fichier prévu pour être supprimé.
## Une base à la place des fichiers d'état
@@ -32,4 +32,6 @@ Tout le code écrit pour ménager les installations « jean » : la migration du
La CLI perd ses alias hérités — `skills`, `machine`, `tools`, `web-access`, `mem`, `upgrade`, `self-update`, `paths`, `llama` — et son aide est réorganisée autour des deux services. Chaque commande a désormais un seul nom. `app` quitte l'aide : c'est le comportement du double-clic, qu'on n'atteint pas en tapant son nom.
Les releases ne publient plus qu'un jeu de binaires, `ajean-<os>-<arch>`. La double publication qui accompagnait la transition n'a plus d'objet.
Les releases ne publient plus qu'un jeu de binaires, et sous des noms lisibles : `ajean-linux`, `ajean-linux-arm`, `ajean-macos`, `ajean-macos-arm`, `ajean-windows.exe`, `ajean-windows-arm.exe`. La double publication qui accompagnait la transition n'a plus d'objet.
Ce changement de noms n'est pas cosmétique. Les versions 0.7 cherchent leur mise à jour sous la forme `ajean-<GOOS>-<GOARCH>` : ne trouvant aucun asset qui corresponde, leur bouton « mettre à jour » échoue proprement, sans rien remplacer. C'est délibéré. Laisser la 0.7 installer ce binaire aurait remplacé l'exécutable sans migrer les données ni les unités : le service de lien serait reparti en boucle d'échec sur une sous-commande disparue, et le moteur n'aurait plus trouvé sa configuration — une machine à réparer en SSH après un clic dans un navigateur.
+26 -6
View File
@@ -35,13 +35,33 @@ type ghRelease struct {
}
// updateAssetName est le nom de l'asset de release pour la plateforme courante :
// ajean-<os>-<arch>[.exe]. Un seul nom publié, un seul nom cherché.
func updateAssetName() string {
suffix := runtime.GOOS + "-" + runtime.GOARCH
if runtime.GOOS == "windows" {
suffix += ".exe"
// ajean-linux, ajean-linux-arm, ajean-macos, ajean-macos-arm, ajean-windows.exe,
// ajean-windows-arm.exe. Un seul nom publié, un seul nom cherché.
//
// Ces noms sont volontairement lisibles — « macos » plutôt que « darwin », pas
// de « amd64 » pour le cas courant — et volontairement DIFFÉRENTS du schéma
// ajean-<GOOS>-<GOARCH> qu'utilisaient les versions 0.7 : leur mise à jour
// automatique ne trouve donc aucun asset et échoue sans rien remplacer, au lieu
// d'installer un binaire 0.8 sur une machine encore agencée en 0.7 — ce qui
// laissait le service de lien en boucle d'échec. La 0.7 se met à jour à la main,
// par réinstallation.
func updateAssetName() string { return assetNameFor(runtime.GOOS, runtime.GOARCH) }
// assetNameFor est séparée pour être vérifiable sur les six plateformes, et pas
// seulement sur celle qui exécute les tests.
func assetNameFor(goos, goarch string) string {
name := "ajean-" + map[string]string{
"darwin": "macos",
"linux": "linux",
"windows": "windows",
}[goos]
if goarch == "arm64" {
name += "-arm"
}
return "ajean-" + suffix
if goos == "windows" {
name += ".exe"
}
return name
}
// pickAsset trouve dans la release l'asset de cette plateforme. Renvoie son nom
+33 -1
View File
@@ -1,6 +1,9 @@
package ajean
import "testing"
import (
"runtime"
"testing"
)
// relWith fabrique une release ne contenant que les assets nommés.
func relWith(names ...string) *ghRelease {
@@ -34,3 +37,32 @@ func TestPickAssetSansCorrespondance(t *testing.T) {
t.Fatalf("URL inattendue: %q", url)
}
}
// Le schéma de nommage ne doit PAS coïncider avec ajean-<GOOS>-<GOARCH> : c'est
// ce qui empêche la mise à jour automatique d'une 0.7 de s'installer sur une
// machine encore agencée en 0.7.
func TestNomDAssetDistinctDuSchema07(t *testing.T) {
legacy := "ajean-" + runtime.GOOS + "-" + runtime.GOARCH
if runtime.GOOS == "windows" {
legacy += ".exe"
}
if got := updateAssetName(); got == legacy {
t.Fatalf("le nom %q est celui que cherche la 0.7 — sa mise à jour casserait l'installation", got)
}
}
// Les six noms publiés par la release, vérifiés un par un.
func TestNomsDAssetParPlateforme(t *testing.T) {
for _, c := range []struct{ goos, goarch, want string }{
{"linux", "amd64", "ajean-linux"},
{"linux", "arm64", "ajean-linux-arm"},
{"darwin", "amd64", "ajean-macos"},
{"darwin", "arm64", "ajean-macos-arm"},
{"windows", "amd64", "ajean-windows.exe"},
{"windows", "arm64", "ajean-windows-arm.exe"},
} {
if got := assetNameFor(c.goos, c.goarch); got != c.want {
t.Errorf("%s/%s → %q, attendu %q", c.goos, c.goarch, got, c.want)
}
}
}