diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b389cf0..3404ad3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,6 +24,19 @@ For the external reference images (BitLocker, FileVault 2, dfvfs, AFF4), run `sc The desktop app signs its update packages: `tauri.conf.json` has `createUpdaterArtifacts` on, so a local `tauri build` needs `TAURI_SIGNING_PRIVATE_KEY` (any key made with `tauri signer generate`; the release key lives only in the repository secrets). For a quick local bundle, pass `--config '{"bundle":{"createUpdaterArtifacts":false}}'`. +## Releases + +Pushing a `v*` tag makes the Gitea CI create the release (notes come from `CHANGELOG.md`, so update it first), attach the Linux CLI (x86_64 and aarch64), the desktop app for Linux **aarch64** and Windows, and build the updater's `latest.json`. The runner is arm64, so the Linux **x86_64** desktop app comes from an x86_64 Linux machine: + +```bash +scripts/build-gui.sh linux # AppImage + .deb (signed) in dist-gui/ +API=https://git.lucasrguerra.dev.br/api/v1/repos/lucasrguerra/guara TOKEN=... \ + scripts/release-upload.sh vX.Y.Z dist-gui/* +API=... TOKEN=... python3 scripts/make-latest-json.py vX.Y.Z notes.md latest.json # then upload it too +``` + +There is no macOS build: it needs Apple's SDK and code signing, which a Linux runner cannot provide. + ## Where to make changes A map of the modules is in [docs/architecture.md](docs/architecture.md). What is missing and what is welcome is in the [ROADMAP](ROADMAP.md). diff --git a/CONTRIBUTING.pt-BR.md b/CONTRIBUTING.pt-BR.md index cbb9a6d..2600327 100644 --- a/CONTRIBUTING.pt-BR.md +++ b/CONTRIBUTING.pt-BR.md @@ -24,6 +24,19 @@ Para as imagens de referência externas (BitLocker, FileVault 2, dfvfs, AFF4), r O app desktop assina os pacotes de atualização: o `tauri.conf.json` tem `createUpdaterArtifacts` ligado, então um `tauri build` local precisa de `TAURI_SIGNING_PRIVATE_KEY` (qualquer chave feita com `tauri signer generate`; a chave da release fica só nos segredos do repositório). Para um pacote local rápido, passe `--config '{"bundle":{"createUpdaterArtifacts":false}}'`. +## Releases + +Enviar uma tag `v*` faz o CI do Gitea criar a release (as notas vêm do `CHANGELOG.md`, então atualize-o antes), anexar o CLI para Linux (x86_64 e aarch64), o app desktop para Linux **aarch64** e Windows, e montar o `latest.json` do atualizador. O runner é arm64, então o app Linux **x86_64** vem de uma máquina Linux x86_64: + +```bash +scripts/build-gui.sh linux # AppImage + .deb (assinados) em dist-gui/ +API=https://git.lucasrguerra.dev.br/api/v1/repos/lucasrguerra/guara TOKEN=... \ + scripts/release-upload.sh vX.Y.Z dist-gui/* +API=... TOKEN=... python3 scripts/make-latest-json.py vX.Y.Z notes.md latest.json # e envie-o também +``` + +Não há build para macOS: ele exige o SDK e a assinatura da Apple, que um runner Linux não tem. + ## Onde mexer Mapa dos módulos em [docs/pt-BR/arquitetura.md](docs/pt-BR/arquitetura.md). O que falta e o que é bem-vindo está no [ROADMAP](ROADMAP.pt-BR.md). diff --git a/scripts/build-gui.sh b/scripts/build-gui.sh index 984910f..4a3989d 100755 --- a/scripts/build-gui.sh +++ b/scripts/build-gui.sh @@ -53,14 +53,14 @@ cd apps/gui/src-tauri case "$platform" in linux) tauri build --bundles appimage,deb - bundle=target/release/bundle + bundle="${CARGO_TARGET_DIR:-target}/release/bundle" cp "$bundle"/appimage/*.AppImage "$bundle"/deb/*.deb ../../../dist-gui/ cp "$bundle"/appimage/*.AppImage.sig ../../../dist-gui/ 2>/dev/null || true ;; windows) rustup target add x86_64-pc-windows-msvc >/dev/null tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis - bundle=target/x86_64-pc-windows-msvc/release/bundle/nsis + bundle="${CARGO_TARGET_DIR:-target}/x86_64-pc-windows-msvc/release/bundle/nsis" cp "$bundle"/*-setup.exe ../../../dist-gui/ cp "$bundle"/*-setup.exe.sig ../../../dist-gui/ 2>/dev/null || true ;; diff --git a/scripts/make-latest-json.py b/scripts/make-latest-json.py index b2b89bf..b55645c 100755 --- a/scripts/make-latest-json.py +++ b/scripts/make-latest-json.py @@ -18,6 +18,7 @@ from datetime import datetime, timezone # Sem macOS: não há runner para compilar essa plataforma. PLATFORMS = [ (["linux-x86_64", "linux-x86_64-appimage"], "Guara_{v}_amd64.AppImage"), + (["linux-aarch64", "linux-aarch64-appimage"], "Guara_{v}_aarch64.AppImage"), (["windows-x86_64", "windows-x86_64-nsis"], "Guara_{v}_x64-setup.exe"), ] @@ -61,10 +62,12 @@ def main(): assets[name] = (by_name[name]["browser_download_url"], sig) data = build(version, open(notes_path, encoding="utf-8").read(), assets, datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")) - # Sem Linux e Windows o atualizador não funciona para ninguém: não publica pela metade. - for must in ("linux-x86_64", "windows-x86_64"): - if must not in data["platforms"]: - sys.exit(f"faltam o pacote ou a assinatura de {must}; confira se TAURI_SIGNING_PRIVATE_KEY está nos segredos") + # O CI gera o Linux aarch64 (o runner é arm64); o x86_64 vem de uma máquina x86_64 e + # entra depois (scripts/build-gui.sh linux). Exige o Windows e ao menos um Linux. + platforms = data["platforms"] + if "windows-x86_64" not in platforms or not any(k.startswith("linux-") for k in platforms): + sys.exit(f"faltam pacotes ou assinaturas (achei {sorted(platforms)}); " + "confira se TAURI_SIGNING_PRIVATE_KEY está nos segredos") with open(out, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) f.write("\n") diff --git a/scripts/test_make_latest_json.py b/scripts/test_make_latest_json.py index 7fc97bb..32cd179 100644 --- a/scripts/test_make_latest_json.py +++ b/scripts/test_make_latest_json.py @@ -22,7 +22,7 @@ class LatestJson(unittest.TestCase): self.assertEqual(d["version"], "1.3.2") self.assertEqual(d["notes"], "### Novidades") p = d["platforms"] - for k in ("linux-x86_64", "linux-x86_64-appimage", "windows-x86_64", "windows-x86_64-nsis"): + for k in ("linux-x86_64", "linux-x86_64-appimage", "linux-aarch64", "windows-x86_64", "windows-x86_64-nsis"): self.assertIn(k, p) self.assertTrue(p["windows-x86_64"]["url"].endswith("x64-setup.exe")) self.assertEqual(p["linux-x86_64"]["signature"], "assinatura-de-Guara_1.3.2_amd64.AppImage")