Skip to content

Commit 191da6a

Browse files
committed
chore: Bump version to 0.5.2 and add GitHub release automation
- Bump workspace version from 0.5.1 to 0.5.2 - Add CD workflow for automated GitHub releases on version tags - Add install.sh script for Unix-like systems with auto-detection for Linux/macOS and x86_64/aarch64 - Add install.ps1 script for Windows with support for x64 and ARM64 architectures - Both installers support version override and custom install directory via environment variables - Installers automatically add binary to PATH and
1 parent e1f6b08 commit 191da6a

File tree

5 files changed

+209
-9
lines changed

5 files changed

+209
-9
lines changed

.github/workflows/cd.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CD
2+
3+
on:
4+
push:
5+
tags: ["v*.*.*"]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
call-cd:
13+
uses: qntx/workflows/.github/workflows/rust-cd.yml@main
14+
with:
15+
bin: kobe
16+
package: kobe-cli

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ default-members = ["kobe"]
44
resolver = "3"
55

66
[workspace.package]
7-
version = "0.5.1"
7+
version = "0.5.2"
88
edition = "2024"
99
license = "MIT OR Apache-2.0"
1010
repository = "https://github.com/qntx/kobe"

install.ps1

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# CLI installer — downloads the latest release binary from GitHub.
2+
# Configure $Repo and $Bin below. Everything else is derived automatically.
3+
#
4+
# Environment (upper-cased $Bin prefix):
5+
# <BIN>_VERSION Override version (default: latest)
6+
# <BIN>_INSTALL_DIR Override install directory (default: %LOCALAPPDATA%\<bin>)
7+
8+
$ErrorActionPreference = "Stop"
9+
$InformationPreference = "Continue"
10+
$Repo = "qntx/kobe"
11+
$Bin = "kobe"
12+
13+
$BinUpper = $Bin.ToUpper()
14+
$VerEnv = "${BinUpper}_VERSION"
15+
$DirEnv = "${BinUpper}_INSTALL_DIR"
16+
17+
function Get-TargetArch {
18+
try {
19+
$a = [System.Reflection.Assembly]::LoadWithPartialName("System.Runtime.InteropServices.RuntimeInformation")
20+
switch ($a.GetType("System.Runtime.InteropServices.RuntimeInformation").GetProperty("OSArchitecture").GetValue($null).ToString()) {
21+
"X64" { return "x86_64-pc-windows-msvc" }
22+
"Arm64" { return "aarch64-pc-windows-msvc" }
23+
}
24+
}
25+
catch {}
26+
if ([Environment]::Is64BitOperatingSystem) { return "x86_64-pc-windows-msvc" }
27+
throw "32-bit Windows is not supported"
28+
}
29+
30+
function Get-LatestVersion {
31+
$tag = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name
32+
if ($tag.StartsWith("v")) { $tag = $tag.Substring(1) }
33+
return $tag
34+
}
35+
36+
function Add-ToUserPath($Dir) {
37+
$reg = 'registry::HKEY_CURRENT_USER\Environment'
38+
$current = (Get-Item -LiteralPath $reg).GetValue('Path', '', 'DoNotExpandEnvironmentNames') -split ';' -ne ''
39+
if ($Dir -in $current) { return }
40+
41+
Set-ItemProperty -Type ExpandString -LiteralPath $reg Path ((@($Dir) + $current) -join ';')
42+
# Broadcast WM_SETTINGCHANGE so Explorer picks up the new PATH
43+
$k = "$Bin-" + [guid]::NewGuid().ToString()
44+
[Environment]::SetEnvironmentVariable($k, "1", "User")
45+
[Environment]::SetEnvironmentVariable($k, [NullString]::value, "User")
46+
47+
Write-Information " Added $Dir to PATH (restart your shell to apply)"
48+
}
49+
50+
try {
51+
$target = Get-TargetArch
52+
$envVer = [Environment]::GetEnvironmentVariable($VerEnv)
53+
$envDir = [Environment]::GetEnvironmentVariable($DirEnv)
54+
$ver = if ($envVer) { $envVer } else { Get-LatestVersion }
55+
$dir = if ($envDir) { $envDir } else { Join-Path $env:LOCALAPPDATA $Bin }
56+
57+
Write-Information "Installing $Bin v$ver ($target)"
58+
59+
$url = "https://github.com/$Repo/releases/download/v$ver/$Bin-$ver-$target.zip"
60+
$tmp = New-Item -ItemType Directory -Path (Join-Path ([IO.Path]::GetTempPath()) ([Guid]::NewGuid()))
61+
62+
try {
63+
Invoke-WebRequest -Uri $url -OutFile "$tmp\archive.zip" -UseBasicParsing
64+
Expand-Archive "$tmp\archive.zip" -DestinationPath $tmp -Force
65+
66+
$null = New-Item -ItemType Directory -Force -Path $dir
67+
Copy-Item "$tmp\$Bin.exe" -Destination $dir -Force
68+
Write-Information " -> $(Join-Path $dir "$Bin.exe")"
69+
}
70+
finally {
71+
Remove-Item $tmp -Recurse -Force -ErrorAction SilentlyContinue
72+
}
73+
74+
# Add to PATH if needed
75+
if ($env:GITHUB_PATH) {
76+
$dir | Out-File $env:GITHUB_PATH -Encoding utf8 -Append
77+
}
78+
elseif (-not ($env:Path -split ';' | Where-Object { $_ -eq $dir })) {
79+
Add-ToUserPath $dir
80+
}
81+
82+
Write-Information "`n$Bin v$ver installed successfully!"
83+
}
84+
catch {
85+
Write-Error $_
86+
exit 1
87+
}

