Skip to content

Commit 2826377

Browse files
committed
add install scripts
1 parent cf2982f commit 2826377

File tree

5 files changed

+389
-0
lines changed

5 files changed

+389
-0
lines changed

.github/workflows/release.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
include:
14+
- goos: darwin
15+
goarch: amd64
16+
ext: ""
17+
- goos: darwin
18+
goarch: arm64
19+
ext: ""
20+
- goos: windows
21+
goarch: amd64
22+
ext: ".exe"
23+
- goos: windows
24+
goarch: arm64
25+
ext: ".exe"
26+
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Set up Go
31+
uses: actions/setup-go@v5
32+
with:
33+
go-version: "1.20"
34+
35+
- name: Build
36+
env:
37+
GOOS: ${{ matrix.goos }}
38+
GOARCH: ${{ matrix.goarch }}
39+
CGO_ENABLED: "0"
40+
TAG: ${{ github.ref_name }}
41+
run: |
42+
mkdir -p dist
43+
go build -ldflags "-s -w -X main.version=${TAG}" -o "dist/vpeak${{ matrix.ext }}" ./cmd/vpeak
44+
45+
- name: Package
46+
env:
47+
GOOS: ${{ matrix.goos }}
48+
GOARCH: ${{ matrix.goarch }}
49+
TAG: ${{ github.ref_name }}
50+
run: |
51+
mkdir -p dist/pkg
52+
if [ "${GOOS}" = "windows" ]; then
53+
zip -j "dist/pkg/vpeak_${TAG}_${GOOS}_${GOARCH}.zip" "dist/vpeak.exe"
54+
else
55+
tar -czf "dist/pkg/vpeak_${TAG}_${GOOS}_${GOARCH}.tar.gz" -C dist "vpeak"
56+
fi
57+
58+
- name: Upload artifacts
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: vpeak-${{ matrix.goos }}-${{ matrix.goarch }}
62+
path: dist/pkg/*
63+
64+
release:
65+
needs: build
66+
runs-on: ubuntu-latest
67+
permissions:
68+
contents: write
69+
70+
steps:
71+
- name: Download artifacts
72+
uses: actions/download-artifact@v4
73+
with:
74+
path: dist
75+
merge-multiple: true
76+
77+
- name: Generate checksums
78+
run: |
79+
cd dist
80+
sha256sum *.tar.gz *.zip > checksums.txt
81+
ls -la
82+
83+
- name: Release
84+
uses: softprops/action-gh-release@v2
85+
with:
86+
files: |
87+
dist/**/*.tar.gz
88+
dist/**/*.zip
89+
dist/checksums.txt
90+
fail_on_unmatched_files: true

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,50 @@ You may need to manually delete the files after playback if you don't want them
2121

2222
### Installation
2323

24+
#### Recommended (prebuilt binaries)
25+
26+
macOS (curl):
27+
28+
```sh
29+
curl -fsSL https://raw.githubusercontent.com/shinshin86/vpeak/main/install.sh | bash
30+
```
31+
32+
Windows (PowerShell):
33+
34+
```powershell
35+
irm https://raw.githubusercontent.com/shinshin86/vpeak/main/install.ps1 | iex
36+
```
37+
38+
Note: the macOS installer places `vpeak` in `~/.local/bin` by default. Set `BIN_DIR` to change the install path if needed.
39+
40+
Verify:
41+
42+
```sh
43+
vpeak --version
44+
```
45+
46+
Update to a specific version:
47+
48+
```sh
49+
curl -fsSL https://raw.githubusercontent.com/shinshin86/vpeak/main/install.sh | bash -s -- vX.Y.Z
50+
```
51+
52+
```powershell
53+
irm https://raw.githubusercontent.com/shinshin86/vpeak/main/install.ps1 | iex -Version vX.Y.Z
54+
```
55+
56+
Uninstall:
57+
58+
```sh
59+
rm -f ~/.local/bin/vpeak
60+
```
61+
62+
```powershell
63+
Remove-Item "$env:LOCALAPPDATA\\Programs\\vpeak\\vpeak.exe"
64+
```
65+
66+
#### Go install (source)
67+
2468
To install `vpeak` as a CLI tool, run the following command:
2569

