Skip to content

Commit dfeb712

Browse files
committed
feat: added multi-platform distribution support
1 parent 664ebbd commit dfeb712

9 files changed

Lines changed: 284 additions & 53 deletions

File tree

.dockerignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
target/
2+
.git/
3+
.github/
4+
.gitignore
5+
*.md
6+
!README.md
7+
Dockerfile
8+
.dockerignore
9+
dist/
10+
snap/

.github/workflows/release.yml

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,44 @@ env:
99
CARGO_TERM_COLOR: always
1010
BINARY_NAME: null-e
1111

12+
permissions:
13+
contents: write
14+
1215
jobs:
13-
# Build binaries for all platforms
1416
build:
1517
name: Build ${{ matrix.target }}
1618
runs-on: ${{ matrix.os }}
1719
strategy:
1820
fail-fast: false
1921
matrix:
2022
include:
21-
# macOS
22-
- os: macos-latest
23-
target: x86_64-apple-darwin
24-
artifact_name: null-e
25-
asset_name: null-e-x86_64-apple-darwin
26-
27-
- os: macos-latest
28-
target: aarch64-apple-darwin
29-
artifact_name: null-e
30-
asset_name: null-e-aarch64-apple-darwin
31-
3223
# Linux
3324
- os: ubuntu-latest
3425
target: x86_64-unknown-linux-gnu
3526
artifact_name: null-e
36-
asset_name: null-e-x86_64-unknown-linux-gnu
37-
27+
asset_name: null-e-linux-x86_64
3828
- os: ubuntu-latest
3929
target: x86_64-unknown-linux-musl
4030
artifact_name: null-e
41-
asset_name: null-e-x86_64-unknown-linux-musl
42-
31+
asset_name: null-e-linux-x86_64-musl
32+
- os: ubuntu-latest
33+
target: aarch64-unknown-linux-gnu
34+
artifact_name: null-e
35+
asset_name: null-e-linux-aarch64
36+
# macOS
37+
- os: macos-latest
38+
target: x86_64-apple-darwin
39+
artifact_name: null-e
40+
asset_name: null-e-darwin-x86_64
41+
- os: macos-latest
42+
target: aarch64-apple-darwin
43+
artifact_name: null-e
44+
asset_name: null-e-darwin-aarch64
4345
# Windows
4446
- os: windows-latest
4547
target: x86_64-pc-windows-msvc
4648
artifact_name: null-e.exe
47-
asset_name: null-e-x86_64-pc-windows-msvc
49+
asset_name: null-e-windows-x86_64
4850

4951
steps:
5052
- uses: actions/checkout@v4
@@ -58,6 +60,12 @@ jobs:
5860
if: matrix.target == 'x86_64-unknown-linux-musl'
5961
run: sudo apt-get update && sudo apt-get install -y musl-tools
6062

63+
- name: Install cross-compilation tools (Linux aarch64)
64+
if: matrix.target == 'aarch64-unknown-linux-gnu'
65+
run: |
66+
sudo apt-get update
67+
sudo apt-get install -y gcc-aarch64-linux-gnu
68+
6169
- name: Cache cargo
6270
uses: actions/cache@v4
6371
with:
@@ -71,37 +79,41 @@ jobs:
7179

7280
- name: Build
7381
run: cargo build --release --target ${{ matrix.target }}
82+
env:
83+
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
7484

