121 lines
5.2 KiB
Nix
121 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 ];
|
||
|
|
};
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|