feat: overhaul Nix flake with full Linux support and convenience commands

- Remove rust-overlay dependency, use nixpkgs built-in Rust
- Add comprehensive Linux library dependencies for Chromium browsers
- Set up proper LD_LIBRARY_PATH/NIX_LD for NixOS dynamic linking
- Add nix run apps: setup, dev, tauri-dev, full-dev, build, test, info
- Add AppImage release launcher for NixOS users (v0.17.6)
- Add flake-test CI workflow
- Update release version and hashes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Hp
2026-03-24 02:09:28 +04:00
committed by zhom
co-authored by Claude Opus 4.6
parent aa2e9e2528
commit cae758f0ab
3 changed files with 362 additions and 59 deletions
+49
View File
@@ -0,0 +1,49 @@
name: Flake Test
on:
pull_request:
paths:
- "flake.nix"
- "flake.lock"
- ".github/workflows/flake-test.yml"
push:
branches:
- main
paths:
- "flake.nix"
- "flake.lock"
- ".github/workflows/flake-test.yml"
workflow_dispatch:
permissions:
contents: read
jobs:
flake:
name: validate-flake
runs-on: ubuntu-22.04
timeout-minutes: 90
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: Evaluate flake outputs
run: nix flake show --all-systems
- name: Check setup app is exposed
run: nix eval .#apps.x86_64-linux.setup.program --raw
- name: Run flake setup app
env:
CI: "true"
run: nix run .#setup
- name: Run flake info app
run: nix run .#info
Generated
+1 -22
View File
@@ -37,28 +37,7 @@
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs"
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1767926800,
"narHash": "sha256-x0n73J6ufD/EhDlVdcoAmF0OQHZ+b0a2cKDc8RZyt+o=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "499e9eed88ff9494b6604205b42847e847dfeb91",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
} }
}, },
"systems": { "systems": {
+311 -36
View File
@@ -1,66 +1,341 @@
{ {
description = "Donut Browser Development Environment"; description = "Donut Browser development environment and quick-start commands";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, nixpkgs, flake-utils, rust-overlay, ... }: outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system: flake-utils.lib.eachDefaultSystem (system:
let let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system overlays; inherit system;
config.allowUnfree = true;
}; };
lib = pkgs.lib;
# Rust toolchain nodejs =
rustToolchain = pkgs.rust-bin.stable.latest.default.override { if pkgs ? nodejs_23 then
extensions = [ "rust-src" "rust-analyzer" "clippy" "rustfmt" ]; pkgs.nodejs_23
}; else
pkgs.nodejs_22;
# System dependencies for Tauri on Linux rustPackages = with pkgs; [
libraries = with pkgs; [ cargo
clippy
rust-analyzer
rustc
rustfmt
];
commonLibs = with pkgs; [
webkitgtk_4_1 webkitgtk_4_1
libsoup_3
glib
gtk3 gtk3
cairo cairo
gdk-pixbuf gdk-pixbuf
glib pango
atk
at-spi2-atk
at-spi2-core
dbus dbus
librsvg nss
libsoup_3 nspr
libdrm
libgbm
libxkbcommon
libx11
libxcomposite
libxdamage
libxext
libxfixes
libxrandr
libxcb
libxshmfence
libxtst
libxi
xdotool
libxrender
libxinerama
libxcursor
libxscrnsaver
fontconfig
freetype
fribidi
harfbuzz
expat
libglvnd
libgpg-error
e2fsprogs
gmp
zlib
stdenv.cc.cc.lib
]; ];
packages = with pkgs; [ runtimeLibPath = lib.makeLibraryPath commonLibs;
rustToolchain nixLd = pkgs.stdenv.cc.bintools.dynamicLinker;
nodejs_22 pkgConfigLibs = [
pnpm pkgs.at-spi2-atk
pkg-config pkgs.at-spi2-core
cargo-tauri pkgs.cairo
openssl pkgs.dbus
# App specific tools pkgs.gdk-pixbuf
biome pkgs.glib
] ++ libraries; pkgs.gtk3
pkgs.libsoup_3
pkgs.libxkbcommon
pkgs.openssl
pkgs.pango
pkgs.harfbuzz
pkgs.webkitgtk_4_1
];
pkgConfigPath = lib.makeSearchPath "lib/pkgconfig" (
pkgConfigLibs ++ map lib.getDev pkgConfigLibs
);
releaseVersion = "0.17.6";
releaseAppImage =
if system == "x86_64-linux" then
pkgs.fetchurl {
url = "https://github.com/zhom/donutbrowser/releases/download/v${releaseVersion}/Donut_0.17.6_amd64.AppImage";
hash = "sha256-Bmqmb0zgaC02DKC9gcyI/St9wfwFWTEoYybOb1LXiS0=";
}
else if system == "aarch64-linux" then
pkgs.fetchurl {
url = "https://github.com/zhom/donutbrowser/releases/download/v${releaseVersion}/Donut_0.17.6_aarch64.AppImage";
hash = "sha256-FOV0PlYw59gY1QSoFrUcixtUcnFt27EYAzZE/KNQUrM=";
}
else
null;
releaseUnpacked =
if releaseAppImage != null then
pkgs.stdenvNoCC.mkDerivation {
pname = "donut-release-unpacked";
version = releaseVersion;
src = releaseAppImage;
dontUnpack = true;
nativeBuildInputs = [ pkgs.xz ];
installPhase = ''
runHook preInstall
cp "$src" ./donut.AppImage
chmod +x ./donut.AppImage
./donut.AppImage --appimage-extract >/dev/null
mkdir -p "$out"
cp -a ./squashfs-root "$out/"
runHook postInstall
'';
}
else
null;
releaseWrapped =
if releaseAppImage != null then
pkgs.appimageTools.wrapType2 {
pname = "donut";
version = releaseVersion;
src = releaseAppImage;
extraPkgs = _: commonLibs;
extraInstallCommands = ''
for bin in "$out"/bin/*; do
if [ -f "$bin" ]; then
mv "$bin" "$out/bin/donut-release"
break
fi
done
'';
}
else
null;
releaseLauncher =
if releaseUnpacked != null then
pkgs.writeShellApplication {
name = "donut-release-start";
runtimeInputs = with pkgs; [
coreutils
xdg-utils
];
text = ''
set -euo pipefail
if [ -x "${releaseWrapped}/bin/donut-release" ]; then
if "${releaseWrapped}/bin/donut-release" "$@"; then
exit 0
fi
echo "Wrapped AppImage failed, retrying with direct AppRun..." >&2
fi
export LD_LIBRARY_PATH="${releaseUnpacked}/squashfs-root/usr/lib:${releaseUnpacked}/squashfs-root/usr/lib64:${runtimeLibPath}:''${LD_LIBRARY_PATH:-}"
export NIX_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
export LIBRARY_PATH="$LD_LIBRARY_PATH"
export XDG_DATA_DIRS="${releaseUnpacked}/squashfs-root/usr/share:''${XDG_DATA_DIRS:-}"
exec "${releaseUnpacked}/squashfs-root/AppRun" "$@"
'';
}
else
pkgs.writeShellApplication {
name = "donut-release-start";
text = ''
echo "Release launcher is supported only on Linux (x86_64/aarch64)."
exit 1
'';
};
mkApp = name: text:
let
app = pkgs.writeShellApplication {
inherit name;
runtimeInputs = with pkgs; [
bash
coreutils
findutils
git
gnugrep
gnused
curl
gcc
pkg-config
openssl
cargo
clippy
rustc
rustfmt
nodejs
pnpm
cargo-tauri
];
text = ''
export NODE_ENV=development
export NIX_LD="${nixLd}"
export NIX_LD_LIBRARY_PATH="${runtimeLibPath}:''${NIX_LD_LIBRARY_PATH:-}"
export LD_LIBRARY_PATH="${runtimeLibPath}:''${LD_LIBRARY_PATH:-}"
export LIBRARY_PATH="${runtimeLibPath}:''${LIBRARY_PATH:-}"
export PKG_CONFIG_PATH="${pkgConfigPath}:''${PKG_CONFIG_PATH:-}"
export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}"
${text}
'';
};
in
{
type = "app";
program = "${app}/bin/${name}";
};
in in
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = packages; packages = with pkgs; [
nodejs
pnpm
cargo-tauri
pkg-config
openssl
git
bashInteractive
gnumake
clang
llvmPackages.bintools
python3
curl
wget
unzip
zip
xz
biome
docker
] ++ rustPackages ++ commonLibs;
shellHook = '' shellHook = ''
export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath libraries}:$LD_LIBRARY_PATH export NODE_ENV=development
export XDG_DATA_DIRS=${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS export NIX_LD="${nixLd}"
export NIX_LD_LIBRARY_PATH="${runtimeLibPath}:''${NIX_LD_LIBRARY_PATH:-}"
export LD_LIBRARY_PATH="${runtimeLibPath}:''${LD_LIBRARY_PATH:-}"
export LIBRARY_PATH="${runtimeLibPath}:''${LIBRARY_PATH:-}"
export PKG_CONFIG_PATH="${pkgConfigPath}:''${PKG_CONFIG_PATH:-}"
export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}"
export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share:${pkgs.gtk3}/share:''${XDG_DATA_DIRS:-}"
echo "🍩 Donut Browser Dev Environment Loaded!" echo "Donut Browser dev shell ready."
echo "Node: $(node --version)" echo "Quick start:"
echo "Rust: $(rustc --version)" echo " nix run .#setup"
echo "Tauri CLI: $(cargo-tauri --version)" echo " nix run .#tauri-dev"
echo " nix run .#full-dev"
echo " nix run .#build"
echo " nix run .#test"
echo " nix run .#release-start"
''; '';
}; };
}
); apps.info = mkApp "donut-info" ''
set -euo pipefail
echo "Node: $(node --version)"
echo "pnpm: $(pnpm --version)"
echo "Rust: $(rustc --version)"
echo "Cargo: $(cargo --version)"
echo "Tauri CLI: $(cargo-tauri --version)"
'';
apps.deps = mkApp "donut-deps" ''
set -euo pipefail
pnpm install
'';
apps.dev = mkApp "donut-dev" ''
set -euo pipefail
pnpm dev
'';
apps."tauri-dev" = mkApp "donut-tauri-dev" ''
set -euo pipefail
pnpm tauri dev
'';
apps."full-dev" = mkApp "donut-full-dev" ''
set -euo pipefail
chmod +x ./scripts/dev.sh
./scripts/dev.sh
'';
apps.build = mkApp "donut-build" ''
set -euo pipefail
pnpm build
(cd src-tauri && cargo build)
'';
apps.start = mkApp "donut-start" ''
set -euo pipefail
pnpm start
'';
apps.test = mkApp "donut-test" ''
set -euo pipefail
pnpm format && pnpm lint && pnpm test
'';
apps.setup = mkApp "donut-setup" ''
set -euo pipefail
if [ ! -f "package.json" ]; then
echo "package.json not found. Run this from the donutbrowser repo root."
exit 1
fi
pnpm install
pnpm copy-proxy-binary
echo "Setup complete."
echo "Run the app with:"
echo " nix run .#tauri-dev"
echo "Or run full local stack (sync + minio + tauri):"
echo " nix run .#full-dev"
'';
apps."release-start" = {
type = "app";
program = "${releaseLauncher}/bin/donut-release-start";
};
apps.default = self.apps.${system}.setup;
});
} }