Release 1.4.1: add macOS DMG and Navis.app.zip to release artifacts.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,11 +4,11 @@
|
||||
|
||||
## Платформы
|
||||
|
||||
| OS | Артефакт | UI |
|
||||
| OS | Артефакты | UI |
|
||||
|----|----------|----|
|
||||
| Windows amd64 | `dist/navis-release/Navis.exe` | GUI (WebView2) |
|
||||
| macOS arm64 | `dist/navis-release/darwin-arm64/Navis` | CLI |
|
||||
| macOS amd64 | `dist/navis-release/darwin-amd64/Navis` | CLI |
|
||||
| Windows amd64 | `Navis.exe` | GUI (WebView2) |
|
||||
| macOS arm64 | `Navis` · **`Navis.dmg`** · `Navis.app.zip` | CLI / .app |
|
||||
| macOS amd64 | `Navis` · **`Navis.dmg`** · `Navis.app.zip` | CLI / .app |
|
||||
|
||||
## Скачать macOS прямо с git
|
||||
|
||||
@@ -25,7 +25,55 @@ uname -m
|
||||
- `arm64` → Apple Silicon (M1/M2/M3/M4) → папка **darwin-arm64**
|
||||
- `x86_64` → Intel → папка **darwin-amd64**
|
||||
|
||||
### 2. Скачайте бинарник одной командой
|
||||
### 2a. Скачать DMG (удобнее)
|
||||
|
||||
**Apple Silicon:**
|
||||
|
||||
```bash
|
||||
cd ~/Downloads
|
||||
curl -fL -o Navis.dmg \
|
||||
"https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg"
|
||||
open Navis.dmg
|
||||
```
|
||||
|
||||
**Intel:**
|
||||
|
||||
```bash
|
||||
cd ~/Downloads
|
||||
curl -fL -o Navis.dmg \
|
||||
"https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg"
|
||||
open Navis.dmg
|
||||
```
|
||||
|
||||
Откроется диск с `Navis.app` — перетащите в **Программы** (Applications).
|
||||
|
||||
Если Gatekeeper ругается:
|
||||
|
||||
```bash
|
||||
xattr -dr com.apple.quarantine /Applications/Navis.app
|
||||
```
|
||||
|
||||
Запуск CLI из .app:
|
||||
|
||||
```bash
|
||||
/Applications/Navis.app/Contents/MacOS/Navis init
|
||||
/Applications/Navis.app/Contents/MacOS/Navis install-core
|
||||
/Applications/Navis.app/Contents/MacOS/Navis connect
|
||||
```
|
||||
|
||||
Альтернатива DMG — zip с тем же `.app`:
|
||||
|
||||
```bash
|
||||
# arm64
|
||||
curl -fL -o Navis.app.zip \
|
||||
"https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip"
|
||||
# amd64
|
||||
curl -fL -o Navis.app.zip \
|
||||
"https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip"
|
||||
unzip Navis.app.zip
|
||||
```
|
||||
|
||||
### 2b. Скачать CLI-бинарник одной командой
|
||||
|
||||
**Apple Silicon (arm64):**
|
||||
|
||||
@@ -51,7 +99,7 @@ chmod +x Navis
|
||||
./Navis check-update
|
||||
```
|
||||
|
||||
### 3. Первый запуск
|
||||
### 3. Первый запуск (CLI)
|
||||
|
||||
```bash
|
||||
cd ~/Navis
|
||||
@@ -82,10 +130,10 @@ cd ~/Navis
|
||||
“Navis” cannot be opened because it is from an unidentified developer
|
||||
```
|
||||
|
||||
Снимите quarantine и разрешите в Настройках:
|
||||
|
||||
```bash
|
||||
xattr -dr com.apple.quarantine ~/Navis/Navis
|
||||
# или для .app:
|
||||
xattr -dr com.apple.quarantine /Applications/Navis.app
|
||||
```
|
||||
|
||||
Затем: **Системные настройки → Конфиденциальность и безопасность → Всё равно открыть**.
|
||||
@@ -99,15 +147,15 @@ cd ~/Navis
|
||||
# закройте процесс Navis — бинарник подменится сам
|
||||
```
|
||||
|
||||
Или скачайте файл заново теми же `curl` из шага 2.
|
||||
Или скачайте DMG/бинарник заново.
|
||||
|
||||
Прямые ссылки (raw):
|
||||
|
||||
| Архитектура | URL |
|
||||
|-------------|-----|
|
||||
| arm64 | https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis |
|
||||
| amd64 | https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis |
|
||||
| манифест | https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json |
|
||||
| Архитектура | CLI | DMG | ZIP (.app) |
|
||||
|-------------|-----|-----|------------|
|
||||
| arm64 | [Navis](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis) | [Navis.dmg](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg) | [Navis.app.zip](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip) |
|
||||
| amd64 | [Navis](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis) | [Navis.dmg](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg) | [Navis.app.zip](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip) |
|
||||
| манифест | [update.json](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json) | | |
|
||||
|
||||
## Сборка Windows
|
||||
|
||||
|
||||
+14
-2
@@ -15,7 +15,19 @@ set GOARCH=amd64
|
||||
go build -ldflags="-s -w" -o "dist\navis-release\darwin-amd64\Navis" .\cmd\vpnclient
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
set GOOS=
|
||||
set GOARCH=
|
||||
set CGO_ENABLED=
|
||||
|
||||
go build -o "tools\packmac\packmac.exe" .\tools\packmac
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-arm64\Navis" -out "dist\navis-release\darwin-arm64" -version 1.4.1 -arch arm64
|
||||
if errorlevel 1 exit /b 1
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-amd64\Navis" -out "dist\navis-release\darwin-amd64" -version 1.4.1 -arch amd64
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
echo Built:
|
||||
dir /b "dist\navis-release\darwin-arm64\Navis"
|
||||
dir /b "dist\navis-release\darwin-amd64\Navis"
|
||||
dir "dist\navis-release\darwin-arm64"
|
||||
dir "dist\navis-release\darwin-amd64"
|
||||
endlocal
|
||||
|
||||
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+16
-8
@@ -1,30 +1,38 @@
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"notes": "macOS CLI (arm64/amd64), multi-platform updates, networksetup proxy, naive tar.xz",
|
||||
"version": "1.4.1",
|
||||
"notes": "macOS DMG + Navis.app.zip в релизе (arm64/amd64)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "4ce2b429fe4c8e8e1fdf776150003e42e4452e9ecf95cb55a714f84884717fd6",
|
||||
"sha256": "a3bc2bcc256842d3914c44385a5fb9b61e691be2c19a9c283bc2099fcc48af9a",
|
||||
"os": "darwin",
|
||||
"arch": "arm64"
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
"dmg_sha256": "a49584770e7453e7046ba80a4da8ac84a34797e3a8e4eb307a3d572d1fc95b59",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip",
|
||||
"zip_sha256": "436c8c0382bf4491d288f6899d1a8fb0f7cd86b53063801f9dbc03f29a92046d"
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "a91bc03c7c68d896c42bb3520010e96191c12a0e95e2b9c2582dd2732637d9af",
|
||||
"sha256": "a1471b447e481e3fe61a65bb66c8633facd968087907e561584fd845842805fb",
|
||||
"os": "darwin",
|
||||
"arch": "amd64"
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
"dmg_sha256": "eca2127f956959c1a4567dece779bfcd4bd414d2f63f430c24b133456fa5c56a",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip",
|
||||
"zip_sha256": "de039f591032dbcf69e81499074cf7f51b80c83f08958521df9b8f873d2fe7be"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+16
-8
@@ -1,30 +1,38 @@
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"notes": "macOS CLI (arm64/amd64), multi-platform updates, networksetup proxy, naive tar.xz",
|
||||
"version": "1.4.1",
|
||||
"notes": "macOS DMG + Navis.app.zip в релизе (arm64/amd64)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "4ce2b429fe4c8e8e1fdf776150003e42e4452e9ecf95cb55a714f84884717fd6",
|
||||
"sha256": "a3bc2bcc256842d3914c44385a5fb9b61e691be2c19a9c283bc2099fcc48af9a",
|
||||
"os": "darwin",
|
||||
"arch": "arm64"
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
"dmg_sha256": "a49584770e7453e7046ba80a4da8ac84a34797e3a8e4eb307a3d572d1fc95b59",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip",
|
||||
"zip_sha256": "436c8c0382bf4491d288f6899d1a8fb0f7cd86b53063801f9dbc03f29a92046d"
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "a91bc03c7c68d896c42bb3520010e96191c12a0e95e2b9c2582dd2732637d9af",
|
||||
"sha256": "a1471b447e481e3fe61a65bb66c8633facd968087907e561584fd845842805fb",
|
||||
"os": "darwin",
|
||||
"arch": "amd64"
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
"dmg_sha256": "eca2127f956959c1a4567dece779bfcd4bd414d2f63f430c24b133456fa5c56a",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip",
|
||||
"zip_sha256": "de039f591032dbcf69e81499074cf7f51b80c83f08958521df9b8f873d2fe7be"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,21 @@ module vpnclient
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/diskfs/go-diskfs v1.9.4
|
||||
github.com/jchv/go-webview2 v0.0.0-20260205173254-56598839c808
|
||||
golang.org/x/image v0.44.0
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.org/x/sys v0.43.0
|
||||
)
|
||||
|
||||
require github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 // indirect
|
||||
require (
|
||||
github.com/anchore/go-lzo v0.1.0 // indirect
|
||||
github.com/djherbis/times v1.6.0 // indirect
|
||||
github.com/elliotwutingfeng/asciiset v0.0.0-20260129054604-cfde2086bc57 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 // indirect
|
||||
github.com/klauspost/compress v1.18.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.26 // indirect
|
||||
github.com/pkg/xattr v0.4.12 // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/ulikunitz/xz v0.5.15 // indirect
|
||||
)
|
||||
|
||||
@@ -1,10 +1,44 @@
|
||||
github.com/anchore/go-lzo v0.1.0 h1:NgAacnzqPeGH49Ky19QKLBZEuFRqtTG9cdaucc3Vncs=
|
||||
github.com/anchore/go-lzo v0.1.0/go.mod h1:3kLx0bve2oN1iDwgM1U5zGku1Tfbdb0No5qp1eL1fIk=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/diskfs/go-diskfs v1.9.4 h1:0j2d7eG4IjyxL6+ChWbDPocdBCF6HQ4HBWU2WDYWVnc=
|
||||
github.com/diskfs/go-diskfs v1.9.4/go.mod h1:TePJORO83Adh5pb2SqsxAwaP0fofFxKLkxctiS/9OQc=
|
||||
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
|
||||
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
|
||||
github.com/elliotwutingfeng/asciiset v0.0.0-20260129054604-cfde2086bc57 h1:x5yxNrq8XffV/OoNUeFPM6hxHVi5OTspSTBxr/9pemg=
|
||||
github.com/elliotwutingfeng/asciiset v0.0.0-20260129054604-cfde2086bc57/go.mod h1:GLo/8fDswSAniFG+BFIaiSPcK610jyzgEhWYPQwuQdw=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jchv/go-webview2 v0.0.0-20260205173254-56598839c808 h1:ftnsTqIUH57XQEF+PnXX9++nlHCzdkuB5zbWyMMruZo=
|
||||
github.com/jchv/go-webview2 v0.0.0-20260205173254-56598839c808/go.mod h1:rWifBlzkgrvd7zUqlfq91sWt3473OikgnglnIILx/Jo=
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 h1:njuLRcjAuMKr7kI3D85AXWkw6/+v9PwtV6M6o11sWHQ=
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY=
|
||||
github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
|
||||
github.com/pkg/xattr v0.4.12 h1:rRTkSyFNTRElv6pkA3zpjHpQ90p/OdHQC1GmGh1aTjM=
|
||||
github.com/pkg/xattr v0.4.12/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
|
||||
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
|
||||
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -39,7 +39,7 @@ func Fetch(ctx context.Context, rawURL string) ([]Item, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", "Navis/1.4.0")
|
||||
req.Header.Set("User-Agent", "Navis/1.4.1")
|
||||
client := &http.Client{Timeout: 45 * time.Second}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// CurrentVersion is the shipped client version.
|
||||
const CurrentVersion = "1.4.0"
|
||||
const CurrentVersion = "1.4.1"
|
||||
|
||||
// DefaultManifestURL is the update feed (hosted in the project git repo).
|
||||
const DefaultManifestURL = "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json"
|
||||
@@ -28,6 +28,10 @@ type PlatformAsset struct {
|
||||
SHA256 string `json:"sha256,omitempty"`
|
||||
OS string `json:"os,omitempty"`
|
||||
Arch string `json:"arch,omitempty"`
|
||||
DmgURL string `json:"dmg_url,omitempty"`
|
||||
DmgSHA256 string `json:"dmg_sha256,omitempty"`
|
||||
ZipURL string `json:"zip_url,omitempty"`
|
||||
ZipSHA256 string `json:"zip_sha256,omitempty"`
|
||||
}
|
||||
|
||||
// Manifest describes a remote release (multi-platform + legacy single URL).
|
||||
|
||||
+16
-8
@@ -1,30 +1,38 @@
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"notes": "macOS CLI (arm64/amd64), multi-platform updates, networksetup proxy, naive tar.xz",
|
||||
"version": "1.4.1",
|
||||
"notes": "macOS DMG + Navis.app.zip в релизе (arm64/amd64)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "110ab8f5806f2635b39ec586d8218120d0041a82212715530ae8c3838078bf11",
|
||||
"sha256": "4217542dfa49a60d522295267b9bd7f3a838b2917b68d9ee59041abecf149e09",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "4ce2b429fe4c8e8e1fdf776150003e42e4452e9ecf95cb55a714f84884717fd6",
|
||||
"sha256": "a3bc2bcc256842d3914c44385a5fb9b61e691be2c19a9c283bc2099fcc48af9a",
|
||||
"os": "darwin",
|
||||
"arch": "arm64"
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
"dmg_sha256": "a49584770e7453e7046ba80a4da8ac84a34797e3a8e4eb307a3d572d1fc95b59",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip",
|
||||
"zip_sha256": "436c8c0382bf4491d288f6899d1a8fb0f7cd86b53063801f9dbc03f29a92046d"
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "a91bc03c7c68d896c42bb3520010e96191c12a0e95e2b9c2582dd2732637d9af",
|
||||
"sha256": "a1471b447e481e3fe61a65bb66c8633facd968087907e561584fd845842805fb",
|
||||
"os": "darwin",
|
||||
"arch": "amd64"
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
"dmg_sha256": "eca2127f956959c1a4567dece779bfcd4bd414d2f63f430c24b133456fa5c56a",
|
||||
"zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip",
|
||||
"zip_sha256": "de039f591032dbcf69e81499074cf7f51b80c83f08958521df9b8f873d2fe7be"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
diskfs "github.com/diskfs/go-diskfs"
|
||||
"github.com/diskfs/go-diskfs/disk"
|
||||
"github.com/diskfs/go-diskfs/filesystem"
|
||||
"github.com/diskfs/go-diskfs/filesystem/iso9660"
|
||||
)
|
||||
|
||||
func main() {
|
||||
bin := flag.String("bin", "", "path to darwin Navis binary")
|
||||
outDir := flag.String("out", "", "output directory (e.g. dist/navis-release/darwin-arm64)")
|
||||
version := flag.String("version", "1.4.1", "CFBundleShortVersionString")
|
||||
arch := flag.String("arch", "arm64", "arch label for volume name")
|
||||
flag.Parse()
|
||||
if *bin == "" || *outDir == "" {
|
||||
fmt.Fprintln(os.Stderr, "usage: packmac -bin <Navis> -out <dir> [-version 1.4.1] [-arch arm64]")
|
||||
os.Exit(2)
|
||||
}
|
||||
if err := run(*bin, *outDir, *version, *arch); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "packmac: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(binPath, outDir, version, arch string) error {
|
||||
if err := os.MkdirAll(outDir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
stage, err := os.MkdirTemp("", "navis-packmac-*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(stage)
|
||||
|
||||
appRoot := filepath.Join(stage, "Navis.app")
|
||||
if err := writeAppBundle(appRoot, binPath, version); err != nil {
|
||||
return err
|
||||
}
|
||||
readme := filepath.Join(stage, "README.txt")
|
||||
if err := os.WriteFile(readme, []byte(readmeText(version, arch)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
zipPath := filepath.Join(outDir, "Navis.app.zip")
|
||||
if err := zipDir(zipPath, stage, []string{"Navis.app", "README.txt"}); err != nil {
|
||||
return fmt.Errorf("zip: %w", err)
|
||||
}
|
||||
fmt.Println("wrote", zipPath)
|
||||
|
||||
dmgPath := filepath.Join(outDir, "Navis.dmg")
|
||||
if err := writeDMG(dmgPath, appRoot, readme, "Navis-"+arch); err != nil {
|
||||
return fmt.Errorf("dmg: %w", err)
|
||||
}
|
||||
fmt.Println("wrote", dmgPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeAppBundle(appRoot, binPath, version string) error {
|
||||
macOSDir := filepath.Join(appRoot, "Contents", "MacOS")
|
||||
if err := os.MkdirAll(macOSDir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
plist := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key><string>Navis</string>
|
||||
<key>CFBundleIdentifier</key><string>win.evilfox.navis</string>
|
||||
<key>CFBundleName</key><string>Navis</string>
|
||||
<key>CFBundlePackageType</key><string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key><string>%s</string>
|
||||
<key>CFBundleVersion</key><string>%s</string>
|
||||
<key>LSMinimumSystemVersion</key><string>11.0</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
`, version, version)
|
||||
if err := os.WriteFile(filepath.Join(appRoot, "Contents", "Info.plist"), []byte(plist), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
dest := filepath.Join(macOSDir, "Navis")
|
||||
if err := copyFile(binPath, dest, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeDMG(dmgPath, appRoot, readmePath, volume string) error {
|
||||
_ = os.Remove(dmgPath)
|
||||
appSize, err := dirSize(appRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readmeSize, err := fileSize(readmePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
need := appSize + readmeSize + 4*1024*1024
|
||||
if need < 12*1024*1024 {
|
||||
need = 12 * 1024 * 1024
|
||||
}
|
||||
// round up to 2048
|
||||
need = ((need + 2047) / 2048) * 2048
|
||||
|
||||
mydisk, err := diskfs.Create(dmgPath, need, diskfs.SectorSizeDefault)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mydisk.LogicalBlocksize = 2048
|
||||
fs, err := mydisk.CreateFilesystem(disk.FilesystemSpec{
|
||||
Partition: 0,
|
||||
FSType: filesystem.TypeISO9660,
|
||||
VolumeLabel: sanitizeVol(volume),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyTreeToISO(fs, appRoot, "/Navis.app"); err != nil {
|
||||
_ = fs.Close()
|
||||
return err
|
||||
}
|
||||
if err := writeISOFile(fs, "/README.txt", readmePath, 0o644); err != nil {
|
||||
_ = fs.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
iso, ok := fs.(*iso9660.FileSystem)
|
||||
if !ok {
|
||||
_ = fs.Close()
|
||||
return fmt.Errorf("not iso9660")
|
||||
}
|
||||
if err := iso.Finalize(iso9660.FinalizeOptions{
|
||||
RockRidge: true,
|
||||
Joliet: true,
|
||||
DeepDirectories: true,
|
||||
VolumeIdentifier: sanitizeVol(volume),
|
||||
PublisherIdentifier: "Navis",
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return fs.Close()
|
||||
}
|
||||
|
||||
func copyTreeToISO(fs filesystem.FileSystem, srcRoot, dstRoot string) error {
|
||||
return filepath.Walk(srcRoot, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel, err := filepath.Rel(srcRoot, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel = filepath.ToSlash(rel)
|
||||
dst := dstRoot
|
||||
if rel != "." {
|
||||
dst = dstRoot + "/" + rel
|
||||
}
|
||||
if info.IsDir() {
|
||||
if dst == dstRoot {
|
||||
return fs.Mkdir(dst)
|
||||
}
|
||||
return fs.Mkdir(dst)
|
||||
}
|
||||
mode := info.Mode()
|
||||
if mode&0o111 != 0 || strings.HasSuffix(rel, "MacOS/Navis") || strings.HasSuffix(rel, "MacOS\\Navis") {
|
||||
mode = 0o755
|
||||
} else {
|
||||
mode = 0o644
|
||||
}
|
||||
return writeISOFile(fs, dst, path, mode)
|
||||
})
|
||||
}
|
||||
|
||||
func writeISOFile(fs filesystem.FileSystem, dst, src string, mode os.FileMode) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
rw, err := fs.OpenFile(dst, os.O_CREATE|os.O_RDWR|os.O_TRUNC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(rw, in); err != nil {
|
||||
_ = rw.Close()
|
||||
return err
|
||||
}
|
||||
if err := rw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.Chmod(dst, mode); err != nil {
|
||||
_ = err // best-effort
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func zipDir(zipPath, stage string, entries []string) error {
|
||||
_ = os.Remove(zipPath)
|
||||
f, err := os.Create(zipPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
zw := zip.NewWriter(f)
|
||||
defer zw.Close()
|
||||
|
||||
for _, name := range entries {
|
||||
root := filepath.Join(stage, name)
|
||||
info, err := os.Stat(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
if err := addZipFile(zw, root, name, 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel, err := filepath.Rel(stage, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel = filepath.ToSlash(rel)
|
||||
if fi.IsDir() {
|
||||
_, err := zw.Create(rel + "/")
|
||||
return err
|
||||
}
|
||||
mode := os.FileMode(0o644)
|
||||
if strings.Contains(rel, "Contents/MacOS/") {
|
||||
mode = 0o755
|
||||
}
|
||||
return addZipFile(zw, path, rel, mode)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addZipFile(zw *zip.Writer, path, name string, mode os.FileMode) error {
|
||||
h, err := zip.FileInfoHeader(mustStat(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.Name = name
|
||||
h.Method = zip.Deflate
|
||||
h.SetMode(mode)
|
||||
w, err := zw.CreateHeader(h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
in, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
_, err = io.Copy(w, in)
|
||||
return err
|
||||
}
|
||||
|
||||
func mustStat(path string) os.FileInfo {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return fi
|
||||
}
|
||||
|
||||
func copyFile(src, dst string, mode os.FileMode) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
out, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
_, err = io.Copy(out, in)
|
||||
return err
|
||||
}
|
||||
|
||||
func dirSize(root string) (int64, error) {
|
||||
var n int64
|
||||
err := filepath.Walk(root, func(_ string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
n += info.Size()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return n, err
|
||||
}
|
||||
|
||||
func fileSize(path string) (int64, error) {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return fi.Size(), nil
|
||||
}
|
||||
|
||||
func sanitizeVol(s string) string {
|
||||
s = strings.ToUpper(s)
|
||||
s = strings.Map(func(r rune) rune {
|
||||
if (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '-' || r == '_' {
|
||||
return r
|
||||
}
|
||||
return '-'
|
||||
}, s)
|
||||
if len(s) > 32 {
|
||||
s = s[:32]
|
||||
}
|
||||
if s == "" {
|
||||
s = "NAVIS"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func readmeText(version, arch string) string {
|
||||
return fmt.Sprintf(`Navis %s for macOS (%s)
|
||||
|
||||
1) Open this disk image
|
||||
2) Drag Navis.app to Applications (or any folder)
|
||||
3) First launch may need:
|
||||
xattr -dr com.apple.quarantine /Applications/Navis.app
|
||||
4) Run from Terminal:
|
||||
/Applications/Navis.app/Contents/MacOS/Navis init
|
||||
/Applications/Navis.app/Contents/MacOS/Navis install-core
|
||||
/Applications/Navis.app/Contents/MacOS/Navis connect
|
||||
|
||||
Or use the CLI binary next to this DMG on git (file named Navis).
|
||||
|
||||
Shop: https://evilfox.win/
|
||||
`, version, arch)
|
||||
}
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"FixedFileInfo": {
|
||||
"FileVersion": { "Major": 1, "Minor": 4, "Patch": 0, "Build": 0 },
|
||||
"ProductVersion": { "Major": 1, "Minor": 4, "Patch": 0, "Build": 0 },
|
||||
"FileVersion": { "Major": 1, "Minor": 4, "Patch": 1, "Build": 0 },
|
||||
"ProductVersion": { "Major": 1, "Minor": 4, "Patch": 1, "Build": 0 },
|
||||
"FileFlagsMask": "3f",
|
||||
"FileFlags": "00",
|
||||
"FileOS": "40004",
|
||||
@@ -11,11 +11,11 @@
|
||||
"StringFileInfo": {
|
||||
"CompanyName": "Navis",
|
||||
"FileDescription": "Navis — NaiveProxy / Hysteria 2 client for Windows and macOS",
|
||||
"FileVersion": "1.4.0.0",
|
||||
"FileVersion": "1.4.1.0",
|
||||
"InternalName": "Navis",
|
||||
"OriginalFilename": "Navis.exe",
|
||||
"ProductName": "Navis",
|
||||
"ProductVersion": "1.4.0.0"
|
||||
"ProductVersion": "1.4.1.0"
|
||||
},
|
||||
"VarFileInfo": {
|
||||
"Translation": {
|
||||
|
||||
Reference in New Issue
Block a user