Skip to content

Commit ec191d2

Browse files
committed
ci: add installer smoke checks and multi-arch runners
Validate one-liner installers on Linux/macOS/Windows, expand CI and release matrices to x64+arm64, and update install/docs examples to match signed/unsigned GH behavior.
1 parent ed66bbe commit ec191d2

9 files changed

Lines changed: 208 additions & 21 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@ on:
88

99
jobs:
1010
test:
11-
runs-on: ${{ matrix.os }}
11+
name: test (${{ matrix.label }})
12+
runs-on: ${{ matrix.runner }}
1213
strategy:
1314
fail-fast: false
1415
matrix:
15-
os: [ubuntu-latest, macos-latest, windows-latest]
16+
include:
17+
- label: linux-x64
18+
runner: ubuntu-latest
19+
- label: linux-arm64
20+
runner: ubuntu-24.04-arm
21+
- label: macos-x64
22+
runner: macos-13
23+
- label: macos-arm64
24+
runner: macos-latest
25+
- label: windows-x64
26+
runner: windows-latest
27+
- label: windows-arm64
28+
runner: windows-11-arm
1629

1730
steps:
1831
- uses: actions/checkout@v4
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: Installer Smoke
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
workflow_dispatch:
9+
10+
jobs:
11+
one-liner:
12+
name: one-liner (${{ matrix.label }})
13+
runs-on: ${{ matrix.runner }}
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- label: linux-x64
19+
runner: ubuntu-latest
20+
- label: linux-arm64
21+
runner: ubuntu-24.04-arm
22+
- label: macos-x64
23+
runner: macos-13
24+
- label: macos-arm64
25+
runner: macos-latest
26+
- label: windows-x64
27+
runner: windows-latest
28+
- label: windows-arm64
29+
runner: windows-11-arm
30+
31+
steps:
32+
- uses: actions/checkout@v4
33+
34+
- name: Set up Dart
35+
uses: dart-lang/setup-dart@v1
36+
37+
- name: Install dependencies
38+
run: dart pub get
39+
40+
- name: Build local payload (Linux/macOS)
41+
if: runner.os != 'Windows'
42+
shell: bash
43+
run: |
44+
set -euo pipefail
45+
os_raw="$(uname -s | tr '[:upper:]' '[:lower:]')"
46+
case "$os_raw" in
47+
linux*) os="linux" ;;
48+
darwin*) os="macos" ;;
49+
*) echo "Unsupported OS: $os_raw"; exit 1 ;;
50+
esac
51+
arch_raw="$(uname -m | tr '[:upper:]' '[:lower:]')"
52+
case "$arch_raw" in
53+
x86_64|amd64) arch="x64" ;;
54+
arm64|aarch64) arch="arm64" ;;
55+
*) echo "Unsupported architecture: $arch_raw"; exit 1 ;;
56+
esac
57+
asset="drx-${os}-${arch}"
58+
59+
serve_root="$RUNNER_TEMP/serve"
60+
mkdir -p "$serve_root/download" "$serve_root/tool"
61+
62+
dart compile exe bin/drx.dart -o "$serve_root/download/$asset"
63+
shasum -a 256 "$serve_root/download/$asset" > "$serve_root/download/$asset.sha256"
64+
65+
cp tool/install.sh "$serve_root/tool/install.sh"
66+
67+
- name: Build local payload (Windows)
68+
if: runner.os == 'Windows'
69+
shell: pwsh
70+
run: |
71+
$archRaw = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant()
72+
switch ($archRaw) {
73+
'x64' { $arch = 'x64' }
74+
'arm64' { $arch = 'arm64' }
75+
default { throw "Unsupported architecture: $archRaw" }
76+
}
77+
$asset = "drx-windows-$arch.exe"
78+
79+
$serveRoot = Join-Path $env:RUNNER_TEMP "serve"
80+
New-Item -ItemType Directory -Path (Join-Path $serveRoot "download") -Force | Out-Null
81+
New-Item -ItemType Directory -Path (Join-Path $serveRoot "tool") -Force | Out-Null
82+
83+
$assetPath = Join-Path $serveRoot "download/$asset"
84+
dart compile exe bin/drx.dart -o $assetPath
85+
86+
$hash = (Get-FileHash -Algorithm SHA256 $assetPath).Hash.ToLower()
87+
"$hash $asset" | Out-File -Encoding ascii (Join-Path $serveRoot "download/$asset.sha256")
88+
89+
Copy-Item tool/install.ps1 (Join-Path $serveRoot "tool/install.ps1")
90+
91+
- name: Test one-liner install (Linux/macOS)
92+
if: runner.os != 'Windows'
93+
shell: bash
94+
run: |
95+
set -euo pipefail
96+
port=18080
97+
serve_root="$RUNNER_TEMP/serve"
98+
99+
python3 -m http.server "$port" --directory "$serve_root" >"$RUNNER_TEMP/http.log" 2>&1 &
100+
server_pid=$!
101+
trap 'kill "$server_pid"' EXIT INT TERM
102+
sleep 2
103+
104+
curl -fsSL "http://127.0.0.1:${port}/tool/install.sh" | \
105+
DRX_REPO=example/drx \
106+
DRX_DOWNLOAD_BASE="http://127.0.0.1:${port}/download" \
107+
DRX_INSTALL_DIR="$RUNNER_TEMP/bin" \
108+
sh
109+
110+
"$RUNNER_TEMP/bin/drx" --version
111+
"$RUNNER_TEMP/bin/drx" cache list --json
112+
113+
- name: Test one-liner install (Windows)
114+
if: runner.os == 'Windows'
115+
shell: pwsh
116+
run: |
117+
$port = 18080
118+
$serveRoot = Join-Path $env:RUNNER_TEMP "serve"
119+
$stdoutLog = Join-Path $env:RUNNER_TEMP "http-out.log"
120+
$stderrLog = Join-Path $env:RUNNER_TEMP "http-err.log"
121+
$server = Start-Process -FilePath python -ArgumentList "-m","http.server",$port,"--directory",$serveRoot -RedirectStandardOutput $stdoutLog -RedirectStandardError $stderrLog -PassThru
122+
Start-Sleep -Seconds 2
123+
124+
try {
125+
$env:DRX_REPO = "example/drx"
126+
$env:DRX_DOWNLOAD_BASE = "http://127.0.0.1:$port/download"
127+
$env:DRX_INSTALL_DIR = Join-Path $env:RUNNER_TEMP "bin"
128+
129+
Invoke-WebRequest -Uri "http://127.0.0.1:$port/tool/install.ps1" -UseBasicParsing | Invoke-Expression
130+
131+
$drxExe = Join-Path (Join-Path $env:RUNNER_TEMP "bin") "drx.exe"
132+
& $drxExe --version
133+
& $drxExe cache list --json
134+
}
135+
finally {
136+
if (-not $server.HasExited) {
137+
Stop-Process -Id $server.Id -Force
138+
}
139+
}

