Skip to content

Commit fd4d973

Browse files
committed
Add auto update
Changelog(feat)
1 parent fcdbc6e commit fd4d973

8 files changed

Lines changed: 336 additions & 2 deletions

File tree

.github/workflows/release.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,28 @@ jobs:
220220
name: "VIIPER ${{ steps.build_info.outputs.version }}"
221221
body: |
222222
${{ needs.generate-changelog.outputs.changelog }}
223+
224+
---
225+
226+
## Install / Update
227+
228+
<details>
229+
<summary><b>Windows (PowerShell)</b></summary>
230+
231+
```powershell
232+
irm https://alia5.github.io/VIIPER/stable/install.ps1 | iex
233+
```
234+
Installs / updates to `%LOCALAPPDATA%\VIIPER\viiper.exe`
235+
</details>
236+
237+
<details>
238+
<summary><b>Linux</b></summary>
239+
240+
```bash
241+
curl -fsSL https://alia5.github.io/VIIPER/stable/install.sh | sh
242+
```
243+
Installs / updates to `/usr/local/bin/viiper`
244+
</details>
223245
files: release_files/*
224246
prerelease: false
225247
draft: true

.github/workflows/snapshots.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,27 @@ jobs:
116116
⚠️ These are the latest development builds and may contain bugs or unfinished features.
117117
118118
${{ needs.generate-changelog.outputs.changelog }}
119+
120+
---
121+
122+
## Install / Update
123+
124+
<details>
125+
<summary><b>Windows (PowerShell)</b></summary>
126+
127+
```powershell
128+
irm https://alia5.github.io/VIIPER/main/install.ps1 | iex
129+
```
130+
Installs / updates to `%LOCALAPPDATA%\VIIPER\viiper.exe`
131+
</details>
132+
133+
<details>
134+
<summary><b>Linux</b></summary>
135+
136+
```bash
137+
curl -fsSL https://alia5.github.io/VIIPER/main/install.sh | sh
138+
```
139+
Installs / updates to `/usr/local/bin/viiper`
140+
</details>
119141
files: |
120142
./release_files/*

cmd/viiper/viiper.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77
"log/slog"
88
"os"
99
"strings"
10+
"time"
1011

1112
"github.com/Alia5/VIIPER/internal/config"
1213
"github.com/Alia5/VIIPER/internal/configpaths"
1314
"github.com/Alia5/VIIPER/internal/log"
15+
"github.com/Alia5/VIIPER/internal/updater"
1416

1517
_ "github.com/Alia5/VIIPER/internal/registry" // Register all device handlers
1618

@@ -54,6 +56,16 @@ func main() {
5456
ctx.Bind(logger)
5557
ctx.BindTo(rawLogger, (*log.RawLogger)(nil))
5658

59+
if cli.UpdateNotify != config.UpdateNotifyNone {
60+
go func() {
61+
time.Sleep(10 * time.Second)
62+
updater.CheckUpdate(Version, cli.UpdateNotify)
63+
for range time.NewTicker(1 * time.Hour).C {
64+
updater.CheckUpdate(Version, cli.UpdateNotify)
65+
}
66+
}()
67+
}
68+
5769
err = ctx.Run()
5870
ctx.FatalIfErrorf(err)
5971
}

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ require (
1717
require (
1818
github.com/Zyko0/go-sdl3 v0.0.0-20260125144524-02de3d449cb1 // indirect
1919
github.com/Zyko0/purego-gen v0.0.0-20250727121216-3bcd331a1e0c // indirect
20+
github.com/akavel/rsrc v0.10.2 // indirect
2021
github.com/davecgh/go-spew v1.1.1 // indirect
22+
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f // indirect
2123
github.com/ebitengine/purego v0.9.0-alpha.2.0.20250124174847-29f0104e3c2b // indirect
24+
github.com/josephspurrier/goversioninfo v1.4.1 // indirect
2225
github.com/kr/text v0.2.0 // indirect
26+
github.com/ncruces/zenity v0.10.14 // indirect
2327
github.com/pmezard/go-difflib v1.0.0 // indirect
28+
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 // indirect
2429
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
30+
golang.org/x/image v0.34.0 // indirect
2531
)

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/Zyko0/go-sdl3 v0.0.0-20260125144524-02de3d449cb1 h1:a7BoGQPgciWaIwBlh
22
github.com/Zyko0/go-sdl3 v0.0.0-20260125144524-02de3d449cb1/go.mod h1:mJcKev/gsLraiuXsB/EPyh4hdYnsUHyNU5CXch3cv0A=
33
github.com/Zyko0/purego-gen v0.0.0-20250727121216-3bcd331a1e0c h1:3z1BdpfvUbaP7oXjPabl7STN7zz88S432hZJ8M095kI=
44
github.com/Zyko0/purego-gen v0.0.0-20250727121216-3bcd331a1e0c/go.mod h1:xpUxPkAb7v0Ffn/NGp1XpD+tZly4dpSPI7DTAFT37es=
5+
github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
6+
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
57
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
68
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
79
github.com/alecthomas/kong v1.13.0 h1:5e/7XC3ugvhP1DQBmTS+WuHtCbcv44hsohMgcvVxSrA=
@@ -13,32 +15,46 @@ github.com/alecthomas/kong-yaml v0.2.0/go.mod h1:vMvOIy+wpB49MCZ0TA3KMts38Mu9YfR
1315
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
1416
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
1517
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
18+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1619
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1720
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
21+
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f h1:OGqDDftRTwrvUoL6pOG7rYTmWsTCvyEWFsMjg+HcOaA=
22+
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f/go.mod h1:Dv9D0NUlAsaQcGQZa5kc5mqR9ua72SmA8VXi4cd+cBw=
1823
github.com/ebitengine/purego v0.9.0-alpha.2.0.20250124174847-29f0104e3c2b h1:/KAOJuXR4cWaQIiA9xBMDSQJ1JXq5gZHdSK8prrtUqQ=
1924
github.com/ebitengine/purego v0.9.0-alpha.2.0.20250124174847-29f0104e3c2b/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
2025
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
2126
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
27+
github.com/josephspurrier/goversioninfo v1.4.1 h1:5LvrkP+n0tg91J9yTkoVnt/QgNnrI1t4uSsWjIonrqY=
28+
github.com/josephspurrier/goversioninfo v1.4.1/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY=
2229
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
2330
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
2431
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2532
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
33+
github.com/ncruces/zenity v0.10.14 h1:OBFl7qfXcvsdo1NUEGxTlZvAakgWMqz9nG38TuiaGLI=
34+
github.com/ncruces/zenity v0.10.14/go.mod h1:ZBW7uVe/Di3IcRYH0Br8X59pi+O6EPnNIOU66YHpOO4=
2635
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
2736
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
2837
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2938
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
39+
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 h1:GranzK4hv1/pqTIhMTXt2X8MmMOuH3hMeUR0o9SP5yc=
40+
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844/go.mod h1:T1TLSfyWVBRXVGzWd0o9BI4kfoO9InEgfQe4NV3mLz8=
41+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
42+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3043
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
3144
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
3245
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
3346
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
3447
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
3548
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
49+
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
50+
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
3651
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
3752
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
3853
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
3954
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
4055
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4156
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
4257
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
58+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
4359
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4460
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/config/config.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ import (
55
"github.com/Alia5/VIIPER/internal/cmd"
66
)
77

8+
type UpdateNotify string
9+
10+
const (
11+
UpdateNotifyNone UpdateNotify = "none"
12+
UpdateNotifyStable UpdateNotify = "stable"
13+
UpdateNotifyPrerelease UpdateNotify = "prerelease"
14+
)
15+
816
type Log struct {
917
Level string `help:"Log level: trace, debug, info, warn, error" default:"info" env:"VIIPER_LOG_LEVEL"`
1018
File string `help:"Log file path (default: none; logs only to console)" env:"VIIPER_LOG_FILE"`
@@ -14,8 +22,9 @@ type Log struct {
1422
// CLI is the root command structure for Kong CLI parsing.
1523
type CLI struct {
1624
// Global
17-
ConfigPath string `help:"Path to configuration file (json|yaml|toml)" name:"config" env:"VIIPER_CONFIG"`
18-
Log `embed:"" prefix:"log."`
25+
ConfigPath string `help:"Path to configuration file (json|yaml|toml)" name:"config" env:"VIIPER_CONFIG"`
26+
UpdateNotify UpdateNotify `help:"Update notification level: none, stable, prerelease" default:"stable" env:"VIIPER_UPDATE_NOTIFY"`
27+
Log `embed:"" prefix:"log."`
1928

2029
Server cmd.Server `cmd:"" help:"Start the VIIPER USB-IP server"`
2130
Proxy cmd.Proxy `cmd:"" help:"Start the VIIPER USB-IP proxy"`

internal/updater/msgbox.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package updater
2+
3+
import (
4+
"runtime"
5+
6+
"github.com/ncruces/zenity"
7+
)
8+
9+
func showMessageBox(title, message string) int {
10+
options := []string{"Update Now", "View on GitHub", "Remind Me Later", "Skip This Version"}
11+
if runtime.GOOS == "linux" {
12+
options = []string{"View on GitHub", "Remind Me Later", "Skip This Version"}
13+
}
14+
choice, err := zenity.List(
15+
message,
16+
options,
17+
zenity.Title(title),
18+
)
19+
if err != nil {
20+
return ActionRemindLater
21+
}
22+
switch choice {
23+
case "Update Now":
24+
return ActionUpdateNow
25+
case "View on GitHub":
26+
return ActionViewGitHub
27+
case "Skip This Version":
28+
return ActionDismiss
29+
default:
30+
return ActionRemindLater
31+
}
32+
}

0 commit comments

Comments
 (0)