75-
- name: Package (Unix)
85+
- name: Create tarball (Unix)
7686
if: runner.os != 'Windows'
7787
run: |
7888
cd target/${{ matrix.target }}/release
79-
tar -czvf ../../../${{ matrix.asset_name }}.tar.gz ${{ matrix.artifact_name }}
89+
tar czvf ../../../${{ matrix.asset_name }}.tar.gz ${{ matrix.artifact_name }}
8090
cd ../../..
91+
shasum -a 256 ${{ matrix.asset_name }}.tar.gz > ${{ matrix.asset_name }}.tar.gz.sha256
8192
82-
- name: Package (Windows)
93+
- name: Create zip (Windows)
8394
if: runner.os == 'Windows'
95+
shell: pwsh
8496
run: |
8597
cd target/${{ matrix.target }}/release
86-
7z a ../../../${{ matrix.asset_name }}.zip ${{ matrix.artifact_name }}
98+
Compress-Archive -Path ${{ matrix.artifact_name }} -DestinationPath ../../../${{ matrix.asset_name }}.zip
8799
cd ../../..
100+
(Get-FileHash ${{ matrix.asset_name }}.zip -Algorithm SHA256).Hash.ToLower() + " " + "${{ matrix.asset_name }}.zip" | Out-File -Encoding ASCII ${{ matrix.asset_name }}.zip.sha256
88101
89102
- name: Upload artifact
90103
uses: actions/upload-artifact@v4
91104
with:
92105
name: ${{ matrix.asset_name }}
93106
path: |
94-
${{ matrix.asset_name }}.tar.gz
95-
${{ matrix.asset_name }}.zip
107+
*.tar.gz
108+
*.tar.gz.sha256
109+
*.zip
110+
*.zip.sha256
111+
if-no-files-found: ignore
96112

97-
# Create GitHub Release
98113
release:
99114
name: Create Release
100115
needs: build
101116
runs-on: ubuntu-latest
102-
permissions:
103-
contents: write
104-
105117
steps:
106118
- uses: actions/checkout@v4
107119

@@ -110,44 +122,38 @@ jobs:
110122
with:
111123
path: artifacts
112124

