Skip to content

Commit fc22c92

Browse files
committed
release
1 parent 0f77518 commit fc22c92

File tree

4 files changed

+373
-3
lines changed

4 files changed

+373
-3
lines changed

.github/workflows/release.yml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Publish to GitHub Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
jobs:
10+
check-version:
11+
runs-on: ubuntu-latest
12+
outputs:
13+
version_changed: ${{ steps.check.outputs.version_changed }}
14+
version: ${{ steps.check.outputs.version }}
15+
steps:
16+
- name: Check out the code
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 2
20+
21+
- name: Check if version changed
22+
id: check
23+
run: |
24+
CURRENT_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
25+
echo "version=${CURRENT_VERSION}" >> "$GITHUB_OUTPUT"
26+
27+
# For workflow_dispatch, always treat as changed
28+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
29+
echo "version_changed=true" >> "$GITHUB_OUTPUT"
30+
echo "Manual trigger — treating version ${CURRENT_VERSION} as changed"
31+
exit 0
32+
fi
33+
34+
PREV_VERSION=$(git show HEAD~1:Cargo.toml 2>/dev/null | grep '^version' | head -1 | sed 's/.*"\(.*\)".*/\1/' || echo "")
35+
36+
if [ "$CURRENT_VERSION" != "$PREV_VERSION" ]; then
37+
echo "version_changed=true" >> "$GITHUB_OUTPUT"
38+
echo "Version changed: ${PREV_VERSION} -> ${CURRENT_VERSION}"
39+
else
40+
echo "version_changed=false" >> "$GITHUB_OUTPUT"
41+
echo "Version unchanged: ${CURRENT_VERSION}"
42+
fi
43+
44+
build:
45+
needs: check-version
46+
if: needs.check-version.outputs.version_changed == 'true'
47+
strategy:
48+
fail-fast: false
49+
matrix:
50+
include:
51+
- target: x86_64-unknown-linux-gnu
52+
os: ubuntu-latest
53+
archive: tar.gz
54+
- target: aarch64-unknown-linux-gnu
55+
os: ubuntu-latest
56+
archive: tar.gz
57+
- target: x86_64-apple-darwin
58+
os: macos-latest
59+
archive: tar.gz
60+
- target: aarch64-apple-darwin
61+
os: macos-latest
62+
archive: tar.gz
63+
- target: x86_64-pc-windows-msvc
64+
os: windows-latest
65+
archive: zip
66+
runs-on: ${{ matrix.os }}
67+
permissions:
68+
contents: read
69+
steps:
70+
- name: Check out the code
71+
uses: actions/checkout@v4
72+
73+
- name: Install Rust toolchain
74+
uses: dtolnay/rust-toolchain@stable
75+
with:
76+
targets: ${{ matrix.target }}
77+
78+
- name: Install cross-compilation tools (Linux ARM64)
79+
if: matrix.target == 'aarch64-unknown-linux-gnu'
80+
run: |
81+
sudo apt-get update
82+
sudo apt-get install -y gcc-aarch64-linux-gnu
83+
84+
- name: Build release binary
85+
env:
86+
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
87+
run: cargo build --release --target ${{ matrix.target }}
88+
89+
- name: Package (Unix)
90+
if: matrix.archive == 'tar.gz'
91+
run: |
92+
BINARY_NAME="reaper"
93+
ARCHIVE_NAME="reaper-v${{ needs.check-version.outputs.version }}-${{ matrix.target }}.tar.gz"
94+
cd target/${{ matrix.target }}/release
95+
tar czf "../../../${ARCHIVE_NAME}" "${BINARY_NAME}"
96+
cd ../../..
97+
echo "ARCHIVE_NAME=${ARCHIVE_NAME}" >> "$GITHUB_ENV"
98+
99+
- name: Package (Windows)
100+
if: matrix.archive == 'zip'
101+
shell: pwsh
102+
run: |
103+
$BINARY_NAME = "reaper.exe"
104+
$ARCHIVE_NAME = "reaper-v${{ needs.check-version.outputs.version }}-${{ matrix.target }}.zip"
105+
Compress-Archive -Path "target/${{ matrix.target }}/release/$BINARY_NAME" -DestinationPath "$ARCHIVE_NAME"
106+
echo "ARCHIVE_NAME=$ARCHIVE_NAME" >> $env:GITHUB_ENV
107+
108+
- name: Upload artifact
109+
uses: actions/upload-artifact@v4
110+
with:
111+
name: reaper-${{ matrix.target }}
112+
path: ${{ env.ARCHIVE_NAME }}
113+
retention-days: 1
114+
115+
release:
116+
needs: [check-version, build]
117+
runs-on: ubuntu-latest
118+
permissions:
119+
contents: write
120+
steps:
121+
- name: Check out the code
122+
uses: actions/checkout@v4
123+
124+
- name: Download all artifacts
125+
uses: actions/download-artifact@v4
126+
with:
127+
path: artifacts
128+
merge-multiple: true
129+
130+
- name: List artifacts
131+
run: ls -R artifacts/
132+
133+
- name: Generate checksums
134+
run: |
135+
cd artifacts
136+
sha256sum reaper-* > checksums-sha256.txt
137+
cat checksums-sha256.txt
138+
139+
- name: Create GitHub Release
140+
uses: softprops/action-gh-release@v2
141+
with:
142+
tag_name: v${{ needs.check-version.outputs.version }}
143+
name: Reaper v${{ needs.check-version.outputs.version }}
144+
generate_release_notes: true
145+
draft: false
146+
prerelease: false
147+
files: |
148+
artifacts/reaper-*
149+
artifacts/checksums-sha256.txt