install.sh

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/bin/sh
2+
# CLI installer — downloads the latest release binary from GitHub.
3+
# Configure REPO and BIN below. Everything else is derived automatically.
4+
#
5+
# Environment (upper-cased BIN prefix):
6+
# <BIN>_VERSION Override version (default: latest)
7+
# <BIN>_INSTALL_DIR Override install directory (default: ~/.local/bin)
8+
9+
set -eu
10+
11+
REPO="qntx/kobe"
12+
BIN="kobe"
13+
14+
BIN_UPPER=$(echo "$BIN" | tr '[:lower:]' '[:upper:]')
15+
16+
say() { printf '\033[1m%s\033[0m\n' "$*"; }
17+
err() { printf '\033[31merror\033[0m: %s\n' "$*" >&2; exit 1; }
18+
19+
fetch() {
20+
if command -v curl >/dev/null 2>&1; then curl -fsSL "$1"
21+
elif command -v wget >/dev/null 2>&1; then wget -qO- "$1"
22+
else err "curl or wget is required"; fi
23+
}
24+
25+
download() {
26+
if command -v curl >/dev/null 2>&1; then curl -fsSL -o "$2" "$1"
27+
elif command -v wget >/dev/null 2>&1; then wget -q -O "$2" "$1"
28+
else err "curl or wget is required"; fi
29+
}
30+
31+
detect_target() {
32+
os=$(uname -s)
33+
arch=$(uname -m)
34+
35+
case "$os" in
36+
Linux) os="unknown-linux-gnu" ;;
37+
Darwin)
38+
os="apple-darwin"
39+
# Detect Apple Silicon behind Rosetta 2
40+
[ "$arch" = x86_64 ] && sysctl -n hw.optional.arm64 2>/dev/null | grep -q 1 && arch=aarch64
41+
;;
42+
*) err "unsupported OS: $os" ;;
43+
esac
44+
45+
case "$arch" in
46+
x86_64 | amd64) arch=x86_64 ;;
47+
aarch64 | arm64) arch=aarch64 ;;
48+
*) err "unsupported architecture: $arch" ;;
49+
esac
50+
51+
echo "${arch}-${os}"
52+
}
53+
54+
latest_version() {
55+
tag=$(fetch "https://api.github.com/repos/$REPO/releases/latest" \
56+
| grep '"tag_name"' | head -1 | cut -d'"' -f4)
57+
[ -n "$tag" ] || err "failed to detect latest version"
58+
echo "${tag#v}"
59+
}
60+
61+
main() {
62+
target=$(detect_target)
63+
eval "ver=\${${BIN_UPPER}_VERSION:-\$(latest_version)}"
64+
eval "dir=\${${BIN_UPPER}_INSTALL_DIR:-\$HOME/.local/bin}"
65+
66+
say "Installing $BIN v$ver ($target)"
67+
68+
url="https://github.com/$REPO/releases/download/v$ver/$BIN-$ver-$target.tar.gz"
69+
tmp=$(mktemp -d)
70+
trap 'rm -rf "$tmp"' EXIT
71+
72+
download "$url" "$tmp/archive.tar.gz"
73+
tar xzf "$tmp/archive.tar.gz" -C "$tmp"
74+
75+
mkdir -p "$dir"
76+
install -m 755 "$tmp/$BIN" "$dir/$BIN"
77+
78+
say "$dir/$BIN"
79+
80+
# Add to PATH if needed
81+
case ":${PATH}:" in *":$dir:"*) return ;; esac
82+
83+
line="export PATH=\"$dir:\$PATH\""
84+
for rc in .zshrc .bashrc .bash_profile .profile; do
85+
[ -f "$HOME/$rc" ] || continue
86+
grep -qF "$dir" "$HOME/$rc" 2>/dev/null && return
87+
printf '\n%s\n' "$line" >> "$HOME/$rc"
88+
say " Added $dir to PATH in ~/$rc (restart your shell to apply)"
89+
return
90+
done
91+
92+
# No rc file found — create .profile
93+
printf '%s\n' "$line" > "$HOME/.profile"
94+
say " Created ~/.profile with PATH entry (restart your shell to apply)"
95+
}
96+
97+
main

0 commit comments

Comments
 (0)