packages.default builds natively and runs the suite: 357 tests pass in the sandbox, including the 60 socket integration tests, which settles the open question of whether they can bind in a Nix build. The sandbox's private network namespace has loopback up and the tests take port 0, so there is nothing to collide with. packages.static is the published artifact, fully static against musl, so a consumer needs neither autoPatchelfHook nor a matching glibc. There is no C dependency anywhere in the tree, not even a TLS library, so unlike bunshin's sqlite there is nothing to cross-provide. 2.3 MB stripped. nixpkgs is pinned to unstable and deliberately not followed from a consumer: every crate here declares rust-version 1.97 and nixos-25.11 ships 1.91.1, so bucur's nixpkgs could not build this. It does not need to, since it fetches the release asset. wml is built in. It is opt-in upstream, and the bundled itsybitsy.toml names it, so a default build refuses to boot the config shipped beside it. apps.release-static publishes to Forgejo tagged by short rev, following bunshin's. Note the asymmetry that bit bunshin: assets upload to /releases/<id>/assets but download from /releases/download/<tag>/<name>. THIRD_PARTY_NOTICES.md covers the static link closure, 73 crates across five license families, plus the two vendored FIGlet fonts, which carry their terms in the FIGfont comment header and which no crate scan can see. They are behind the non-default figlet feature and so are not in this binary, but they are redistributed with the source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
120 lines
5.2 KiB
Nix
120 lines
5.2 KiB
Nix
{
|
|
description = "itsybitsy - serve folders of Markdown over HTTP, Gemini, Spartan, Nex and Gopher";
|
|
|
|
inputs = {
|
|
# Pinned independently of any consumer, and deliberately not `follows`-ed.
|
|
# Every crate here declares rust-version = "1.97"; nixos-25.11 ships 1.91.1,
|
|
# so a consumer's nixpkgs cannot build this. Nothing needs to: bucur fetches
|
|
# the release asset that `apps.release-static` publishes.
|
|
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
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
|
|
common = {
|
|
pname = "itsybitsy";
|
|
version = "0.1.0";
|
|
src = ./.;
|
|
cargoLock.lockFile = ./Cargo.lock;
|
|
|
|
# The workspace root is virtual, and cargo refuses `--features` there
|
|
# without a package selector, so name the binary crate outright.
|
|
cargoBuildFlags = [ "--package" "itsybitsy" ];
|
|
|
|
# WML is opt-in upstream and the bundled itsybitsy.toml lists it, so a
|
|
# default build refuses to boot that config at all. The deployment
|
|
# wants it too: WAP handsets are the only client that asks for it, and
|
|
# they are exactly the audience a WML face exists for.
|
|
buildFeatures = [ "wml" ];
|
|
|
|
meta = {
|
|
description = "Serve folders of Markdown to several domains";
|
|
license = pkgs.lib.licenses.asl20;
|
|
mainProgram = "itsybitsy";
|
|
};
|
|
};
|
|
in
|
|
{
|
|
# Native build, and where the test suite runs. The integration tests
|
|
# bind 127.0.0.1 on port 0, which the Nix sandbox allows: it has its own
|
|
# network namespace with loopback up, so there is nothing to collide
|
|
# with and no fixed port to claim.
|
|
packages.default = pkgs.rustPlatform.buildRustPackage (
|
|
common // { cargoTestFlags = [ "--workspace" ]; }
|
|
);
|
|
|
|
# The published artifact. Fully static against musl, so the consumer
|
|
# needs neither autoPatchelfHook nor a matching glibc: there is no C
|
|
# dependency anywhere in the tree, not even a TLS library, so unlike
|
|
# bunshin's sqlite there is nothing to cross-provide.
|
|
packages.static = pkgs.pkgsStatic.rustPlatform.buildRustPackage (
|
|
common // { doCheck = false; }
|
|
);
|
|
|
|
apps.default = flake-utils.lib.mkApp {
|
|
drv = self.packages.${system}.default;
|
|
name = "itsybitsy";
|
|
};
|
|
|
|
# Builds packages.static and publishes it as a Forgejo release tagged by
|
|
# short commit hash, creating the release if absent and replacing the
|
|
# asset if present. Needs FORGEJO_TOKEN (write:repository) in the
|
|
# environment or in .env. Same shape as bunshin's.
|
|
#
|
|
# Note the asymmetry that bit bunshin: assets are *uploaded* to
|
|
# /releases/<id>/assets but *downloaded* from /releases/download/<tag>/
|
|
# <name>. The generic package-registry path 404s; the consumer must use
|
|
# the download form.
|
|
apps.release-static = flake-utils.lib.mkApp {
|
|
drv = pkgs.writeShellApplication {
|
|
name = "itsybitsy-release-static";
|
|
runtimeInputs = [ pkgs.nix pkgs.curl pkgs.git pkgs.jq ];
|
|
text = ''
|
|
if [ -f .env ]; then
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
. ./.env
|
|
set +a
|
|
fi
|
|
: "''${FORGEJO_TOKEN:?set FORGEJO_TOKEN (env or .env) to a Forgejo token with write:repository scope}"
|
|
|
|
rev=$(git rev-parse --short HEAD)
|
|
sha=$(git rev-parse HEAD)
|
|
out=$(nix build .#static --no-link --print-out-paths)
|
|
bin="$out/bin/itsybitsy"
|
|
|
|
api="https://code.randogoth.com/api/v1/repos/randogoth/itsybitsy"
|
|
auth=(-H "Authorization: token ''${FORGEJO_TOKEN}")
|
|
|
|
release_id=$(curl -sS "''${auth[@]}" "$api/releases/tags/$rev" | jq -r '.id // empty')
|
|
if [ -z "$release_id" ]; then
|
|
release_id=$(curl -sSf "''${auth[@]}" -H "Content-Type: application/json" \
|
|
-d "$(jq -n --arg tag "$rev" --arg sha "$sha" \
|
|
'{tag_name:$tag, target_commitish:$sha, name:$tag, body:"Static musl build.", draft:false, prerelease:false}')" \
|
|
"$api/releases" | jq -r '.id')
|
|
fi
|
|
|
|
asset_id=$(curl -sSf "''${auth[@]}" "$api/releases/$release_id/assets" | jq -r '.[] | select(.name=="itsybitsy") | .id' | head -1)
|
|
if [ -n "$asset_id" ]; then
|
|
curl -sSf -X DELETE "''${auth[@]}" "$api/releases/$release_id/assets/$asset_id" >/dev/null
|
|
fi
|
|
curl -sSf "''${auth[@]}" -F "attachment=@$bin;filename=itsybitsy" "$api/releases/$release_id/assets?name=itsybitsy" >/dev/null
|
|
|
|
echo "released: https://code.randogoth.com/randogoth/itsybitsy/releases/tag/$rev"
|
|
echo "fetch at: https://code.randogoth.com/randogoth/itsybitsy/releases/download/$rev/itsybitsy"
|
|
'';
|
|
};
|
|
};
|
|
|
|
devShells.default = pkgs.mkShell {
|
|
packages = with pkgs; [ cargo rustc rustfmt clippy ];
|
|
};
|
|
}
|
|
);
|
|
}
|