113-
- name: Display structure
114-
run: ls -la artifacts/
125+
- name: Flatten artifacts
126+
run: |
127+
mkdir -p release
128+
find artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" -o -name "*.sha256" \) -exec mv {} release/ \;
129+
ls -la release/
115130
116131
- name: Create Release
117132
uses: softprops/action-gh-release@v2
118133
with:
119-
files: |
120-
artifacts/**/*.tar.gz
121-
artifacts/**/*.zip
134+
files: release/*
122135
generate_release_notes: true
123136
draft: false
124137
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
125138
env:
126139
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
127140

128-
# Publish to crates.io
129-
publish-crates:
141+
publish-crate:
130142
name: Publish to crates.io
131143
needs: release
132144
runs-on: ubuntu-latest
133-
134145
steps:
135146
- uses: actions/checkout@v4
136-
137-
- name: Install Rust
138-
uses: dtolnay/rust-toolchain@stable
139-
140-
- name: Publish to crates.io
147+
- uses: dtolnay/rust-toolchain@stable
148+
- name: Publish
141149
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
142-
continue-on-error: true # Don't fail if already published
150+
continue-on-error: true
143151

144-
# Update Homebrew tap
145152
update-homebrew:
146153
name: Update Homebrew Formula
147154
needs: release
148155
runs-on: ubuntu-latest
149156
if: ${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}
150-
151157
steps:
152158
- name: Update Homebrew formula
153159
uses: mislav/bump-homebrew-formula-action@v3
@@ -157,4 +163,4 @@ jobs:
157163
download-url: https://github.com/us/null-e/archive/refs/tags/${{ github.ref_name }}.tar.gz
158164
env:
159165
COMMITTER_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
160-
continue-on-error: true # Don't fail if tap doesn't exist yet
166+
continue-on-error: true

Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Build stage
2+
FROM rust:1.75-alpine AS builder
3+
4+
WORKDIR /app
5+
6+
# Install build dependencies
7+
RUN apk add --no-cache musl-dev
8+
9+
# Copy source
10+
COPY Cargo.toml Cargo.lock ./
11+
COPY src ./src
12+
13+
# Build release binary
14+
RUN cargo build --release --locked
15+
16+
# Runtime stage
17+
FROM alpine:3.19
18+
19+
# Install runtime dependencies
20+
RUN apk add --no-cache ca-certificates
21+
22+
# Copy binary from builder
23+
COPY --from=builder /app/target/release/null-e /usr/local/bin/null-e
24+
25+
# Create non-root user
26+
RUN adduser -D -u 1000 nulle
27+
USER nulle
28+
29+
WORKDIR /workspace
30+
31+
ENTRYPOINT ["null-e"]
32+
CMD ["--help"]

README.md

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
null-e helps developers reclaim disk space by finding and cleaning development artifacts, caches, and unused files. It can detect and clean **100+ GB** of reclaimable space across your system.
1515

16+
[![Crates.io](https://img.shields.io/crates/v/null-e.svg)](https://crates.io/crates/null-e)
17+
[![Downloads](https://img.shields.io/crates/d/null-e.svg)](https://crates.io/crates/null-e)
1618
![Rust](https://img.shields.io/badge/rust-1.75+-orange.svg)
1719
![License](https://img.shields.io/badge/license-MIT-blue.svg)
1820
![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey.svg)
@@ -53,25 +55,48 @@ null-e helps developers reclaim disk space by finding and cleaning development a
5355

5456
## Installation
5557

56-
### From Source
58+
### Using Cargo (Recommended)
5759

5860
```bash
59-
git clone https://github.com/us/null-e.git
60-
cd null-e
61-
cargo install --path .
61+
cargo install null-e
6262
```
6363

64-
### Using Cargo
64+
### Pre-built Binaries
65+
66+
Download from [GitHub Releases](https://github.com/us/null-e/releases):
67+
- **macOS**: `null-e-darwin-aarch64.tar.gz` (Apple Silicon) / `null-e-darwin-x86_64.tar.gz` (Intel)
68+
- **Linux**: `null-e-linux-x86_64.tar.gz` / `null-e-linux-aarch64.tar.gz`
69+
- **Windows**: `null-e-windows-x86_64.zip`
70+
71+
### Package Managers
6572

6673
```bash
67-
cargo install null-e
74+
# Homebrew (macOS/Linux) - requires 75+ stars for homebrew-core
75+
brew install null-e # coming soon
76+
77+
# Scoop (Windows)
78+
scoop bucket add us https://github.com/us/scoop-bucket
79+
scoop install null-e
80+
81+
# AUR (Arch Linux)
82+
yay -S null-e
83+
84+
# Nix
85+
nix-env -iA nixpkgs.null-e # coming soon
6886
```
6987

70-
### Using Homebrew (macOS)
88+
### Docker
7189

7290
```bash
73-
brew tap us/tap
74-
brew install null-e
91+
docker run -v $(pwd):/workspace ghcr.io/us/null-e
92+
```
93+
94+
### From Source
95+
96+
```bash
97+
git clone https://github.com/us/null-e.git
98+
cd null-e
99+
cargo install --path .
75100
```
76101

77102
## Quick Start

dist/aur/.SRCINFO

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
pkgbase = null-e
2+
pkgdesc = The friendly disk cleanup robot - send your cruft to /dev/null
3+
pkgver = 0.1.0
4+
pkgrel = 1
5+
url = https://github.com/us/null-e
6+
arch = x86_64
7+
arch = aarch64
8+
license = MIT
9+
makedepends = rust
10+
makedepends = cargo
11+
depends = gcc-libs
12+
source = null-e-0.1.0.tar.gz::https://github.com/us/null-e/archive/v0.1.0.tar.gz
13+
sha256sums = SKIP
14+
15+
pkgname = null-e

dist/aur/PKGBUILD

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Maintainer: us <rahmetsaritekin@gmail.com>
2+
pkgname=null-e
3+
pkgver=0.1.0
4+
pkgrel=1
5+
pkgdesc="The friendly disk cleanup robot - send your cruft to /dev/null"
6+
arch=('x86_64' 'aarch64')
7+
url="https://github.com/us/null-e"
8+
license=('MIT')
9+
depends=('gcc-libs')
10+
makedepends=('rust' 'cargo')
11+
source=("$pkgname-$pkgver.tar.gz::https://github.com/us/null-e/archive/v$pkgver.tar.gz")
12+
sha256sums=('SKIP')
13+
14+
build() {
15+
cd "$pkgname-$pkgver"
16+
export RUSTUP_TOOLCHAIN=stable
17+
export CARGO_TARGET_DIR=target
18+
cargo build --frozen --release --all-features
19+
}
20+
21+
check() {
22+
cd "$pkgname-$pkgver"
23+
export RUSTUP_TOOLCHAIN=stable
24+
cargo test --frozen --all-features
25+
}
26+
27+
package() {
28+
cd "$pkgname-$pkgver"
29+
install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/$pkgname"
30+
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
31+
install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md"
32+
}

0 commit comments

Comments
 (0)