Skip to content
Merged
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
61 changes: 61 additions & 0 deletions .github/workflows/nix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
on:
pull_request:
paths:
- 'nix/**'
- 'go.mod'
- 'go.sum'
- 'vendor/**'
- 'skywire.go'
- 'cmd/**'
- 'pkg/**'
- 'internal/**'
- '.github/workflows/nix.yml'
push:
branches:
- develop
paths:
- 'nix/**'
- 'go.mod'
- 'go.sum'
- 'vendor/**'
- 'skywire.go'
- 'cmd/**'
- 'pkg/**'
- 'internal/**'
- '.github/workflows/nix.yml'

name: Nix

jobs:
build-source:
name: Build skywire (static musl)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true

# Free shared Nix cache; speeds up consecutive runs from cold
# to warm by populating /nix/store from previous runs of this
# workflow (across branches/PRs).
- uses: DeterminateSystems/magic-nix-cache-action@main

# Build the source-only target. skywire-bin is intentionally
# skipped here — it wants per-arch sha256s for upstream
# release tarballs; until those land in nix/flake.nix it
# would always fail. A separate workflow can validate it once
# release-time hashes are populated.
- name: nix build .#skywire
working-directory: nix
run: nix build .#skywire --print-build-logs

- name: smoke-test the binary
working-directory: nix
run: |
./result/bin/skywire --bv
./result/bin/skywire-cli --help >/dev/null
./result/bin/skywire-visor --help >/dev/null
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Table of Contents
- [Linux Packages](#linux-packages)
- [Debian packages](#debian-packages)
- [Arch Linux AUR packages](#arch-linux-aur-packages)
- [NixOS / Nix flake](#nixos--nix-flake)
- [Docker](#docker)
- [How to create a GitHub release](#how-to-create-a-github-release)
- [Dependency Graph](#dependency-graph)
Expand Down Expand Up @@ -1064,6 +1065,32 @@ Build the skywire Arch Linux package from git sources to the latest commits on t
yay --mflags " -p git.PKGBUILD " -S skywire
```

### NixOS / Nix flake

Two derivations under [`nix/`](/nix/) — same flavors as the AUR
packages: `skywire` (source build, static-musl, mirrors
`make build-static`) and `skywire-bin` (the upstream release
tarball).

From a checkout:
```
cd nix
nix build .#skywire # source, static musl
nix build .#skywire-bin # prebuilt tarball
nix run .#skywire -- --bv
```

Or as a flake input from elsewhere:
```nix
inputs.skywire.url = "github:skycoin/skywire?dir=nix";
# ...
environment.systemPackages = [ skywire.packages.${system}.skywire ];
```

See [`nix/README.md`](/nix/README.md) for the per-arch hash-fill
flow on `skywire-bin`, the visor's `--apps-dir` integration, and
the static-binary sanity check.

## Docker

For docker-specific documentation, see: [DOCKER.md](/DOCKER.md)
Expand Down
100 changes: 100 additions & 0 deletions nix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Skywire — Nix packaging

Two derivations, mirroring the AUR `skywire` and `skywire-bin`
packages:

- **`skywire.nix`** — source build. Uses `pkgsStatic.buildGoModule`
(musl-based stdenv), with the same `-linkmode external -extldflags
"-static" -buildid=` ldflags as the upstream `make build-static`
recipe. Produces a fully-static binary identical in shape to the
release tarballs.

- **`skywire-bin.nix`** — install the prebuilt release tarball from
GitHub releases. Faster build, trusts the upstream binary.

Both produce the same layout:

$out/bin/skywire # merged binary
$out/bin/skywire-cli # shim → skywire cli
$out/bin/skywire-visor # shim → skywire visor
$out/share/skywire/apps/ # shims for skychat, skysocks, vpn-*, etc.

## Quick start

From a checkout of this repo:

cd nix
nix build .#skywire # source build (static musl)
nix build .#skywire-bin # download prebuilt
nix run .#skywire -- --bv

Or as a flake input from somewhere else:

{
inputs.skywire.url = "github:0pcom/skywire/nix/packaging";
# …
outputs = { self, nixpkgs, skywire, ... }: {
# nixosConfigurations / systemPackages / etc.
environment.systemPackages = [
skywire.packages.${system}.skywire
];
};
}

## First-time hashes

`skywire-bin.nix` ships with `lib.fakeHash` placeholders for every
arch's release tarball. The first `nix build .#skywire-bin` will
fail and print the expected hash for the arch you're on; copy it
into the `hashes` attrset in `flake.nix` and rebuild. Repeat for
each arch you want to support.

`skywire.nix` defaults to building from the **local working tree**
(handy for iterating on a branch). To build a tagged release from
upstream instead, override `rev` and `version` when calling it from
the flake (the parameter for an explicit src tree is `srcOverride`,
to dodge a `pkgs.src` callPackage auto-bind collision in nixpkgs):

pkgs.callPackage ./skywire.nix {
rev = "v1.3.50";
version = "1.3.50";
}

The first such build will fail with the expected `hash` for
`fetchFromGitHub`; copy it into the `hash = lib.fakeHash` line in
`skywire.nix`.

## Visor app discovery

The visor launches `skychat`, `skysocks`, `vpn-server`, etc. as
separate processes. Both packages install dispatcher shims under
`$out/share/skywire/apps/`. Point the visor at that directory:

skywire visor --apps-dir ${skywire}/share/skywire/apps …

or, in a config file, set `launcher.bin_path` to the same path.

## NixOS module — TODO

A `nixosModules.skywire` exposing `services.skywire.enable`,
service-tree toggles (sn / sd / tpd / dmsg / ar / rf), and the
autoconfig wiring is the natural follow-up. Not in this initial
drop. Once it lands, you'll be able to:

services.skywire = {
enable = true;
package = pkgs.skywire; # or skywire-bin
services.tpd.enable = true;
# …
};

## Validating the build

To sanity-check the source build is actually static:

nix build .#skywire
file ./result/bin/skywire
# → ELF 64-bit LSB executable, x86-64, statically linked, …

If `file` reports `dynamically linked`, the build's `postInstall`
guard already would have failed.
98 changes: 98 additions & 0 deletions nix/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
description = "Skywire packaged for Nix — source build (static musl) and prebuilt-binary variants";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
# Skywire ships without an explicit LICENSE file (the AUR
# PKGBUILD tags it "license-free"), so Nix's policy treats
# it as unfree by default and refuses to build it without an
# opt-in. Whitelist exactly skywire + skywire-bin here so
# `nix build` works on a stock Nix installation without
# exporting NIXPKGS_ALLOW_UNFREE=1 / --impure.
pkgs = import nixpkgs {
inherit system;
config.allowUnfreePredicate = pkg:
builtins.elem (nixpkgs.lib.getName pkg) [
"skywire"
"skywire-bin"
];
};

# Pin the version once for both packages. Bump this when
# cutting a new release — the source build picks the matching
# git tag (or the working tree, the default), and the
# binary build expects upstream tarballs at v${version}.
version = "1.3.50";

skywire = pkgs.callPackage ./skywire.nix {
inherit version;
# Default: build from the local working tree (../..). To
# build a tagged release from upstream instead, override:
#
# nix build .#skywire \
# --override-input src \
# 'github:skycoin/skywire/v1.3.50'
};

skywire-bin = pkgs.callPackage ./skywire-bin.nix {
inherit version;
# Fill in real hashes here once the release is cut. First
# `nix build .#skywire-bin` will print the expected hash
# for whichever arch you're on; copy it in.
#
# hashes = {
# "linux-amd64" = "sha256-...";
# "linux-arm64" = "sha256-...";
# "linux-386" = "sha256-...";
# "linux-armhf" = "sha256-...";
# "linux-arm" = "sha256-...";
# "linux-riscv64" = "sha256-...";
# };
};
in {
packages = {
inherit skywire skywire-bin;
default = skywire;
};

# `nix run .#skywire-cli ...` etc. without typing the bin path.
apps = {
skywire = {
type = "app";
program = "${skywire}/bin/skywire";
};
skywire-cli = {
type = "app";
program = "${skywire}/bin/skywire-cli";
};
skywire-visor = {
type = "app";
program = "${skywire}/bin/skywire-visor";
};
skywire-bin = {
type = "app";
program = "${skywire-bin}/bin/skywire";
};
default = self.apps.${system}.skywire;
};

# `nix develop` drops you into a shell with the toolchain
# the source build needs (Go, musl, the standard CLI deps),
# mirroring `make build-static` requirements.
devShells.default = pkgs.mkShell {
packages = with pkgs; [
go
musl
pkg-config
gnumake
git
];
};
});
}
Loading
Loading