Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/update-flake-hash.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Update Flake Hash on Release
name: Update Nix Package Hash on Release

on:
release:
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
URL="https://github.com/TibixDev/winboat/releases/download/v${VERSION}/winboat-${VERSION}-x64.tar.gz"

echo "Prefetching from: $URL"
HASH=$(nix-prefetch-url "$URL")
HASH=$(nix hash convert --hash-algo sha256 --to sri $(nix-prefetch-url "$URL"))

echo "Calculated SHA256: $HASH"
echo "nix_sha256=${HASH}" >> $GITHUB_OUTPUT
Expand All @@ -61,9 +61,9 @@ jobs:
git fetch origin main
git merge --no-edit -X theirs origin/main

sed -i "s/sha256 = \".*\";/sha256 = \"${ESC_HASH}\";/" flake.nix
sed -i "s/sha256 = \".*\";/sha256 = \"${ESC_HASH}\";/" nix/package.nix
sed -i "s/version = \".*\";/version = \"${VERSION}\";/" nix/package.nix


git add flake.nix || true
git commit -m "chore: update flake.nix for version ${VERSION}" || echo "No changes to commit"
git push origin HEAD:main || echo "Push failed"
git add nix/package.nix || echo "No change in package hash"
git commit -m "chore: update package.nix for version ${VERSION}" || echo "No changes to commit"
git push origin HEAD:main || echo "Push failed"
108 changes: 19 additions & 89 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,25 @@

inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

outputs = { self, nixpkgs }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
packageJson = builtins.fromJSON (builtins.readFile ./package.json);
version = packageJson.version;

usb_ids = builtins.toFile "usb.ids" (builtins.readFile ./data/usb.ids);
iconFile = ./icons/icon.png;
winboatPkg = pkgs.stdenv.mkDerivation {
pname = "winboat";
version = version;

src = pkgs.fetchurl {
url = "https://github.com/TibixDev/winboat/releases/download/v${version}/winboat-${version}-x64.tar.gz";
sha256 = "0wnbdnm1w59xyhw55bqac0jak16nvcs91qixnxyrnq2b46gpvmg0";
};

nativeBuildInputs = [
pkgs.makeWrapper
pkgs.freerdp3
pkgs.usbutils
pkgs.libusb1
];
buildInputs = [ pkgs.electron pkgs.gcc pkgs.glibc pkgs.stdenv.cc.cc.lib ];

installPhase = ''
mkdir -p $out/bin $out/share/winboat
(cd . && tar cf - .) | (cd $out/share/winboat && tar xf -)
cat > $out/bin/winboat <<EOF
#!/bin/sh
export LD_LIBRARY_PATH=${pkgs.gcc}/lib:${pkgs.glibc}/lib:${pkgs.electron}/lib:${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH
exec ${pkgs.electron}/bin/electron $out/share/winboat/resources/app.asar "$@"
EOF
chmod +x $out/bin/winboat

mkdir -p $out/share/icons/hicolor/256x256/apps
mkdir -p $out/share/winboat

cp ${iconFile} $out/share/icons/hicolor/256x256/apps/winboat.png
cp ${iconFile} $out/share/winboat/icon.png

# desktop entry
mkdir -p $out/share/applications
cat > $out/share/applications/winboat.desktop <<EOF
[Desktop Entry]
Name=WinBoat
Exec=$out/bin/winboat %U
Type=Application
Terminal=false
Icon=winboat
Categories=Utility;
EOF

mkdir -p $out/share/winboat/data
mkdir -p $out/share/winboat/resources/data

cp ${usb_ids} $out/share/winboat/data/usb.ids
cp ${usb_ids} $out/share/winboat/resources/data/usb.ids

mkdir -p $out/lib/guest_server

if [ -d guest_server ]; then
cp -a guest_server/. $out/share/winboat/resources/guest_server/
cp -a guest_server/. $out/share/winboat/guest_server/
cp -a guest_server/. $out/lib/guest_server/
elif [ -d resources/guest_server ]; then
cp -a resources/guest_server/. $out/share/winboat/resources/guest_server/
cp -a resources/guest_server/. $out/share/winboat/guest_server/
cp -a resources/guest_server/. $out/lib/guest_server/
else
ls -la
exit 1
fi
'';


meta = with pkgs.lib; { description = "WinBoat"; license = licenses.mit; platforms = [ "x86_64-linux" ]; };
};

in {
packages.x86_64-linux.winboat = winboatPkg;

winboat = winboatPkg;

defaultPackage.x86_64-linux = winboatPkg;
outputs = {
self,
nixpkgs,
}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
self' = self.packages.${system};
in {
packages.${system} = {
winboat = pkgs.callPackage ./nix/package.nix {};
default = self'.winboat;
};

apps.x86_64-linux.winboat = {
type = "app";
program = "${winboatPkg}/bin/winboat";
nixosModules = {
winboat = {
imports = [./nix/module.nix];
services.winboat.package = self'.default;
};
default = self.nixosModules.winboat;
};
}
};
}
30 changes: 30 additions & 0 deletions nix/module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) mkIf mkEnableOption mkOption;
inherit (lib.types) package;

