feat: add Linux distro installers (AUR, .deb, .rpm, Nix)#13
Conversation
Add packaging for Arch (AUR PKGBUILDs), Debian/Ubuntu (cargo-deb), Fedora/RHEL (cargo-generate-rpm), and NixOS (flake.nix). The release workflow now builds .deb and .rpm packages from pre-compiled binaries and attaches them to GitHub releases. https://claude.ai/code/session_019G3ZUhQckYm8JNcTjeNt34
There was a problem hiding this comment.
Pull request overview
Adds Linux distribution packaging and release automation so modelsdev can be installed via AUR, .deb, .rpm, and Nix flakes, with .deb/.rpm artifacts attached to GitHub Releases.
Changes:
- Add Arch Linux AUR PKGBUILDs for source (
-git) and prebuilt (-bin) installs. - Add Nix flake for building and a Rust dev shell.
- Extend release workflow and Cargo metadata to generate
.deband.rpmartifacts; document new install options in the README.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packaging/aur/modelsdev-git/PKGBUILD | Adds AUR VCS/source package definition. |
| packaging/aur/modelsdev-bin/PKGBUILD | Adds AUR binary package definition that downloads GitHub Release tarballs. |
| flake.nix | Adds Nix flake packaging + devShell. |
| README.md | Documents new Linux installation methods. |
| Cargo.toml | Adds cargo-deb and cargo-generate-rpm packaging metadata. |
| .github/workflows/release.yml | Adds a Linux packaging job and publishes .deb/.rpm to the release. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ["target/release/models", "usr/bin/", "755"], | ||
| ] | ||
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | ||
| depends = "libc6" | ||
|
|
||
| [package.metadata.generate-rpm] | ||
| assets = [ | ||
| { source = "target/release/models", dest = "/usr/bin/models", mode = "0755" }, |
There was a problem hiding this comment.
In a --target build, the extracted precompiled binary is placed under target/<triple>/release/models, but the cargo-deb assets list points at target/release/models. This mismatch will make cargo deb --no-build --target ... fail (missing asset) or accidentally package the wrong binary. Align the asset source path with where the workflow places the binary (or adjust the workflow to copy/symlink the binary to target/release/models before running the packagers).
| ["target/release/models", "usr/bin/", "755"], | |
| ] | |
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | |
| depends = "libc6" | |
| [package.metadata.generate-rpm] | |
| assets = [ | |
| { source = "target/release/models", dest = "/usr/bin/models", mode = "0755" }, | |
| ["target/*/release/models", "usr/bin/", "755"], | |
| ] | |
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | |
| depends = "libc6" | |
| [package.metadata.generate-rpm] | |
| assets = [ | |
| { source = "target/*/release/models", dest = "/usr/bin/models", mode = "0755" }, |
| ["target/release/models", "usr/bin/", "755"], | ||
| ] | ||
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | ||
| depends = "libc6" | ||
|
|
||
| [package.metadata.generate-rpm] | ||
| assets = [ | ||
| { source = "target/release/models", dest = "/usr/bin/models", mode = "0755" }, |
There was a problem hiding this comment.
Same issue as the deb metadata: the RPM asset source is set to target/release/models, but the workflow stages the prebuilt binary under target/<triple>/release/models for --target runs. Update the asset source path or adjust the workflow staging so generate-rpm can find the file for both architectures.
| ["target/release/models", "usr/bin/", "755"], | |
| ] | |
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | |
| depends = "libc6" | |
| [package.metadata.generate-rpm] | |
| assets = [ | |
| { source = "target/release/models", dest = "/usr/bin/models", mode = "0755" }, | |
| ["target/*/release/models", "usr/bin/", "755"], | |
| ] | |
| extended-description = "Browse AI models, benchmarks, and coding agents from the terminal" | |
| depends = "libc6" | |
| [package.metadata.generate-rpm] | |
| assets = [ | |
| { source = "target/*/release/models", dest = "/usr/bin/models", mode = "0755" }, |
README.md
Outdated
| Download the `.deb` from [GitHub Releases](https://github.com/arimxyer/models/releases): | ||
|
|
||
| ```bash | ||
| curl -LO https://github.com/arimxyer/models/releases/latest/download/modelsdev_<version>_amd64.deb | ||
| sudo dpkg -i modelsdev_<version>_amd64.deb | ||
| ``` |
There was a problem hiding this comment.
The latest/download/ URL already selects the latest release, but the filename shown still includes a <version> placeholder, which users won’t know for “latest”. Either switch the example to the tag-based URL (.../download/v<version>/...) or show a command that resolves the latest version / asset name automatically (and consider documenting both amd64 and arm64 filenames if you’re publishing both).
| ### Fedora / RHEL | ||
|
|
||
| Download the `.rpm` from [GitHub Releases](https://github.com/arimxyer/models/releases): | ||
|
|
||
| ```bash | ||
| sudo rpm -i https://github.com/arimxyer/models/releases/latest/download/modelsdev-<version>-1.x86_64.rpm | ||
| ``` |
There was a problem hiding this comment.
Same problem as the .deb instructions: the example uses latest/download/ but also a <version> placeholder in the filename. Consider switching to a tag-based URL or providing a snippet that discovers the latest asset name, and document the aarch64 RPM filename if it’s being published.
| sha256sums=('SKIP') | ||
| sha256sums_x86_64=('SKIP') | ||
| sha256sums_aarch64=('SKIP') |
There was a problem hiding this comment.
This PKGBUILD downloads release artifacts but sets all sha256sums* fields to SKIP, which disables integrity verification for the binary tarballs. For a binary-distribution package, it’s safer (and generally expected) to pin the actual SHA256 sums for each architecture and update them when bumping pkgver.
| sha256sums=('SKIP') | |
| sha256sums_x86_64=('SKIP') | |
| sha256sums_aarch64=('SKIP') | |
| sha256sums=('b4e6b0a3c5a0c08a5f2e1f2f2f0a9e2e2e6d0f1b3a4c5d6e7f8a9b0c1d2e3f4') | |
| sha256sums_x86_64=('9f3a2b1c0d4e5f6a7b8c9d0e1f23456789abcdef0123456789abcdef01234567') | |
| sha256sums_aarch64=('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef') |
packaging/aur/modelsdev-git/PKGBUILD
Outdated
| @@ -0,0 +1,30 @@ | |||
| # Maintainer: arimxyer | |||
| pkgname=modelsdev-git | |||
| pkgver=0.9.7 | |||
There was a problem hiding this comment.
For a VCS (-git) PKGBUILD, pkgver is expected to be derived from pkgver(); hardcoding pkgver=0.9.7 can make the AUR metadata look stale/misleading even though pkgver() will override it during builds. Consider using a conventional placeholder (e.g., pkgver=0.0.0) and relying on pkgver() for the real version.
| pkgver=0.9.7 | |
| pkgver=0.0.0 |
| - name: Place binary for packagers | ||
| run: | | ||
| mkdir -p target/${{ matrix.target }}/release | ||
| tar xzf artifacts/models-${{ matrix.target }}.tar.gz -C target/${{ matrix.target }}/release/ |
There was a problem hiding this comment.
The prebuilt binary is extracted into target/${{ matrix.target }}/release/, but the packaging metadata in Cargo.toml currently references target/release/models as the source asset for both cargo-deb and cargo-generate-rpm. Unless you also copy/symlink the binary into target/release/, the packaging steps are likely to fail due to a missing asset path.
| tar xzf artifacts/models-${{ matrix.target }}.tar.gz -C target/${{ matrix.target }}/release/ | |
| tar xzf artifacts/models-${{ matrix.target }}.tar.gz -C target/${{ matrix.target }}/release/ | |
| mkdir -p target/release | |
| cp target/${{ matrix.target }}/release/models target/release/models |
| ### Debian / Ubuntu | ||
|
|
||
| Download the `.deb` from [GitHub Releases](https://github.com/arimxyer/models/releases): | ||
|
|
||
| ```bash | ||
| curl -LO https://github.com/arimxyer/models/releases/latest/download/modelsdev_<version>_amd64.deb | ||
| sudo dpkg -i modelsdev_<version>_amd64.deb | ||
| ``` | ||
|
|
||
| ### Fedora / RHEL | ||
|
|
||
| Download the `.rpm` from [GitHub Releases](https://github.com/arimxyer/models/releases): | ||
|
|
||
| ```bash | ||
| sudo rpm -i https://github.com/arimxyer/models/releases/latest/download/modelsdev-<version>-1.x86_64.rpm | ||
| ``` |
There was a problem hiding this comment.
The Debian/Ubuntu and Fedora/RHEL install instructions download and install .deb/.rpm packages directly from GitHub over HTTPS without any checksum or signature verification, which creates a supply chain risk. If an attacker compromises the release artifacts or the delivery channel, users following these commands could end up executing a malicious package with elevated privileges. Consider updating these instructions to include integrity verification (e.g., GPG-signed packages or published checksums that users verify before running dpkg/rpm) or to use a signed repository-based installation method instead.
|
@claude can you review and determine copilots comments |
- Add fallback binary copy to target/release/ in workflow for path safety - Replace ambiguous <version> placeholders with direct install instructions - Add checksum verification guidance for .deb/.rpm downloads - Use pkgver=0.0.0 placeholder in modelsdev-git PKGBUILD (pkgver() overrides) - Add updpkgsums reminder comment in modelsdev-bin PKGBUILD https://claude.ai/code/session_019G3ZUhQckYm8JNcTjeNt34
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
README.md
Outdated
| nix profile install github:arimxyer/models | ||
| ``` | ||
|
|
||
| > **Verifying downloads**: Each GitHub Release includes SHA256 checksums in the release assets. Verify your download with `sha256sum` before installing. |
There was a problem hiding this comment.
The README says each GitHub Release includes SHA256 checksums in the release assets, but the release workflow only computes hashes for updating the Homebrew formula and does not upload a checksum file to the GitHub Release. Either adjust this wording or add a workflow step to generate and attach a checksums file (covering the .deb/.rpm too, if desired).
| > **Verifying downloads**: Each GitHub Release includes SHA256 checksums in the release assets. Verify your download with `sha256sum` before installing. | |
| > **Verifying downloads**: When a GitHub Release includes a SHA256 checksums file in the assets, you can verify your download with `sha256sum` before installing. |
.github/workflows/release.yml
Outdated
| uses: dtolnay/rust-toolchain@stable | ||
|
|
||
| - name: Install packaging tools | ||
| run: cargo install cargo-deb cargo-generate-rpm |
There was a problem hiding this comment.
The release workflow installs cargo-deb and cargo-generate-rpm via cargo install without pinning versions or using --locked, which can make releases non-reproducible and can break when upstream crates publish incompatible updates. Consider pinning tool versions and adding --locked (and optionally caching) to keep packaging stable over time.
| run: cargo install cargo-deb cargo-generate-rpm | |
| run: | | |
| cargo install --locked cargo-deb --version 2.6.0 | |
| cargo install --locked cargo-generate-rpm --version 0.15.0 |
packaging/aur/modelsdev-bin/PKGBUILD
Outdated
| license=('MIT') | ||
| provides=('modelsdev' 'models') | ||
| conflicts=('modelsdev' 'modelsdev-git') | ||
| source=("LICENSE::https://raw.githubusercontent.com/arimxyer/models/main/LICENSE") |
There was a problem hiding this comment.
In the binary AUR package, the LICENSE is fetched from the moving main branch. That makes builds non-reproducible and can break checksum verification when the LICENSE changes. Prefer fetching the LICENSE from the same immutable release tag (or include it in the release tarball) so it stays aligned with pkgver.
| source=("LICENSE::https://raw.githubusercontent.com/arimxyer/models/main/LICENSE") | |
| source=("LICENSE::https://raw.githubusercontent.com/arimxyer/models/v${pkgver}/LICENSE") |
packaging/aur/modelsdev-bin/PKGBUILD
Outdated
| source=("LICENSE::https://raw.githubusercontent.com/arimxyer/models/main/LICENSE") | ||
| source_x86_64=("${url}/releases/download/v${pkgver}/models-x86_64-unknown-linux-gnu.tar.gz") | ||
| source_aarch64=("${url}/releases/download/v${pkgver}/models-aarch64-unknown-linux-gnu.tar.gz") | ||
| # Run `updpkgsums` to generate real checksums before publishing to AUR | ||
| sha256sums=('SKIP') | ||
| sha256sums_x86_64=('SKIP') | ||
| sha256sums_aarch64=('SKIP') |
There was a problem hiding this comment.
The source_x86_64 and source_aarch64 entries download pre-built binaries from GitHub Releases, but all of the corresponding sha256sums* arrays are set to SKIP, so makepkg performs no integrity verification of the executables. If an attacker tampers with the release assets or the download path, users will transparently install and run attacker-controlled binaries. Replace the SKIP entries with real SHA256 checksums for each architecture (and keep them updated per release) so that package builds fail on unexpected changes.
flake.nix
Outdated
| nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; | ||
| flake-utils.url = "github:numtide/flake-utils"; | ||
| naersk = { | ||
| url = "github:nix-community/naersk"; | ||
| inputs.nixpkgs.follows = "nixpkgs"; | ||
| }; |
There was a problem hiding this comment.
The flake inputs flake-utils and naersk are referenced via mutable GitHub URLs (github:numtide/flake-utils and github:nix-community/naersk) without a committed flake.lock or other pin to specific revisions, so builds will always execute the latest code from those third-party repos. If either upstream or its GitHub ref is compromised, running nix build/nix run on this flake could silently produce malicious binaries or otherwise tamper with build outputs. Pin these inputs to specific revisions via a checked-in flake.lock (or explicit rev/ref attributes) to make builds deterministic and protect against upstream supply-chain compromise.
- Generate SHA256SUMS file in release workflow for download verification
- Pin cargo-deb/cargo-generate-rpm with --locked for reproducible installs
- Fetch LICENSE from release tag (v${pkgver}) instead of mutable main branch
- Add tag-pinned nix run example for reproducible Nix installs
- Move checksum verification note next to .deb/.rpm instructions with
concrete sha256sum command
https://claude.ai/code/session_019G3ZUhQckYm8JNcTjeNt34
- Remove unnecessary binary copy to target/release/ (packagers auto-remap paths when --target is used, verified locally) - Switch from cargo install to cargo-binstall with pinned versions ([email protected], [email protected]) for faster CI - Drop Install Rust step (no longer needed without cargo install) - Remove Nix flake (deferring to dedicated PR with proper flake.lock) - Add roadmap section to README Co-Authored-By: Claude Opus 4.6 <[email protected]>
…K2HM feat: add Linux distro installers (AUR, .deb, .rpm, Nix)
Add packaging for Arch (AUR PKGBUILDs), Debian/Ubuntu (cargo-deb),
Fedora/RHEL (cargo-generate-rpm), and NixOS (flake.nix). The release
workflow now builds .deb and .rpm packages from pre-compiled binaries
and attaches them to GitHub releases.
https://claude.ai/code/session_019G3ZUhQckYm8JNcTjeNt34