Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7638a2f4e | ||
|
|
d885d92643 | ||
|
|
0e31d28342 | ||
|
|
9bcdd6c139 |
No files matched your search
@@ -4,9 +4,9 @@ on:
|
|||||||
# Mudança só de documentação não precisa de 6 jobs em 3 sistemas.
|
# Mudança só de documentação não precisa de 6 jobs em 3 sistemas.
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
paths-ignore: ['**.md', 'docs/**', 'LICENSE*', '.gitignore', '.githooks/**']
|
paths-ignore: ['**.md', 'docs/**', 'LICENSE*', '.gitignore', '.githooks/**', '.wolf/**', '.claude/**', 'scripts/release-notes.sh', '.gitea/workflows/release.yml']
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore: ['**.md', 'docs/**', 'LICENSE*', '.gitignore', '.githooks/**']
|
paths-ignore: ['**.md', 'docs/**', 'LICENSE*', '.gitignore', '.githooks/**', '.wolf/**', '.claude/**', 'scripts/release-notes.sh', '.gitea/workflows/release.yml']
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ci-${{ github.ref }}
|
group: ci-${{ github.ref }}
|
||||||
@@ -15,17 +15,24 @@ concurrency:
|
|||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
RUSTFLAGS: -D warnings
|
RUSTFLAGS: -D warnings
|
||||||
|
# O runner mantém /opt/hostedtoolcache num volume que sobrevive entre jobs:
|
||||||
|
# a toolchain do rustup, o registry do cargo e o diretório target ficam ali,
|
||||||
|
# então nada disso é baixado ou recompilado do zero a cada execução. Cada job
|
||||||
|
# usa o seu próprio target (flags diferentes invalidariam o de outro job).
|
||||||
|
CARGO_HOME: /opt/hostedtoolcache/cargo
|
||||||
|
RUSTUP_HOME: /opt/hostedtoolcache/rustup
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
name: Formatação e clippy
|
name: Formatação e clippy
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_DIR: /opt/hostedtoolcache/cargo-target/sabia-lint
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
- uses: actions/setup-node@v7
|
- uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 22
|
||||||
@@ -34,37 +41,39 @@ jobs:
|
|||||||
- run: cargo fmt --all -- --check
|
- run: cargo fmt --all -- --check
|
||||||
- run: cargo clippy --workspace --all-targets
|
- run: cargo clippy --workspace --all-targets
|
||||||
|
|
||||||
|
# Windows e macOS saem: o Gitea aqui tem um único runner, Linux arm64.
|
||||||
test:
|
test:
|
||||||
name: Testes (${{ matrix.os }})
|
name: Testes (Linux)
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
env:
|
||||||
fail-fast: false
|
CARGO_TARGET_DIR: /opt/hostedtoolcache/cargo-target/sabia-test
|
||||||
matrix:
|
|
||||||
os: [ubuntu-24.04, windows-latest, macos-latest]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
- run: cargo test --workspace
|
- run: cargo test --workspace
|
||||||
|
|
||||||
audit:
|
audit:
|
||||||
name: Auditoria de dependências
|
name: Auditoria de dependências
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- uses: rustsec/audit-check@v2
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
# rustsec/audit-check depends on GitHub's checks API. cargo-audit itself
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
# needs nothing but the advisory database, and installing it once into the
|
||||||
|
# persistent CARGO_HOME makes every later run skip the compile.
|
||||||
|
- name: cargo audit
|
||||||
|
run: |
|
||||||
|
command -v cargo-audit >/dev/null || cargo install cargo-audit --locked
|
||||||
|
cargo audit
|
||||||
|
|
||||||
gui:
|
gui:
|
||||||
name: Compila o app desktop (Linux)
|
name: Compila o app desktop (Linux)
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_DIR: /opt/hostedtoolcache/cargo-target/sabia-gui
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: apps/gui/src-tauri
|
|
||||||
- uses: actions/setup-node@v7
|
- uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 22
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
# Quando uma tag v* é enviada: cria a entrada em "Releases" com as notas do
|
||||||
|
# CHANGELOG.md e anexa o CLI compilado (scripts/package-cli.sh), com um .sha256 ao
|
||||||
|
# lado de cada pacote. É o que o atualizador (`sabia update`) baixa.
|
||||||
|
#
|
||||||
|
# O CLI é só para Linux (x86_64 e aarch64), compilado no runner Linux; o x86_64
|
||||||
|
# por compilação cruzada. Windows e macOS têm só o app desktop.
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ['v*']
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
# Toolchain e registry do cargo ficam no volume que sobrevive entre jobs.
|
||||||
|
CARGO_HOME: /opt/hostedtoolcache/cargo
|
||||||
|
RUSTUP_HOME: /opt/hostedtoolcache/rustup
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Cria a release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Release
|
||||||
|
env:
|
||||||
|
TAG: ${{ gitea.ref_name }}
|
||||||
|
TOKEN: ${{ gitea.token }}
|
||||||
|
API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}
|
||||||
|
run: |
|
||||||
|
# Uma execução repetida não recria a release.
|
||||||
|
if curl -fsS -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" >/dev/null 2>&1; then
|
||||||
|
echo "a release $TAG já existe"; exit 0
|
||||||
|
fi
|
||||||
|
scripts/release-notes.sh "$TAG" > notes.md
|
||||||
|
pre=false; case "$TAG" in *-*) pre=true ;; esac
|
||||||
|
jq -n --arg tag "$TAG" --arg name "Sabiá ${TAG#v}" --rawfile body notes.md --argjson pre "$pre" \
|
||||||
|
'{tag_name:$tag, name:$name, body:$body, prerelease:$pre}' > release.json
|
||||||
|
curl -fsS -X POST "$API/releases" -H "Authorization: token $TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' -d @release.json >/dev/null
|
||||||
|
|
||||||
|
cli:
|
||||||
|
name: CLI (${{ matrix.platform }})
|
||||||
|
needs: release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_DIR: /opt/hostedtoolcache/cargo-target/sabia-release
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { platform: linux-aarch64, target: aarch64-unknown-linux-gnu, apt: "" }
|
||||||
|
- { platform: linux-x86_64, target: x86_64-unknown-linux-gnu, apt: "gcc-x86-64-linux-gnu" }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.target }}
|
||||||
|
- name: Linker e ferramentas desta plataforma
|
||||||
|
if: ${{ matrix.apt != '' }}
|
||||||
|
run: |
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq ${{ matrix.apt }}
|
||||||
|
- name: Compila e empacota
|
||||||
|
run: scripts/package-cli.sh "${{ gitea.ref_name }}" "${{ matrix.platform }}" "${{ matrix.target }}" | tee packages.txt
|
||||||
|
- name: Anexa à release
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ gitea.token }}
|
||||||
|
API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}
|
||||||
|
run: scripts/release-upload.sh "${{ gitea.ref_name }}" $(cat packages.txt)
|
||||||
|
|
||||||
|
gui:
|
||||||
|
name: App desktop (${{ matrix.platform }})
|
||||||
|
needs: release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_DIR: /opt/hostedtoolcache/cargo-target/sabia-release-gui
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform: [linux, windows]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- uses: actions/setup-node@v7
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
- name: Dependências do Tauri (Linux)
|
||||||
|
if: matrix.platform == 'linux'
|
||||||
|
timeout-minutes: 25
|
||||||
|
run: scripts/apt-install.sh ~/apt-cache libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf
|
||||||
|
- name: Ferramentas para compilação cruzada (Windows)
|
||||||
|
if: matrix.platform == 'windows'
|
||||||
|
run: |
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq nsis lld llvm clang
|
||||||
|
command -v cargo-xwin >/dev/null || cargo install cargo-xwin --locked
|
||||||
|
- name: Compila e empacota
|
||||||
|
run: scripts/build-gui.sh "${{ matrix.platform }}"
|
||||||
|
- name: Anexa à release
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ gitea.token }}
|
||||||
|
API: ${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}
|
||||||
|
run: scripts/release-upload.sh "${{ gitea.ref_name }}" dist-gui/*
|
||||||
@@ -18,3 +18,7 @@ apps/gui/src-tauri/target
|
|||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
AGENTS.md
|
AGENTS.md
|
||||||
GEMINI.md
|
GEMINI.md
|
||||||
|
|
||||||
|
# Pacotes gerados por scripts/package-cli.sh
|
||||||
|
/sabia-v*
|
||||||
|
/dist-gui
|
||||||
@@ -4,6 +4,27 @@
|
|||||||
|
|
||||||
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.
|
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.
|
||||||
|
|
||||||
|
## [1.0.1] - 2026-10-30
|
||||||
|
|
||||||
|
The project moved from GitHub to Gitea, and the update check followed it.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Updates now come from Gitea.** `sabia update` and the desktop app's "Update now"
|
||||||
|
read the latest release from `git.lucasrguerra.dev.br` instead of the GitHub API.
|
||||||
|
Versions up to 1.0.0 still look at GitHub, which is no longer reachable, so they
|
||||||
|
cannot find this release: download 1.0.1 once, and later updates are automatic.
|
||||||
|
- Release packages: the CLI for Linux x86_64 and aarch64 (built by the Gitea CI when
|
||||||
|
a `v*` tag is pushed, with a `.sha256` next to each package), and the desktop app
|
||||||
|
for Linux (`.AppImage`, `.deb`) and Windows (NSIS `.exe` installer, cross-compiled
|
||||||
|
from Linux by `scripts/build-gui.sh`). **There is no Windows CLI and no macOS build
|
||||||
|
any more**: the CLI is Linux-only, and macOS needs Apple's SDK and code signing,
|
||||||
|
which this project's CI cannot provide.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `sabia update` refuses to run from the desktop app's executable (`sabia-gui`).
|
||||||
|
The release package contains the CLI, and replacing the app with it would have
|
||||||
|
broken the app; the app now points to the downloads page instead.
|
||||||
|
|
||||||
## [1.0.0] - 2026-10-24
|
## [1.0.0] - 2026-10-24
|
||||||
|
|
||||||
First stable release: real-hardware validation across the whole attack surface, a much more complete cracking pipeline, two new attacks (WPS, Evil Twin), a redesigned report, and several reliability fixes found only by testing against live Wi-Fi networks.
|
First stable release: real-hardware validation across the whole attack surface, a much more complete cracking pipeline, two new attacks (WPS, Evil Twin), a redesigned report, and several reliability fixes found only by testing against live Wi-Fi networks.
|
||||||
|
|||||||
@@ -4,6 +4,27 @@
|
|||||||
|
|
||||||
Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/); versões seguem SemVer.
|
Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/); versões seguem SemVer.
|
||||||
|
|
||||||
|
## [1.0.1] - 2026-10-30
|
||||||
|
|
||||||
|
O projeto saiu do GitHub para o Gitea, e a verificação de atualização foi junto.
|
||||||
|
|
||||||
|
### Alterado
|
||||||
|
- **As atualizações agora vêm do Gitea.** O `sabia update` e o "Atualizar agora" do app
|
||||||
|
desktop leem a última release em `git.lucasrguerra.dev.br`, e não mais a API do
|
||||||
|
GitHub. As versões até a 1.0.0 ainda olham o GitHub, que não responde mais, e por isso
|
||||||
|
não enxergam esta release: baixe a 1.0.1 uma vez, e as próximas atualizações são automáticas.
|
||||||
|
- Pacotes da release: o CLI para Linux x86_64 e aarch64 (compilado pelo CI do Gitea
|
||||||
|
quando uma tag `v*` é enviada, com um `.sha256` ao lado de cada pacote) e o app desktop
|
||||||
|
para Linux (`.AppImage`, `.deb`) e Windows (instalador NSIS `.exe`, compilado a partir
|
||||||
|
do Linux pelo `scripts/build-gui.sh`). **Não há mais CLI para Windows nem build para
|
||||||
|
macOS**: o CLI é só para Linux, e o macOS exige o SDK e a assinatura da Apple, que o CI
|
||||||
|
deste projeto não tem.
|
||||||
|
|
||||||
|
### Corrigido
|
||||||
|
- O `sabia update` se recusa a rodar a partir do executável do app desktop (`sabia-gui`).
|
||||||
|
O pacote da release contém o CLI, e trocar o app por ele o quebraria; o app passa a
|
||||||
|
apontar para a página de downloads.
|
||||||
|
|
||||||
## [1.0.0] - 2026-10-24
|
## [1.0.0] - 2026-10-24
|
||||||
|
|
||||||
Primeira versão estável: validação em hardware real por toda a superfície de ataque, um pipeline de quebra bem mais completo, dois ataques novos (WPS, Evil Twin), relatório redesenhado e várias correções de confiabilidade que só apareceram testando contra redes Wi-Fi de verdade.
|
Primeira versão estável: validação em hardware real por toda a superfície de ataque, um pipeline de quebra bem mais completo, dois ataques novos (WPS, Evil Twin), relatório redesenhado e várias correções de confiabilidade que só apareceram testando contra redes Wi-Fi de verdade.
|
||||||
|
|||||||
+2
-2
@@ -17,9 +17,9 @@ cargo test --workspace
|
|||||||
node scripts/check-ui-i18n.mjs # UI translation coverage
|
node scripts/check-ui-i18n.mjs # UI translation coverage
|
||||||
```
|
```
|
||||||
|
|
||||||
CI runs on Linux, Windows and macOS; run these before pushing — almost everything that fails CI shows up here in seconds. Documentation-only changes (`*.md`, `docs/`) are light on CI.
|
CI runs on Linux only (Gitea has one runner); run these before pushing — almost everything that fails CI shows up here in seconds. Documentation-only changes (`*.md`, `docs/`) are light on CI.
|
||||||
|
|
||||||
Live capture exists only on Linux (`AF_PACKET` + netlink); on Windows and macOS those paths compile but aren't exercised. Parsing and cracking tests run on all three, because they're offline.
|
Live capture exists only on Linux (`AF_PACKET` + netlink); the code behind Windows and macOS paths still compiles and is covered by `cargo check`, but neither runs in CI nor is built for release.
|
||||||
|
|
||||||
## Where to work
|
## Where to work
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ cargo test --workspace
|
|||||||
node scripts/check-ui-i18n.mjs # cobertura da tradução da interface
|
node scripts/check-ui-i18n.mjs # cobertura da tradução da interface
|
||||||
```
|
```
|
||||||
|
|
||||||
O CI roda em Linux, Windows e macOS; rode esses comandos antes do push — quase tudo que faz o CI falhar aparece aqui em segundos. Mudanças só de documentação (`*.md`, `docs/`) são leves no CI.
|
O CI roda só em Linux (o Gitea tem um único runner); rode esses comandos antes do push — quase tudo que faz o CI falhar aparece aqui em segundos. Mudanças só de documentação (`*.md`, `docs/`) são leves no CI.
|
||||||
|
|
||||||
A captura ao vivo só existe no Linux (`AF_PACKET` + netlink); em Windows e macOS esses caminhos são compilados mas não exercitados. Testes de parsing e de quebra rodam nas três plataformas, porque são offline.
|
A captura ao vivo só existe no Linux (`AF_PACKET` + netlink); o código dos caminhos de Windows e macOS continua compilando e é coberto pelo `cargo check`, mas não roda no CI nem é compilado para release. são offline.
|
||||||
|
|
||||||
## Onde mexer
|
## Onde mexer
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -440,7 +440,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sabia-cli"
|
name = "sabia-cli"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
@@ -451,7 +451,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sabia-core"
|
name = "sabia-core"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
|||||||
+2
-2
@@ -3,10 +3,10 @@ resolver = "2"
|
|||||||
members = ["crates/sabia-core", "crates/sabia-cli"]
|
members = ["crates/sabia-core", "crates/sabia-cli"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
repository = "https://github.com/lucasrguerra/sabia"
|
repository = "https://git.lucasrguerra.dev.br/lucasrguerra/sabia"
|
||||||
authors = ["Sabiá contributors"]
|
authors = ["Sabiá contributors"]
|
||||||
rust-version = "1.80"
|
rust-version = "1.80"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<p align="center"><img src="apps/gui/ui/sabia.png" width="300" alt="Sabiá"></p>
|
<p align="center"><img src="apps/gui/ui/sabia.png" width="300" alt="Sabiá"></p>
|
||||||
<h1 align="center">Sabiá</h1>
|
<h1 align="center">Sabiá</h1>
|
||||||
<p align="center">Free and open Wi-Fi auditing.<br>Terminal and desktop app · live capture on Linux, offline analysis on Windows, Linux and macOS · authorized use.</p>
|
<p align="center">Free and open Wi-Fi auditing.<br>Terminal and desktop app · live capture on Linux, offline analysis on Windows too · authorized use.</p>
|
||||||
|
|
||||||
<p align="center"><a href="docs/cli.md">Terminal</a> · <a href="docs/interface.md">Interface</a> · <a href="docs/architecture.md">Architecture</a> · <a href="ROADMAP.md">Roadmap</a> · <a href="CHANGELOG.md">Changelog</a></p>
|
<p align="center"><a href="docs/cli.md">Terminal</a> · <a href="docs/interface.md">Interface</a> · <a href="docs/architecture.md">Architecture</a> · <a href="ROADMAP.md">Roadmap</a> · <a href="CHANGELOG.md">Changelog</a></p>
|
||||||
|
|
||||||
@@ -37,17 +37,18 @@ Download the package for your system from **[Releases](../../releases)**:
|
|||||||
|
|
||||||
| | CLI | Desktop app |
|
| | CLI | Desktop app |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Windows | `sabia-*-windows-x86_64.zip` | `.msi` / `.exe` installer |
|
| Windows | — | `.exe` installer |
|
||||||
| macOS | `sabia-*-macos-{aarch64,x86_64}.tar.gz` | `.dmg` |
|
|
||||||
| Linux | `sabia-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
| Linux | `sabia-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
||||||
|
|
||||||
Each file has a `.sha256` next to it. Build from source: `cargo build --release -p sabia-cli` (Rust 1.80+).
|
The CLI is Linux-only; the desktop app ships for Linux and Windows. Each CLI
|
||||||
|
package has a `.sha256` next to it. Build from source: `cargo build --release
|
||||||
|
-p sabia-cli` (Rust 1.80+, Linux).
|
||||||
|
|
||||||
**Updates:** the desktop app checks GitHub on startup; when a new version exists, a button offers **Update now**: it downloads the right binary for your platform, verifies the **SHA-256** and swaps the running executable — no manual download. The check is a single request to the releases API and sends nothing of yours.
|
**Updates:** the desktop app checks Gitea on startup; when a new version exists, a button offers **Update now**. The CLI updates the same way (`sabia update`); it downloads the right binary for your platform, verifies the **SHA-256** and swaps the running executable — no manual download. The check is a single request to the releases API and sends nothing of yours.
|
||||||
|
|
||||||
> The binaries are **not signed yet**: Windows SmartScreen and macOS Gatekeeper will warn. Check the SHA-256.
|
> The binaries are **not signed yet**: Windows SmartScreen will warn. Check the SHA-256.
|
||||||
|
|
||||||
**Capture and monitor mode require Linux and root** (`CAP_NET_ADMIN`/`CAP_NET_RAW`): raw capture uses `AF_PACKET` and interface control uses netlink. **Offline `.pcap` analysis and cracking** also run on Windows and macOS. The desktop app elevates to administrator on its own at startup.
|
**Capture and monitor mode require Linux and root** — the only platform the CLI ships for (`CAP_NET_ADMIN`/`CAP_NET_RAW`): raw capture uses `AF_PACKET` and interface control uses netlink. **Offline `.pcap` analysis and cracking** also run on Windows and macOS. The desktop app elevates to administrator on its own at startup.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
@@ -74,11 +75,11 @@ Desktop app (Tauri) with an interface sidebar, a capture panel with an animated
|
|||||||
|
|
||||||
## Known limits
|
## Known limits
|
||||||
|
|
||||||
- **Capture is Linux-only**, with a card that supports **monitor mode** (and injection, for `deauth`). On Windows and macOS Sabiá only does `.pcap` analysis and offline cracking.
|
- **Capture is Linux-only**, with a card that supports **monitor mode** (and injection, for `deauth`); the CLI is not built for other platforms. On Windows Sabiá's desktop app only does `.pcap` analysis and offline cracking.
|
||||||
- **WPA3/SAE** does not fall to handshake dictionaries — cracking covers **WPA/WPA2-PSK** (4-way and PMKID).
|
- **WPA3/SAE** does not fall to handshake dictionaries — cracking covers **WPA/WPA2-PSK** (4-way and PMKID).
|
||||||
- **5 and 6 GHz** depend on the card and the regulatory domain; some channels stay passive (no probing).
|
- **5 and 6 GHz** depend on the card and the regulatory domain; some channels stay passive (no probing).
|
||||||
- **Evil Twin's self-signed certificate:** the Enterprise variant's TLS certificate isn't trusted by clients that validate the chain (common on updated corporate/MDM devices) — that's the correct defense working, not a bug.
|
- **Evil Twin's self-signed certificate:** the Enterprise variant's TLS certificate isn't trusted by clients that validate the chain (common on updated corporate/MDM devices) — that's the correct defense working, not a bug.
|
||||||
- **Windows and macOS:** the code compiles and is tested in CI, but live capture does not run on those platforms.
|
- **Windows:** the code compiles and is tested in CI, but live capture does not run there; the desktop app does offline analysis only. There is no macOS build: Tauri needs the macOS SDK and code signing, both tied to Apple hardware and an Apple Developer account, which this project's CI (a single Linux runner) does not have.
|
||||||
|
|
||||||
## Where it's going
|
## Where it's going
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ Summary of the [ROADMAP](ROADMAP.md):
|
|||||||
|---|---|
|
|---|---|
|
||||||
| **Done** | Monitor mode via netlink (with NetworkManager recovery), 2.4/5/6 GHz scanning, 4-way and PMKID capture, CCMP decryption, dictionary/rules/mask cracking (WPA/WPA2-PSK), `.hc22000` export, `.pcap` read/write, authorized `deauth`/PMF/PMKID, WPS attack, Evil Twin (PSK + Enterprise), channel scoring and findings, paginated audit report, hash-chained audit trail, `doctor`, CLI + desktop app, one-click update |
|
| **Done** | Monitor mode via netlink (with NetworkManager recovery), 2.4/5/6 GHz scanning, 4-way and PMKID capture, CCMP decryption, dictionary/rules/mask cracking (WPA/WPA2-PSK), `.hc22000` export, `.pcap` read/write, authorized `deauth`/PMF/PMKID, WPS attack, Evil Twin (PSK + Enterprise), channel scoring and findings, paginated audit report, hash-chained audit trail, `doctor`, CLI + desktop app, one-click update |
|
||||||
| **Next** | GPU acceleration for cracking, capture on Windows (Npcap) |
|
| **Next** | GPU acceleration for cracking, capture on Windows (Npcap) |
|
||||||
|
| **Not planned** | A macOS build — see [Known limits](#known-limits) |
|
||||||
| **Later** | WPA3/SAE downgrade, validation on varied hardware, signed release binaries |
|
| **Later** | WPA3/SAE downgrade, validation on varied hardware, signed release binaries |
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|||||||
+11
-9
@@ -1,6 +1,6 @@
|
|||||||
<p align="center"><img src="apps/gui/ui/sabia.png" width="300" alt="Sabiá"></p>
|
<p align="center"><img src="apps/gui/ui/sabia.png" width="300" alt="Sabiá"></p>
|
||||||
<h1 align="center">Sabiá</h1>
|
<h1 align="center">Sabiá</h1>
|
||||||
<p align="center">Auditoria de Wi-Fi livre e gratuita.<br>Terminal e interface gráfica · captura no Linux, análise offline em Windows, Linux e macOS · uso autorizado.</p>
|
<p align="center">Auditoria de Wi-Fi livre e gratuita.<br>Terminal e interface gráfica · captura no Linux, análise offline também em Windows · uso autorizado.</p>
|
||||||
|
|
||||||
<p align="center"><a href="docs/pt-BR/cli.md">Terminal</a> · <a href="docs/pt-BR/interface.md">Interface</a> · <a href="docs/pt-BR/arquitetura.md">Arquitetura</a> · <a href="ROADMAP.pt-BR.md">Roadmap</a> · <a href="CHANGELOG.pt-BR.md">Changelog</a></p>
|
<p align="center"><a href="docs/pt-BR/cli.md">Terminal</a> · <a href="docs/pt-BR/interface.md">Interface</a> · <a href="docs/pt-BR/arquitetura.md">Arquitetura</a> · <a href="ROADMAP.pt-BR.md">Roadmap</a> · <a href="CHANGELOG.pt-BR.md">Changelog</a></p>
|
||||||
|
|
||||||
@@ -37,17 +37,18 @@ Baixe o pacote do seu sistema em **[Releases](../../releases)**:
|
|||||||
|
|
||||||
| | CLI | App gráfico |
|
| | CLI | App gráfico |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Windows | `sabia-*-windows-x86_64.zip` | instalador `.msi` / `.exe` |
|
| Windows | — | instalador `.exe` |
|
||||||
| macOS | `sabia-*-macos-{aarch64,x86_64}.tar.gz` | `.dmg` |
|
|
||||||
| Linux | `sabia-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
| Linux | `sabia-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
||||||
|
|
||||||
Cada arquivo tem um `.sha256` ao lado. Compilar do código: `cargo build --release -p sabia-cli` (Rust 1.80+).
|
O CLI é só para Linux; o app desktop sai para Linux e Windows. Cada pacote do
|
||||||
|
CLI tem um `.sha256` ao lado. Compilar do código: `cargo build --release -p
|
||||||
|
sabia-cli` (Rust 1.80+, Linux).
|
||||||
|
|
||||||
**Atualizações:** o app desktop consulta o GitHub ao abrir; havendo versão nova, um botão oferece **Atualizar agora**: ele baixa o binário certo para a plataforma, confere o **SHA-256** e troca o executável em uso — você não precisa baixar nada na mão. A consulta é uma única requisição à API de releases e nada seu é enviado.
|
**Atualizações:** o app desktop consulta o Gitea ao abrir; havendo versão nova, um botão oferece **Atualizar agora**. O CLI atualiza do mesmo jeito (`sabia update`); ele baixa o binário certo para a plataforma, confere o **SHA-256** e troca o executável em uso — você não precisa baixar nada na mão. A consulta é uma única requisição à API de releases e nada seu é enviado.
|
||||||
|
|
||||||
> Os binários ainda **não são assinados**: o SmartScreen (Windows) e o Gatekeeper (macOS) vão avisar. Confira o SHA-256.
|
> Os binários ainda **não são assinados**: o SmartScreen do Windows vai avisar. Confira o SHA-256.
|
||||||
|
|
||||||
**Captura e modo monitor exigem Linux e privilégio de root** (`CAP_NET_ADMIN`/`CAP_NET_RAW`): a captura crua usa `AF_PACKET` e o controle de interface usa netlink. A **análise de `.pcap` e a quebra offline** rodam também em Windows e macOS. O app desktop pede elevação de administrador sozinho ao abrir.
|
**Captura e modo monitor exigem Linux e privilégio de root** — a única plataforma para a qual o CLI é compilado (`CAP_NET_ADMIN`/`CAP_NET_RAW`): a captura crua usa `AF_PACKET` e o controle de interface usa netlink. A **análise de `.pcap` e a quebra offline** rodam também em Windows e macOS. O app desktop pede elevação de administrador sozinho ao abrir.
|
||||||
|
|
||||||
## Começando
|
## Começando
|
||||||
|
|
||||||
@@ -74,11 +75,11 @@ App desktop (Tauri) com sidebar de interfaces, painel de captura com linha de si
|
|||||||
|
|
||||||
## Limites conhecidos
|
## Limites conhecidos
|
||||||
|
|
||||||
- **Captura só no Linux**, com placa que suporte **modo monitor** (e injeção, para `deauth`). Em Windows e macOS o Sabiá faz só análise de `.pcap` e quebra offline.
|
- **Captura só no Linux**, com placa que suporte **modo monitor** (e injeção, para `deauth`); o CLI não é compilado para outras plataformas. Em Windows o app desktop do Sabiá faz só análise de `.pcap` e quebra offline.
|
||||||
- **WPA3/SAE** não cai por dicionário de handshake — a quebra cobre **WPA/WPA2-PSK** (4-way e PMKID).
|
- **WPA3/SAE** não cai por dicionário de handshake — a quebra cobre **WPA/WPA2-PSK** (4-way e PMKID).
|
||||||
- **5 e 6 GHz** dependem da placa e do _regulatory domain_; alguns canais ficam passivos (sem _probe_).
|
- **5 e 6 GHz** dependem da placa e do _regulatory domain_; alguns canais ficam passivos (sem _probe_).
|
||||||
- **Certificado autoassinado do Evil Twin Enterprise:** clientes que validam a cadeia de certificado da rede (comum em perfil corporativo/MDM atualizado) não confiam nele — é a defesa correta funcionando, não um bug.
|
- **Certificado autoassinado do Evil Twin Enterprise:** clientes que validam a cadeia de certificado da rede (comum em perfil corporativo/MDM atualizado) não confiam nele — é a defesa correta funcionando, não um bug.
|
||||||
- **Windows e macOS:** o código compila e é testado em CI, mas a captura ao vivo não roda nessas plataformas.
|
- **Windows:** o código compila e é testado em CI, mas a captura ao vivo não roda lá; o app desktop faz só análise offline. Não há build para macOS: o Tauri precisa do SDK do macOS e de assinatura, os dois presos a hardware Apple e a uma conta Apple Developer, que o CI deste projeto (um único runner Linux) não tem.
|
||||||
|
|
||||||
## Para onde vai
|
## Para onde vai
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ Resumo do [ROADMAP](ROADMAP.pt-BR.md):
|
|||||||
|---|---|
|
|---|---|
|
||||||
| **Feito** | Modo monitor por netlink (com recuperação do NetworkManager), varredura 2.4/5/6 GHz, captura de 4-way e PMKID, decriptação CCMP, quebra por dicionário/regras/máscara (WPA/WPA2-PSK), exportação `.hc22000`, escrita e leitura de `.pcap`, `deauth`/PMF/PMKID autorizados, ataque WPS, Evil Twin (PSK + Enterprise), pontuação de canais e achados, relatório de auditoria paginado, trilha de auditoria por hash, `doctor`, CLI + app desktop, atualização em um clique |
|
| **Feito** | Modo monitor por netlink (com recuperação do NetworkManager), varredura 2.4/5/6 GHz, captura de 4-way e PMKID, decriptação CCMP, quebra por dicionário/regras/máscara (WPA/WPA2-PSK), exportação `.hc22000`, escrita e leitura de `.pcap`, `deauth`/PMF/PMKID autorizados, ataque WPS, Evil Twin (PSK + Enterprise), pontuação de canais e achados, relatório de auditoria paginado, trilha de auditoria por hash, `doctor`, CLI + app desktop, atualização em um clique |
|
||||||
| **Próximo** | Aceleração por GPU na quebra, captura em Windows (Npcap) |
|
| **Próximo** | Aceleração por GPU na quebra, captura em Windows (Npcap) |
|
||||||
|
| **Fora de plano** | Um build para macOS — veja [Limites conhecidos](#limites-conhecidos) |
|
||||||
| **Depois** | WPA3/SAE _downgrade_, validação em hardware variado, binários de release assinados |
|
| **Depois** | WPA3/SAE _downgrade_, validação em hardware variado, binários de release assinados |
|
||||||
|
|
||||||
## Desenvolvimento
|
## Desenvolvimento
|
||||||
|
|||||||
Generated
+2
-2
@@ -2538,7 +2538,7 @@ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sabia-core"
|
name = "sabia-core"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"flate2",
|
"flate2",
|
||||||
@@ -2555,7 +2555,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sabia-gui"
|
name = "sabia-gui"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"sabia-core",
|
"sabia-core",
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sabia-gui"
|
name = "sabia-gui"
|
||||||
description = "Sabiá: interface gráfica de auditoria de Wi-Fi"
|
description = "Sabiá: interface gráfica de auditoria de Wi-Fi"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
repository = "https://github.com/lucasrguerra/sabia"
|
repository = "https://git.lucasrguerra.dev.br/lucasrguerra/sabia"
|
||||||
rust-version = "1.80"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Sabia",
|
"productName": "Sabia",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"identifier": "dev.sabia.app",
|
"identifier": "dev.sabia.app",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../ui"
|
"frontendDist": "../ui"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Auto-atualização simples: verifica a última release no GitHub, baixa o
|
//! Auto-atualização simples: verifica a última release no Gitea, baixa o
|
||||||
//! binário certo para a plataforma atual, confere o checksum e troca o
|
//! binário certo para a plataforma atual, confere o checksum e troca o
|
||||||
//! executável em uso — sem o usuário precisar baixar nada manualmente.
|
//! executável em uso — sem o usuário precisar baixar nada manualmente.
|
||||||
//!
|
//!
|
||||||
@@ -12,7 +12,13 @@ use std::fs;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
const REPO: &str = "lucasrguerra/sabia";
|
/// A API do Gitea devolve o mesmo formato de `releases/latest` que o GitHub devolvia
|
||||||
|
/// (`tag_name`, `assets[].name`, `assets[].browser_download_url`).
|
||||||
|
const LATEST_RELEASE_URL: &str =
|
||||||
|
"https://git.lucasrguerra.dev.br/api/v1/repos/lucasrguerra/sabia/releases/latest";
|
||||||
|
|
||||||
|
/// Página de downloads, para quem usa o app desktop.
|
||||||
|
const RELEASES_PAGE_URL: &str = "https://git.lucasrguerra.dev.br/lucasrguerra/sabia/releases";
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct Release {
|
struct Release {
|
||||||
@@ -92,8 +98,8 @@ fn asset_suffix_for_platform() -> String {
|
|||||||
/// Consulta a última release publicada e compara com a versão atual
|
/// Consulta a última release publicada e compara com a versão atual
|
||||||
/// (`CARGO_PKG_VERSION` do binário chamador).
|
/// (`CARGO_PKG_VERSION` do binário chamador).
|
||||||
pub fn check(current_version: &str) -> Result<UpdateStatus> {
|
pub fn check(current_version: &str) -> Result<UpdateStatus> {
|
||||||
let url = format!("https://api.github.com/repos/{REPO}/releases/latest");
|
let url = LATEST_RELEASE_URL;
|
||||||
let body = match curl_text(&url) {
|
let body = match curl_text(url) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// Sem rede, ou repositório ainda sem releases publicadas: não é
|
// Sem rede, ou repositório ainda sem releases publicadas: não é
|
||||||
@@ -118,8 +124,22 @@ pub fn check(current_version: &str) -> Result<UpdateStatus> {
|
|||||||
/// Baixa e aplica a atualização mais recente, substituindo o binário atual.
|
/// Baixa e aplica a atualização mais recente, substituindo o binário atual.
|
||||||
/// Retorna a versão instalada.
|
/// Retorna a versão instalada.
|
||||||
pub fn apply(current_exe: &PathBuf) -> Result<String> {
|
pub fn apply(current_exe: &PathBuf) -> Result<String> {
|
||||||
let url = format!("https://api.github.com/repos/{REPO}/releases/latest");
|
// O pacote da release contém o CLI (`sabia`). Trocar por ele um executável que
|
||||||
let body = curl_text(&url)?;
|
// não seja o CLI, como o `sabia-gui`, o deixaria como um CLI e quebraria o app
|
||||||
|
// na próxima abertura. O app desktop se atualiza baixando o instalador.
|
||||||
|
let is_cli = current_exe
|
||||||
|
.file_stem()
|
||||||
|
.map(|stem| stem == "sabia")
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !is_cli {
|
||||||
|
return Err(SabiaError::CommandFailed {
|
||||||
|
cmd: "update".into(),
|
||||||
|
detail: format!(
|
||||||
|
"a atualização automática vale só para o CLI `sabia`; para o app desktop, baixe o instalador em {RELEASES_PAGE_URL}"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let body = curl_text(LATEST_RELEASE_URL)?;
|
||||||
let release: Release = serde_json::from_str(&body)?;
|
let release: Release = serde_json::from_str(&body)?;
|
||||||
|
|
||||||
let suffix = asset_suffix_for_platform();
|
let suffix = asset_suffix_for_platform();
|
||||||
@@ -225,3 +245,17 @@ fn find_binary(dir: &PathBuf) -> Result<PathBuf> {
|
|||||||
detail: "binário não encontrado no pacote baixado".into(),
|
detail: "binário não encontrado no pacote baixado".into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn apply_refuses_to_overwrite_the_desktop_app() {
|
||||||
|
// Falha antes de qualquer acesso à rede: o nome do executável já não é o do CLI.
|
||||||
|
let err = apply(&PathBuf::from("/opt/sabia/sabia-gui")).unwrap_err();
|
||||||
|
assert!(err.to_string().contains("só para o CLI"), "{err}");
|
||||||
|
let err = apply(&PathBuf::from("C:/Program Files/Sabia/sabia-gui.exe")).unwrap_err();
|
||||||
|
assert!(err.to_string().contains(RELEASES_PAGE_URL), "{err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+59
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Compila o app desktop (Tauri) e deixa os pacotes em dist-gui/, com os nomes
|
||||||
|
# que a release usa.
|
||||||
|
#
|
||||||
|
# scripts/build-gui.sh linux # AppImage e .deb; precisa de uma máquina Linux com os pacotes do Tauri
|
||||||
|
# scripts/build-gui.sh windows # instalador NSIS, compilado a partir do Linux
|
||||||
|
#
|
||||||
|
# O Windows usa cargo-xwin (SDK do Windows baixado na hora) e o NSIS, que o Tauri
|
||||||
|
# documenta como compilação cruzada experimental. Precisa de: nsis, lld, llvm,
|
||||||
|
# clang e `cargo install cargo-xwin`. O .msi não sai daqui (o WiX é só do Windows).
|
||||||
|
# `scripts/build-gui.sh windows-docker` roda o mesmo num container, sem instalar nada.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
platform=${1:?uso: build-gui.sh <linux|windows|windows-docker>}
|
||||||
|
tauri() { npx --yes @tauri-apps/cli@2 "$@"; }
|
||||||
|
|
||||||
|
if [ "$platform" = windows-docker ]; then
|
||||||
|
docker volume create sabia-cargo >/dev/null
|
||||||
|
docker volume create sabia-rustup >/dev/null
|
||||||
|
mkdir -p dist-gui
|
||||||
|
exec docker run --rm -v "$PWD":/src -v sabia-cargo:/root/.cargo -v sabia-rustup:/root/.rustup \
|
||||||
|
-w /src -e HOST_UID="$(id -u)" -e HOST_GID="$(id -g)" ubuntu:24.04 bash -c '
|
||||||
|
set -e
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq curl ca-certificates build-essential pkg-config nsis lld llvm clang nodejs npm unzip >/dev/null
|
||||||
|
[ -x /root/.cargo/bin/rustup ] || curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal >/dev/null
|
||||||
|
export PATH=/root/.cargo/bin:$PATH
|
||||||
|
command -v cargo-xwin >/dev/null || cargo install cargo-xwin --locked
|
||||||
|
scripts/build-gui.sh windows
|
||||||
|
chown -R "$HOST_UID:$HOST_GID" dist-gui apps/gui/src-tauri/target 2>/dev/null || true'
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p dist-gui
|
||||||
|
cd apps/gui/src-tauri
|
||||||
|
|
||||||
|
# Os ícones derivados do original não ficam todos no repositório.
|
||||||
|
[ -f icons/icon.ico ] || tauri icon icons/source.png -o icons
|
||||||
|
|
||||||
|
case "$platform" in
|
||||||
|
linux)
|
||||||
|
tauri build --bundles appimage,deb
|
||||||
|
bundle=target/release/bundle
|
||||||
|
cp "$bundle"/appimage/*.AppImage "$bundle"/deb/*.deb ../../../dist-gui/
|
||||||
|
# O atualizador do Tauri (quando o projeto usa) precisa do .sig ao lado.
|
||||||
|
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
|
||||||
|
cp "$bundle"/*-setup.exe ../../../dist-gui/
|
||||||
|
cp "$bundle"/*-setup.exe.sig ../../../dist-gui/ 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
*) echo "plataforma desconhecida: $platform" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ls -1 ../../../dist-gui
|
||||||
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Compila o CLI para uma plataforma e empacota como o atualizador espera:
|
||||||
|
# sabia-<tag>-<plataforma>.tar.gz com um .sha256 ao lado.
|
||||||
|
#
|
||||||
|
# scripts/package-cli.sh v1.0.1 linux-x86_64 x86_64-unknown-linux-gnu
|
||||||
|
#
|
||||||
|
# Plataformas: linux-x86_64 e linux-aarch64. O alvo diferente da máquina de build
|
||||||
|
# usa o linker cruzado correspondente (gcc-x86-64-linux-gnu). Escreve os arquivos
|
||||||
|
# na raiz do repositório e imprime os nomes.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
tag=${1:?uso: package-cli.sh <tag> <plataforma> <alvo-rust>}
|
||||||
|
platform=${2:?uso: package-cli.sh <tag> <plataforma> <alvo-rust>}
|
||||||
|
target=${3:?uso: package-cli.sh <tag> <plataforma> <alvo-rust>}
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
x86_64-unknown-linux-gnu)
|
||||||
|
if [ "$(uname -m)" != x86_64 ]; then
|
||||||
|
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc
|
||||||
|
export CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc
|
||||||
|
fi ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
rustup target add "$target" >/dev/null 2>&1 || true
|
||||||
|
cargo build --release --locked -p sabia-cli --target "$target"
|
||||||
|
|
||||||
|
name="sabia-${tag}-${platform}"
|
||||||
|
rm -rf "$name"; mkdir "$name"
|
||||||
|
cp "${CARGO_TARGET_DIR:-target}/${target}/release/sabia" "$name/"
|
||||||
|
cp README.md LICENSE-MIT LICENSE-APACHE "$name/"
|
||||||
|
|
||||||
|
tar czf "$name.tar.gz" "$name"
|
||||||
|
asset="$name.tar.gz"
|
||||||
|
rm -rf "$name"
|
||||||
|
sha256sum "$asset" > "$asset.sha256"
|
||||||
|
echo "$asset"
|
||||||
|
echo "$asset.sha256"
|
||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Imprime as notas de uma release: a seção do CHANGELOG.md daquela versão, ou o
|
||||||
|
# log de commits desde a tag anterior quando o changelog não tem a seção.
|
||||||
|
#
|
||||||
|
# scripts/release-notes.sh v1.2.3
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
tag=${1:?uso: release-notes.sh <tag>}
|
||||||
|
version=${tag#v}
|
||||||
|
|
||||||
|
section=""
|
||||||
|
if [ -f CHANGELOG.md ]; then
|
||||||
|
section=$(awk -v head="## [$version]" '
|
||||||
|
index($0, head) == 1 { found = 1; next }
|
||||||
|
found && /^## \[/ { exit }
|
||||||
|
found && /^\[[^]]+\]: / { next }
|
||||||
|
found { print }
|
||||||
|
' CHANGELOG.md)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$(printf '%s' "$section" | tr -d '[:space:]')" ]; then
|
||||||
|
printf '%s\n' "$section"
|
||||||
|
else
|
||||||
|
previous=$(git describe --tags --abbrev=0 "$tag^" 2>/dev/null || true)
|
||||||
|
echo "## Mudanças${previous:+ desde $previous}"
|
||||||
|
echo
|
||||||
|
git log --no-merges --format='- %s (%h)' "${previous:+$previous..}$tag"
|
||||||
|
fi
|
||||||
Executable
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Anexa arquivos a uma release do Gitea, trocando os de mesmo nome (assim uma
|
||||||
|
# execução repetida do CI não falha por anexo duplicado).
|
||||||
|
#
|
||||||
|
# API=https://git.exemplo.com/api/v1/repos/dono/repo TOKEN=... \
|
||||||
|
# scripts/release-upload.sh v1.2.3 arquivo1 arquivo2
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${API:?defina API (URL do repositório na API do Gitea)}"
|
||||||
|
: "${TOKEN:?defina TOKEN}"
|
||||||
|
tag=${1:?uso: release-upload.sh <tag> <arquivo>...}
|
||||||
|
shift
|
||||||
|
|
||||||
|
auth=(-H "Authorization: token $TOKEN")
|
||||||
|
id=$(curl -fsS "${auth[@]}" "$API/releases/tags/$tag" | jq -r .id)
|
||||||
|
|
||||||
|
for file in "$@"; do
|
||||||
|
name=$(basename "$file")
|
||||||
|
for old in $(curl -fsS "${auth[@]}" "$API/releases/$id/assets" | jq -r --arg n "$name" '.[] | select(.name == $n) | .id'); do
|
||||||
|
curl -fsS -X DELETE "${auth[@]}" "$API/releases/$id/assets/$old"
|
||||||
|
done
|
||||||
|
curl -fsS -X POST "${auth[@]}" -F "attachment=@$file" "$API/releases/$id/assets?name=$name" >/dev/null
|
||||||
|
echo "enviado: $name"
|
||||||
|
done
|
||||||
Reference in new issue
Block a user