README.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,27 @@ Reaper reads your **entire project at once** and cross-references every definiti
4242

4343
## ⚡ Quickstart
4444

45+
### Install pre-built binary (recommended)
46+
47+
Pre-built binaries are published on every version bump to [GitHub Releases](https://github.com/taradepan/reaper/releases).
48+
49+
**Linux / macOS (single command):**
50+
51+
```bash
52+
curl -fsSL https://raw.githubusercontent.com/taradepan/reaper/main/install.sh | sh
53+
```
54+
55+
**Windows (PowerShell):**
56+
57+
```powershell
58+
irm https://raw.githubusercontent.com/taradepan/reaper/main/install.ps1 | iex
59+
```
60+
4561
### Install from source
4662

4763
```bash
4864
# Clone and build
49-
git clone https://github.com/YOUR_USERNAME/reaper.git
65+
git clone https://github.com/taradepan/reaper.git
5066
cd reaper
5167
cargo build --release
5268

@@ -385,7 +401,31 @@ These are **always** skipped — you never need to list them manually:
385401

386402
## 🤖 CI Integration
387403

388-
### GitHub Actions
404+
### GitHub Actions (pre-built binary — fast ⚡)
405+
406+
No Rust toolchain needed. Downloads the pre-built binary from GitHub Releases in ~2 seconds.
407+
408+
```yaml
409+
name: Dead Code Check
410+
411+
on: [push, pull_request]
412+
413+
jobs:
414+
reaper:
415+
runs-on: ubuntu-latest
416+
steps:
417+
- uses: actions/checkout@v4
418+
419+
- name: Install Reaper
420+
run: curl -fsSL https://raw.githubusercontent.com/taradepan/reaper/main/install.sh | sh
421+
422+
- name: Find dead code
423+
run: reaper --exclude tests .
424+
```
425+
426+
### GitHub Actions (build from source)
427+
428+
If you prefer to always build from the latest commit:
389429
390430
```yaml
391431
name: Dead Code Check
@@ -402,7 +442,7 @@ jobs:
402442
uses: dtolnay/rust-toolchain@stable
403443

404444
- name: Install Reaper
405-
run: cargo install --git https://github.com/YOUR_USERNAME/reaper.git
445+
run: cargo install --git https://github.com/taradepan/reaper.git
406446

407447
- name: Find dead code
408448
run: reaper --exclude tests .

install.ps1

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#Requires -Version 5.1
2+
Set-StrictMode -Version Latest
3+
$ErrorActionPreference = "Stop"
4+
5+
$Repo = "taradepan/reaper"
6+
$Binary = "reaper.exe"
7+
8+
function Write-Info {
9+
param([string]$Message)
10+
Write-Host $Message -ForegroundColor Cyan
11+
}
12+
13+
function Write-Err {
14+
param([string]$Message)
15+
Write-Host "error: $Message" -ForegroundColor Red
16+
exit 1
17+
}
18+
19+
function Get-Target {
20+
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
21+
switch ($arch) {
22+
"X64" { return "x86_64-pc-windows-msvc" }
23+
default { Write-Err "Unsupported architecture: $arch. Only x86_64 Windows is currently supported." }
24+
}
25+
}
26+
27+
function Get-LatestVersion {
28+
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest"
29+
$tag = $release.tag_name
30+
if (-not $tag) {
31+
Write-Err "Could not determine the latest version. Check https://github.com/$Repo/releases"
32+
}
33+
return $tag -replace '^v', ''
34+
}
35+
36+
function Main {
37+
$target = Get-Target
38+
Write-Info "Detected target: $target"
39+
40+
Write-Info "Fetching latest version..."
41+
$version = Get-LatestVersion
42+
Write-Info "Latest version: v$version"
43+
44+
$archive = "reaper-v${version}-${target}.zip"
45+
$url = "https://github.com/$Repo/releases/download/v${version}/$archive"
46+
47+
$tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) ("reaper-install-" + [guid]::NewGuid().ToString("N"))
48+
New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
49+
50+
try {
51+
$archivePath = Join-Path $tmpDir $archive
52+
Write-Info "Downloading $url..."
53+
Invoke-WebRequest -Uri $url -OutFile $archivePath -UseBasicParsing
54+
55+
Write-Info "Extracting..."
56+
Expand-Archive -Path $archivePath -DestinationPath $tmpDir -Force
57+
58+
$installDir = Join-Path $env:LOCALAPPDATA "reaper"
59+
if (-not (Test-Path $installDir)) {
60+
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
61+
}
62+
63+
$dest = Join-Path $installDir $Binary
64+
Move-Item -Path (Join-Path $tmpDir $Binary) -Destination $dest -Force
65+
66+
# Add to PATH if not already there
67+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
68+
if ($userPath -notlike "*$installDir*") {
69+
Write-Info "Adding $installDir to your PATH..."
70+
[Environment]::SetEnvironmentVariable("Path", "$userPath;$installDir", "User")
71+
$env:Path = "$env:Path;$installDir"
72+
}
73+
74+
Write-Info "Installed reaper v$version to $dest"
75+
Write-Info "Run 'reaper --help' to get started."
76+
Write-Info ""
77+
Write-Info "NOTE: You may need to restart your terminal for PATH changes to take effect."
78+
}
79+
finally {
80+
Remove-Item -Path $tmpDir -Recurse -Force -ErrorAction SilentlyContinue
81+
}
82+
}
83+
84+
Main

0 commit comments

Comments
 (0)