Some checks failed
CI pipeline for ffd-indexer / checks (go test + golangci) (push) Failing after 26s
CI pipeline for ffd-indexer / build binaries + containers (push) Failing after 3s
CI pipeline for ffd-indexer / format (gofmt + nixfmt) (push) Failing after 3s
CI pipeline for ffd-indexer / integration (live scrape + Typesense) (push) Failing after 20s
221 lines
8.1 KiB
Nix
221 lines
8.1 KiB
Nix
{
|
|
description = "Federated Forge Discovery Indexer";
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
gomod2nix = {
|
|
url = "github:tweag/gomod2nix";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
inputs.flake-utils.follows = "flake-utils";
|
|
};
|
|
};
|
|
outputs =
|
|
{
|
|
self,
|
|
nixpkgs,
|
|
flake-utils,
|
|
gomod2nix,
|
|
}:
|
|
flake-utils.lib.eachDefaultSystem (
|
|
system:
|
|
let
|
|
pkgs = import nixpkgs {
|
|
inherit system;
|
|
overlays = [ gomod2nix.overlays.default ];
|
|
};
|
|
go = pkgs.go_1_27;
|
|
version = "0.0.1";
|
|
# Git commit (full + short) used for container labels. Inside a real
|
|
# flake build (including CI's shallow clone) `self.rev` is populated;
|
|
# on a dirty working tree it is null and we fall back to empty so the
|
|
# label is simply omitted.
|
|
rev = self.rev or "";
|
|
shortRev =
|
|
if rev != "" then
|
|
builtins.substring 0 7 rev
|
|
else
|
|
(self.dirtyShortRev or "");
|
|
# Inject version + commit into the binaries via the Go linker, and
|
|
# reuse the same values for the OCI image labels.
|
|
goLdflags = [
|
|
"-X git.xengi.de/ffd/indexer/internal/version.Version=${version}"
|
|
"-X git.xengi.de/ffd/indexer/internal/version.Commit=${shortRev}"
|
|
];
|
|
ffd-indexer = pkgs.buildGoApplication {
|
|
inherit go;
|
|
pname = "ffd-indexer";
|
|
inherit version;
|
|
ldflags = goLdflags;
|
|
src = ./.;
|
|
modules = ./gomod2nix.toml;
|
|
# buildGoApplication runs `go install ./...`, which names each binary
|
|
# after the last element of its package path:
|
|
# git.xengi.de/ffd/indexer -> "indexer"
|
|
# git.xengi.de/ffd/indexer/cmd/ffd-metrics -> "ffd-metrics"
|
|
# Rename "indexer" to the service/container name "ffd-indexer".
|
|
postInstall = ''
|
|
mv "$out/bin/indexer" "$out/bin/ffd-indexer"
|
|
'';
|
|
};
|
|
|
|
# Long-running Prometheus metrics daemon. It is a separate binary but is
|
|
# built in the same derivation; keep it as its own output alias for the
|
|
# NixOS module and containers.
|
|
ffd-metrics = pkgs.runCommand "ffd-metrics" { } ''
|
|
mkdir -p "$out/bin"
|
|
ln -s "${ffd-indexer}/bin/ffd-metrics" "$out/bin/ffd-metrics"
|
|
'';
|
|
go-test = pkgs.stdenv.mkDerivation {
|
|
name = "go-test";
|
|
dontBuild = true;
|
|
src = ./.;
|
|
doCheck = true;
|
|
nativeBuildInputs = [
|
|
go
|
|
pkgs.writableTmpDirAsHomeHook
|
|
];
|
|
checkPhase = ''
|
|
go test -v ./...
|
|
'';
|
|
installPhase = ''
|
|
mkdir "$out"
|
|
'';
|
|
};
|
|
go-lint = pkgs.stdenv.mkDerivation {
|
|
name = "go-lint";
|
|
dontBuild = true;
|
|
src = ./.;
|
|
doCheck = true;
|
|
nativeBuildInputs = [
|
|
pkgs.golangci-lint
|
|
go
|
|
pkgs.writableTmpDirAsHomeHook
|
|
];
|
|
checkPhase = ''
|
|
golangci-lint run
|
|
'';
|
|
installPhase = ''
|
|
mkdir "$out"
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
checks = { inherit go-test go-lint; };
|
|
formatter = pkgs.nixfmt-tree;
|
|
devShells.default = pkgs.mkShell {
|
|
buildInputs = [
|
|
go
|
|
pkgs.go-tools # staticcheck
|
|
gomod2nix.packages.${system}.default
|
|
];
|
|
packages = with pkgs; [
|
|
mkcert
|
|
sqlite # debugging the index db
|
|
typesense
|
|
skopeo # copy OCI/container images to a registry (CI publishing)
|
|
];
|
|
shellHook = ''
|
|
# Local dev Typesense defaults (see packages.typesense-server).
|
|
export TYPESENSE_API_KEY="''${TYPESENSE_API_KEY:-dev-key}"
|
|
export TYPESENSE_URL="''${TYPESENSE_URL:-http://localhost:8108}"
|
|
echo "Typesense dev: run 'typesense-server' (port 8108, api key $TYPESENSE_API_KEY)"
|
|
'';
|
|
};
|
|
packages = {
|
|
default = ffd-indexer;
|
|
inherit ffd-metrics;
|
|
# Runs a local Typesense instance for development.
|
|
typesense-server = pkgs.writeScriptBin "typesense-server" ''
|
|
#!${pkgs.bash}/bin/bash
|
|
set -euo pipefail
|
|
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
|
|
DATA_DIR="$ROOT/.typesense/data"
|
|
API_KEY="''${TYPESENSE_API_KEY:-dev-key}"
|
|
PORT="''${TYPESENSE_PORT:-8108}"
|
|
# Peering port follows the API port so multiple dev instances
|
|
# (different TYPESENSE_PORT) do not collide on the default 8107.
|
|
PEERING_PORT=$((PORT - 1))
|
|
mkdir -p "$DATA_DIR"
|
|
echo "Starting Typesense on 127.0.0.1:$PORT (api key: $API_KEY, data: $DATA_DIR)"
|
|
exec ${pkgs.typesense}/bin/typesense-server \
|
|
--data-dir="$DATA_DIR" \
|
|
--api-key="$API_KEY" \
|
|
--api-port="$PORT" \
|
|
--peering-port="$PEERING_PORT" \
|
|
--api-address=127.0.0.1 \
|
|
--enable-cors
|
|
'';
|
|
container = pkgs.dockerTools.buildImage {
|
|
name = "ffd-indexer";
|
|
contents = [
|
|
ffd-indexer
|
|
pkgs.cacert # TLS CA for HTTPS requests to the forges
|
|
];
|
|
config = {
|
|
# The user must provide their own config file and mount it at
|
|
# /etc/ffd-indexer/config.yaml, e.g.:
|
|
# docker run -v $PWD/config.yaml:/etc/ffd-indexer/config.yaml ffd-indexer
|
|
Labels = {
|
|
"org.opencontainers.image.title" = "ffd-indexer";
|
|
"org.opencontainers.image.description" = "Federated Forge Discovery Indexer (scraper)";
|
|
"org.opencontainers.image.licenses" = "AGPL-3.0-or-later";
|
|
"org.opencontainers.image.source" = "https://git.xengi.de/ffd/indexer";
|
|
"org.opencontainers.image.vendor" = "ffd";
|
|
"org.opencontainers.image.version" = version;
|
|
"org.opencontainers.image.revision" = shortRev;
|
|
};
|
|
Volumes = {
|
|
"/etc/ffd-indexer" = { };
|
|
};
|
|
Cmd = [
|
|
"${ffd-indexer}/bin/ffd-indexer"
|
|
"-config"
|
|
"/etc/ffd-indexer/config.yaml"
|
|
];
|
|
};
|
|
};
|
|
|
|
# Long-running metrics image. It shares the same config file shape and
|
|
# reads the same DB volume as the indexer.
|
|
container-metrics = pkgs.dockerTools.buildImage {
|
|
name = "ffd-metrics";
|
|
contents = [
|
|
ffd-indexer
|
|
pkgs.cacert
|
|
];
|
|
config = {
|
|
Labels = {
|
|
"org.opencontainers.image.title" = "ffd-metrics";
|
|
"org.opencontainers.image.description" = "Federated Forge Discovery Indexer (Prometheus metrics daemon)";
|
|
"org.opencontainers.image.licenses" = "AGPL-3.0-or-later";
|
|
"org.opencontainers.image.source" = "https://git.xengi.de/ffd/indexer";
|
|
"org.opencontainers.image.vendor" = "ffd";
|
|
"org.opencontainers.image.version" = version;
|
|
"org.opencontainers.image.revision" = shortRev;
|
|
};
|
|
Volumes = {
|
|
"/etc/ffd-indexer" = { };
|
|
};
|
|
ExposedPorts = {
|
|
"9090/tcp" = { };
|
|
};
|
|
Cmd = [
|
|
"${ffd-indexer}/bin/ffd-metrics"
|
|
"-config"
|
|
"/etc/ffd-indexer/config.yaml"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
nixosModules.default = import ./option.nix;
|
|
}
|
|
)
|
|
// {
|
|
# Overlay so the NixOS module's default package (`pkgs.ffd-indexer`)
|
|
# resolves to this flake's package.
|
|
overlays.default = final: prev: {
|
|
ffd-indexer = self.packages.${final.system}.default;
|
|
ffd-metrics = self.packages.${final.system}.ffd-metrics;
|
|
};
|
|
};
|
|
}
|