.github/workflows/release-binaries.yml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,24 @@ permissions:
1616

1717
jobs:
1818
build:
19-
runs-on: ${{ matrix.os }}
19+
name: build (${{ matrix.label }})
20+
runs-on: ${{ matrix.runner }}
2021
strategy:
2122
fail-fast: false
2223
matrix:
23-
os: [ubuntu-latest, macos-latest, windows-latest]
24+
include:
25+
- label: linux-x64
26+
runner: ubuntu-latest
27+
- label: linux-arm64
28+
runner: ubuntu-24.04-arm
29+
- label: macos-x64
30+
runner: macos-13
31+
- label: macos-arm64
32+
runner: macos-latest
33+
- label: windows-x64
34+
runner: windows-latest
35+
- label: windows-arm64
36+
runner: windows-11-arm
2437

2538
steps:
2639
- uses: actions/checkout@v4
@@ -67,7 +80,7 @@ jobs:
6780
- name: Upload platform artifacts
6881
uses: actions/upload-artifact@v4
6982
with:
70-
name: drx-${{ runner.os }}
83+
name: drx-${{ matrix.label }}
7184
path: build/*
7285

7386
publish-release:
@@ -93,4 +106,5 @@ jobs:
93106
uses: softprops/action-gh-release@v2
94107
with:
95108
tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
109+
overwrite_files: true
96110
files: dist/*

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- Add `--json` output mode for cache and versions commands.
1515
- Support global utility flags before command verbs (for example `--json versions`).
1616
- Add GH version-list fallback to repository tags when releases are absent.
17+
- Add one-liner installer smoke tests across Linux/macOS/Windows.
18+
- Expand binary build matrix to include Intel macOS and ARM Linux/Windows.
1719

1820
## 0.1.0
1921

README.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,28 @@ Examples:
2929
```bash
3030
drx melos -- --version
3131
drx mason_cli:mason -- --help
32-
drx --from pub:very_good_cli@0.20.0 very_good -- --help
32+
drx --from pub:very_good_cli very_good -- --help
3333
drx --from gh:cli/cli@v2.70.0 gh -- version
3434
drx --from gh:BurntSushi/ripgrep rg -- --version
35-
drx --from gh:sharkdp/fd fd -- --version
3635
drx --from gh:junegunn/fzf fzf -- --version
37-
drx --from gh:sharkdp/bat bat -- --version
38-
drx --from gh:dandavison/delta delta -- --version
39-
drx --from gh:jqlang/jq jq -- --version
4036
drx --from gh:charmbracelet/gum gum -- --version
37+
drx --allow-unsigned --from gh:sharkdp/fd fd -- --version
38+
drx --allow-unsigned --from gh:sharkdp/bat bat -- --version
39+
drx --allow-unsigned --from gh:dandavison/delta delta -- --version
4140
drx versions melos --limit 5
4241
drx versions gh:cli/cli --limit 10
4342
drx cache list
4443
drx cache prune --max-age-days 30 --max-size-mb 2048
4544
```
4645

46+
Note: some repositories do not publish checksums. Those require
47+
`--allow-unsigned` as shown above.
48+
4749
## Cross-Platform Support
4850

49-
- macOS: supported
50-
- Linux: supported by implementation and CI workflow
51-
- Windows: supported by implementation and CI workflow
51+
- Linux: `x64`, `arm64`
52+
- macOS: `x64` (Intel), `arm64` (Apple Silicon)
53+
- Windows: `x64`, `arm64`
5254

5355
`drx` handles Windows executable resolution (`.exe`, `.cmd`, `.bat`) and
5456
Unix executable permissions for downloaded binaries.
@@ -191,11 +193,15 @@ installing binaries.
191193
The repository includes ready workflows for CI and binary release publishing:
192194

193195
- `.github/workflows/ci.yml`
196+
- `.github/workflows/installer-smoke.yml`
194197
- `.github/workflows/release-binaries.yml`
195198

196199
`release-binaries.yml` runs on pushed tags (`v*`) and also supports manual
197200
dispatch with a required `tag` input.
198201

202+
`installer-smoke.yml` validates one-liner install scripts on Linux/macOS/Windows
203+
across `x64` and `arm64` runners.
204+
199205
## Development
200206

201207
```bash

doc/compatibility.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ assets match platform/arch naming and include checksums.
8383
Examples:
8484

8585
- `my_tool-linux-x64.tar.gz`
86+
- `my_tool-linux-arm64.tar.gz`
87+
- `my_tool-macos-x64.tar.gz`
8688
- `my_tool-macos-arm64.tar.gz`
8789
- `my_tool-windows-x64.exe`
90+
- `my_tool-windows-arm64.exe`
8891

8992
### Supported formats in drx
9093

@@ -118,11 +121,11 @@ Real-world examples:
118121
```bash
119122
drx --from gh:cli/cli gh -- version
120123
drx --from gh:BurntSushi/ripgrep rg -- --version
121-
drx --from gh:sharkdp/fd fd -- --version
122-
drx --from gh:sharkdp/bat bat -- --version
123-
drx --from gh:dandavison/delta delta -- --version
124-
drx --from gh:jqlang/jq jq -- --version
124+
drx --from gh:junegunn/fzf fzf -- --version
125125
drx --from gh:charmbracelet/gum gum -- --version
126+
drx --allow-unsigned --from gh:sharkdp/fd fd -- --version
127+
drx --allow-unsigned --from gh:sharkdp/bat bat -- --version
128+
drx --allow-unsigned --from gh:dandavison/delta delta -- --version
126129
```
127130

128131
### Security behavior

example/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ drx mason_cli:mason -- --help
1616
Use `drx` with explicit sources:
1717

1818
```sh
19-
drx --from pub:very_good_cli@0.28.0 very_good -- --help
19+
drx --from pub:very_good_cli very_good -- --help
2020
drx --from gh:cli/cli@v2.70.0 gh -- version
2121
drx --from gh:BurntSushi/ripgrep rg -- --version
22-
drx --from gh:sharkdp/fd fd -- --version
22+
drx --from gh:junegunn/fzf fzf -- --version
23+
drx --from gh:charmbracelet/gum gum -- --version
24+
drx --allow-unsigned --from gh:sharkdp/fd fd -- --version
2325
```
2426

2527
Use runtime controls for pub tools:

tool/install.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ switch ($arch) {
1818
}
1919

2020
$asset = "drx-windows-$archToken.exe"
21+
$downloadBase = $env:DRX_DOWNLOAD_BASE
2122

22-
if ($Version -eq "latest") {
23+
if ($downloadBase) {
24+
$downloadBase = $downloadBase.TrimEnd('/')
25+
$url = "$downloadBase/$asset"
26+
} elseif ($Version -eq "latest") {
2327
$url = "https://github.com/$Repository/releases/latest/download/$asset"
2428
} else {
2529
$url = "https://github.com/$Repository/releases/download/$Version/$asset"

tool/install.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set -eu
44
REPO="${DRX_REPO:-}"
55
VERSION="latest"
66
INSTALL_DIR="${DRX_INSTALL_DIR:-$HOME/.local/bin}"
7+
DOWNLOAD_BASE="${DRX_DOWNLOAD_BASE:-}"
78

89
while [ "$#" -gt 0 ]; do
910
case "$1" in
@@ -60,7 +61,10 @@ esac
6061

6162
ASSET="drx-${OS}-${ARCH}"
6263

63-
if [ "$VERSION" = "latest" ]; then
64+
if [ -n "$DOWNLOAD_BASE" ]; then
65+
DOWNLOAD_BASE="${DOWNLOAD_BASE%/}"
66+
URL="${DOWNLOAD_BASE}/${ASSET}"
67+
elif [ "$VERSION" = "latest" ]; then
6468
URL="https://github.com/${REPO}/releases/latest/download/${ASSET}"
6569
else
6670
URL="https://github.com/${REPO}/releases/download/${VERSION}/${ASSET}"

0 commit comments

Comments
 (0)