2670
```sh

cmd/vpeak/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"github.com/shinshin86/vpeak"
1111
)
1212

13+
var version = "dev"
14+
1315
func main() {
1416
var (
1517
dirOpt = flag.String("d", "", "Directory to read files from")
@@ -19,6 +21,7 @@ func main() {
1921
speedOpt = flag.String("speed", "", "Specify the speech speed (50-200)")
2022
pitchOpt = flag.String("pitch", "", "Specify the pitch adjustment (-300 - 300)")
2123
silentOpt = flag.Bool("silent", false, "Silent mode (no sound)")
24+
versionOpt = flag.Bool("version", false, "Show version")
2225
)
2326

2427
flag.Usage = func() {
@@ -49,6 +52,11 @@ func main() {
4952
os.Exit(0)
5053
}
5154

55+
if *versionOpt {
56+
fmt.Println(version)
57+
os.Exit(0)
58+
}
59+
5260
if len(flag.Args()) == 0 && *dirOpt == "" {
5361
log.Fatalf("Usage: %s [-n] <text>", os.Args[0])
5462
}

install.ps1

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
Param(
2+
[string]$Version = "latest"
3+
)
4+
5+
$Owner = "shinshin86"
6+
$Repo = "vpeak"
7+
$BinName = "vpeak.exe"
8+
$BinDir = "$env:LOCALAPPDATA\Programs\vpeak"
9+
10+
function Write-Info {
11+
Param([string]$Message)
12+
Write-Host "Info: $Message"
13+
}
14+
15+
function Write-ErrorMessage {
16+
Param([string]$Message)
17+
Write-Host "Error: $Message" -ForegroundColor Red
18+
}
19+
20+
function Assert-Command {
21+
Param([string]$Command)
22+
if (-not (Get-Command $Command -ErrorAction SilentlyContinue)) {
23+
throw "Required command not found: $Command"
24+
}
25+
}
26+
27+
function Get-Arch {
28+
$arch = $env:PROCESSOR_ARCHITECTURE
29+
if ($env:PROCESSOR_ARCHITEW6432) {
30+
$arch = $env:PROCESSOR_ARCHITEW6432
31+
}
32+
33+
switch ($arch) {
34+
"AMD64" { return "amd64" }
35+
"ARM64" { return "arm64" }
36+
default { throw "Unsupported architecture: $arch" }
37+
}
38+
}
39+
40+
function Get-LatestVersion {
41+
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Owner/$Repo/releases/latest"
42+
if (-not $release.tag_name) {
43+
throw "Failed to fetch latest version"
44+
}
45+
return $release.tag_name
46+
}
47+
48+
function Get-Checksum {
49+
Param(
50+
[string]$ChecksumsPath,
51+
[string]$Asset
52+
)
53+
$lines = Get-Content -Path $ChecksumsPath
54+
foreach ($line in $lines) {
55+
if ($line -match "\s+$Asset$") {
56+
return $line.Split(" ")[0].ToLower()
57+
}
58+
}
59+
return $null
60+
}
61+
62+
function Add-ToPath {
63+
Param([string]$Path)
64+
$current = [Environment]::GetEnvironmentVariable("Path", "User")
65+
if ($null -eq $current) {
66+
$current = ""
67+
}
68+
if ($current -notlike "*$Path*") {
69+
$newPath = $current
70+
if ($newPath -ne "" -and -not $newPath.EndsWith(";")) {
71+
$newPath += ";"
72+
}
73+
$newPath += $Path
74+
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
75+
$env:Path = "$env:Path;$Path"
76+
Write-Info "Added $Path to PATH (user)"
77+
}
78+
}
79+
80+
function Invoke-Download {
81+
Param(
82+
[string]$Uri,
83+
[string]$OutFile
84+
)
85+
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -MaximumRedirection 10 | Out-Null
86+
}
87+
88+
$TempDir = $null
89+
90+
try {
91+
Assert-Command "PowerShell"
92+
Assert-Command "Expand-Archive"
93+
94+
if ($Version -eq "latest") {
95+
Write-Info "Fetching latest version..."
96+
$Version = Get-LatestVersion
97+
}
98+
99+
$Arch = Get-Arch
100+
$Asset = "vpeak_${Version}_windows_${Arch}.zip"
101+
$BaseUrl = "https://github.com/$Owner/$Repo/releases/download/$Version"
102+
103+
$TempDir = New-Item -ItemType Directory -Path ([System.IO.Path]::GetTempPath()) -Name "vpeak_$((Get-Random))"
104+
$ZipPath = Join-Path $TempDir $Asset
105+
$ChecksumPath = Join-Path $TempDir "checksums.txt"
106+
107+
Write-Info "Downloading $BaseUrl/$Asset..."
108+
Invoke-Download -Uri "$BaseUrl/$Asset" -OutFile $ZipPath
109+
110+
Write-Info "Downloading checksums..."
111+
Invoke-Download -Uri "$BaseUrl/checksums.txt" -OutFile $ChecksumPath
112+
113+
$Expected = Get-Checksum -ChecksumsPath $ChecksumPath -Asset $Asset
114+
if (-not $Expected) {
115+
throw "Checksum not found for $Asset"
116+
}
117+
118+
Write-Info "Verifying checksum..."
119+
$Actual = (Get-FileHash -Algorithm SHA256 -Path $ZipPath).Hash.ToLower()
120+
if ($Actual -ne $Expected) {
121+
throw "Checksum mismatch. expected=$Expected actual=$Actual"
122+
}
123+
124+
Write-Info "Installing to $BinDir..."
125+
if (-not (Test-Path $BinDir)) {
126+
New-Item -ItemType Directory -Path $BinDir | Out-Null
127+
}
128+
129+
Expand-Archive -Path $ZipPath -DestinationPath $TempDir -Force
130+
131+
$InstalledBin = Join-Path $BinDir $BinName
132+
if (Test-Path $InstalledBin) {
133+
$Backup = "$InstalledBin.bak"
134+
Write-Info "Backing up existing binary to $Backup"
135+
Copy-Item $InstalledBin $Backup -Force
136+
}
137+
138+
Copy-Item (Join-Path $TempDir $BinName) $InstalledBin -Force
139+
140+
Add-ToPath $BinDir
141+
142+
Write-Info "Done! Run 'vpeak --version' to verify."
143+
} catch {
144+
Write-ErrorMessage $_
145+
exit 1
146+
} finally {
147+
if ($TempDir -and (Test-Path $TempDir)) {
148+
Remove-Item $TempDir -Recurse -Force
149+
}
150+
}

0 commit comments

Comments
 (0)