cfg = config.services.winboat;
in {
options.services.winboat = {
enable = mkEnableOption "WinBoat - Windows apps on Linux";
package = mkOption {
type = package;
description = "WinBoat package to use";
};
};

config = mkIf cfg.enable {
virtualisation.docker.enable = true;
virtualisation.libvirtd.enable = true;

environment.systemPackages = [
cfg.package
pkgs.freerdp3
pkgs.docker-compose
];
};
}
89 changes: 89 additions & 0 deletions nix/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
stdenv,
lib,
fetchurl,
makeWrapper,
electron,
autoPatchelfHook,
wrapGAppsHook3,
makeDesktopItem,
usbutils,
copyDesktopItems,
asar,
libusb1,
}:
stdenv.mkDerivation (final: {
pname = "winboat";
version = "0.8.7";

src = fetchurl {
url = "https://github.com/TibixDev/winboat/releases/download/v${final.version}/winboat-${final.version}-x64.tar.gz";
sha256 = "sha256-4NV9nyFLYJt9tz3ikDTb1oSpJGAKr1I49D0VHqpty3I=";
};

desktopItems = [
(makeDesktopItem {
name = "winboat";
desktopName = "WinBoat";
type = "Application";
exec = "winboat %U";
terminal = false;
icon = "winboat";
categories = ["Utility"];
})
];

nativeBuildInputs = [
makeWrapper
wrapGAppsHook3
copyDesktopItems
autoPatchelfHook
asar
];

buildInputs = [libusb1 usbutils];

dontBuild = true;
dontWrapGApps = true;
autoPatchelfIgnoreMissingDeps = ["libc.musl-x86_64.so.1"];

installPhase = ''
runHook preInstall

mkdir -p $out/bin $out/share/winboat
cp -r ./* $out/share/winboat
rm $out/share/winboat/{*.so*,winboat,chrome_crashpad_handler,chrome-sandbox}

mkdir -p $out/share/icons/hicolor/256x256/apps
cp ${../icons/icon.png} $out/share/icons/hicolor/256x256/apps/winboat.png

mkdir -p $out/share/winboat/data
cp resources/data/usb.ids $out/share/winboat/data/usb.ids

mkdir -p $out/lib
cp -r resources/guest_server $out/lib/guest_server
cp -r resources/guest_server $out/share/winboat/guest_server

# Rebuild the ASAR archive to patchelf native module.
tmp=$(mktemp -d)
asar extract $out/share/winboat/resources/app.asar $tmp
rm $out/share/winboat/resources/app.asar
autoPatchelf $tmp
asar pack $tmp/ $out/share/winboat/resources/app.asar
rm -rf $tmp

makeWrapper ${electron}/bin/electron $out/bin/winboat \
--add-flag "$out/share/winboat/resources/app.asar" \
--suffix PATH : "${usbutils}/bin" \
''${gappsWrapperArgs[@]}

runHook postInstall
'';

meta = {
mainProgram = "winboat";
description = "Run Windows apps on Linux with seamless integration";
license = lib.licenses.mit;
platforms = ["x86_64-linux"];
};
})