DEV Community

Cover image for Packaging and Distributing a Rust CLI for All Platforms - A Case Study with Tooka
Benjamin Demetz
Benjamin Demetz

Posted on • Edited on

Packaging and Distributing a Rust CLI for All Platforms - A Case Study with Tooka

Recently, I built a small Rust CLI tool called Tooka, and I wanted to share how I set it up to compile for all major systems — Windows, Linux, macOS — and how I handled packaging and distribution across app stores.

This post covers:

  • GitHub Actions setup
  • Cross-compilation with Rust
  • Packaging with cargo-packager
  • Distributing via Snapcraft, AUR, Winget, Docker, Cloudsmith, etc.
  • Real-world pitfalls (like GLIBC incompatibility)
  • And a full example Dockerfile

Introducing Tooka

Tooka is a tiny CLI that sorts files using YAML-based rules. It doesn’t use a GUI or any external dependencies — a design choice that makes packaging much easier across platforms.

Side note: Naming it Tooka turned out to be... suboptimal. There are way too many projects with similar names. But hey, too late to go back now. 😅

Repo: https://github.com/tooka-org/cli


GitHub Setup

I host Tooka on GitHub with some basic files to kick things off:

  • README.md
  • LICENSE
  • CODE_OF_CONDUCT.md
  • renovate.json — for dependency management via RenovateBot

If you're familiar with Dependabot, Renovate is a great alternative — and free for public repos. Here’s my renovate.json:

{ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended"], "lockFileMaintenance": { "enabled": true, "automerge": true }, "packageRules": [ { "matchUpdateTypes": ["minor", "patch"], "matchCurrentVersion": ">= 1.0.0", "automerge": true }, { "matchDepTypes": ["devDependencies"], "automerge": true } ] } 
Enter fullscreen mode Exit fullscreen mode

This setup ensures Cargo.lock stays clean and synced, and minor updates merge automatically.


Building and Packaging Releases

I use GitHub Actions to build Tooka for all platforms. The release process:

  • Compiles for Windows, macOS (Intel + Apple Silicon), and multiple Linux targets
  • Packages into .deb, .rpm, .dmg, .msi, .exe, and even AppImage
  • Uses cargo-packager for packaging
  • Creates a draft release with all artifacts for review

Here’s the release workflow, powered by a build matrix that handles platform-specific logic.

Bonus: I also use cargo-generate-rpm since RPM isn’t yet supported by cargo-packager.


GLIBC Pitfall on Linux

One real-world problem I hit: GLIBC incompatibilities.

If you compile on a newer distro (like Ubuntu 22.04), and your user runs it on something older (like Debian 10), your app might crash with errors like:

version `GLIBC_2.32' not found 
Enter fullscreen mode Exit fullscreen mode

To discover and debug this, I created a simple Dockerfile:

FROM debian:bookworm-slim RUN apt-get update && apt-get install -y \  curl wget jq ca-certificates && \  apt-get clean && rm -rf /var/lib/apt/lists/* RUN LATEST_URL=$(curl -s https://api.github.com/repos/tooka-org/cli/releases/latest | \  jq -r '.assets[] | select(.name | endswith("_amd64.deb")) | .browser_download_url') && \  wget -O tooka.deb "$LATEST_URL" && \  dpkg -i tooka.deb && \  rm tooka.deb RUN useradd -ms /bin/bash tooka USER tooka WORKDIR /home/tooka/workspace ENTRYPOINT ["/bin/bash"] 
Enter fullscreen mode Exit fullscreen mode

This container mimics a minimal Linux user environment and helped uncover runtime issues early.

💡 Tip: Consider building with musl instead of glibc for max compatibility.


Distributing to App Stores

Distributing CLI tools to users across platforms is... complicated. But it’s doable.

Here’s where I published Tooka:

  • Snap Store
  • Winget (Windows)
  • AppImageHub
  • AUR (tooka-git)
  • Cloudsmith (for APT/RPM repos)

Snapcraft

Setting up Snapcraft is tricky at first — especially if you’re not on Debian/Ubuntu. But once it’s live, you can automate builds via GitHub and maintain it with a snap/ folder.

AUR

I created a -git package that pulls from the latest commit or release. AUR is great for Arch users but requires manual updates for non--git versions.

AppImage

AppImage is surprisingly easy with cargo-packager. Just pass the format and it’ll generate the artifact. Hosting is manual (I uploaded mine to GitHub releases). And you can then also publish it to the AppImage store

Winget

Winget setup requires a Windows box, but once configured, it’s mostly maintenance-free. I also added a GitHub Action to push new versions.

APT/RPM with Cloudsmith

Want sudo apt install tooka? You'll need to host your own APT repo. I used Cloudsmith — it’s free for small projects and super easy to automate.

Here’s my GitHub Action that uploads .deb and .rpm files to Cloudsmith on every release.


Docker Support

Tooka also has a Dockerfile for users who want to run it in a container without installing it locally.

This can also be used for:

  • Sandboxed usage
  • Reproducible testing
  • Musl-based builds

Other Notes


Feedback Wanted

I’m still learning Rust, packaging, and everything in between. Tooka is just a side project, but I hope others can learn from it, fork it, or even improve on it.

If you have ideas, tips, or questions — I’d really love your feedback! Feel free to open issues, submit PRs, or leave a comment here.

Thanks for reading! ❤️

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.