Files
Oleks f8053537a9
ci/woodpecker/push/amd64 Pipeline failed
ci/woodpecker/push/arm64 Pipeline was canceled
feat(antigravity): update to v2.0 split; expose ide, ide-no-fhs, cli; add all to CI warming
2026-06-05 12:34:25 +03:00

430 lines
17 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
description = "oleks's personal Flake hub a place to publish custom packages and overlays";
inputs = {
fleet-pins.url = "git+https://git.oleks.space/oleks/fleet-pins?ref=main";
nixpkgs.follows = "fleet-pins/nixpkgs-projects";
flake-utils.url = "github:numtide/flake-utils";
# Shared per-archetype parity publish-app builders (cluster#104, emmett#44).
# flake-hub is an ATTIC-CLOSURE repo: it builds package closures and warms
# the Attic cache with them — there is NO registry artifact.
# mkAtticClosurePublish makes that archetype explicit to pipeline-doctor.
parity.url = "git+https://git.oleks.space/oleks/parity-lib";
# Hyprspace source; no flake.nix in the repo so we consume it as raw src.
# Pin tracks the last v0.52-compatible commit of Hyprspace.
hyprspace = {
url = "github:KZDKM/Hyprspace/0467be86b18cfc324fab04afbd40fe9ef80f7fa9";
flake = false;
};
# Google Antigravity packaging. Upstream auto-updates daily; we re-expose
# the overlay and build into our attic cache so emmett pulls from there.
antigravity-nix = {
url = "github:jacopone/antigravity-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# nix-deps: "see the real cost of installing packages on NixOS".
# Re-exposed through our overlay so CI builds it into attic.
nix-deps = {
url = "github:manelinux/nix-deps";
inputs.nixpkgs.follows = "nixpkgs";
};
# stalewood — find/reap merged git worktrees. Ships its own flake;
# re-expose its package (mirrors the nix-deps pattern).
stalewood = {
url = "github:retif/stalewood";
inputs.nixpkgs.follows = "nixpkgs";
};
# woodpecker-peek — tray app for Woodpecker CI (on git.oleks.space).
# Re-exposed so flake-hub CI warms attic and emmett pulls cached.
woodpecker-peek = {
url = "git+https://git.oleks.space/oleks/woodpecker-peek?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
# mcp-chrome — Chrome MCP server + extension (English-localized fork of
# hangwin/mcp-chrome). Re-exposes the from-source wasm-simd worker (proven
# green, ~22 s) and the full chrome-mcp-extension build. The extension
# target is KNOWN-BROKEN under nix-daemon at this pin (see oleks/mcp-chrome
# issue #1 close comment); expect attic to miss it until that's resolved.
mcp-chrome = {
url = "git+https://git.oleks.space/oleks/mcp-chrome?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
nixpkgs,
fleet-pins,
flake-utils,
parity,
hyprspace,
antigravity-nix,
nix-deps,
stalewood,
woodpecker-peek,
mcp-chrome,
...
}:
let
# Systems that have native builders
buildSystems = [
"x86_64-linux"
"aarch64-linux"
];
# Cross-compilation targets from x86_64-linux
crossTargets = {
"s390x-linux" = "s390x-linux";
};
mkPackages =
pkgs:
let
sys = pkgs.stdenv.hostPlatform.system;
# Antigravity ships a Google-provided x86_64/aarch64 Linux binary.
# Skip it for cross targets (e.g. s390x) where it can't run anyway.
supportsAntigravity = sys == "x86_64-linux" || sys == "aarch64-linux";
xontribs = import ./packages/xontribs.nix {
inherit (pkgs) python3Packages fetchurl;
};
in
{
hello-world = pkgs.callPackage ./packages/hello-world.nix { };
geesefs = pkgs.callPackage ./packages/geesefs.nix { };
metamcp = pkgs.callPackage ./packages/metamcp.nix { };
xonsh = pkgs.callPackage ./packages/xonsh.nix {
xonsh-unwrapped = import ./packages/xonsh-unwrapped.nix {
inherit (pkgs) lib python3Packages fetchFromGitHub;
};
};
}
# Native-only packages — skip on s390x cross (gitea's pnpm step and
# cgo+sqlite link don't cross-compile cleanly).
// nixpkgs.lib.optionalAttrs (sys == "x86_64-linux" || sys == "aarch64-linux") {
gitea-local-fork =
let
# Our fork's go.mod requires Go 1.26.3; nixpkgs at this pin has
# only 1.26.0 (and unstable has 1.26.2). Bump the package's src.
go = pkgs.go_1_26.overrideAttrs (_: rec {
version = "1.26.3";
src = pkgs.fetchurl {
url = "https://go.dev/dl/go${version}.src.tar.gz";
hash = "sha256-HGRoddCqh5kTMYTtV895/yS97+jIggRwYCqdPW2Rkrg=";
};
});
in
pkgs.callPackage ./packages/gitea-local-fork.nix {
buildGoModule = pkgs.buildGoModule.override { inherit go; };
};
}
# Xontribs: pass into `programs.xonsh.extraPackages` or
# `pkgs.xonsh.override { extraPackages = ps: [...]; }`.
// xontribs
# Antigravity: re-expose jacopone/antigravity-nix's outputs so emmett
# consumes a single flake-hub input and our CI builds into attic.
// nixpkgs.lib.optionalAttrs supportsAntigravity {
inherit (antigravity-nix.packages.${sys})
google-antigravity
google-antigravity-no-fhs
google-antigravity-ide
google-antigravity-ide-no-fhs
google-antigravity-cli
;
# nix-deps' flake only outputs eachDefaultSystem (no s390x), so
# gate it on the same native x86_64/aarch64 condition.
nix-deps = nix-deps.packages.${sys}.default;
# stalewood — re-exposed from its own flake. No s390x output,
# so it rides the same native-only gate.
stalewood = stalewood.packages.${sys}.default;
# woodpecker-peek — same pattern; consumers (emmett) read the
# attic-cached binary via flake-hub's overlay, then set
# services.woodpecker-peek.package = pkgs.woodpecker-peek;.
woodpecker-peek = woodpecker-peek.packages.${sys}.default;
# mcp-chrome — Rust→wasm worker (proven green) plus the full
# chrome-mcp-extension build. The latter is KNOWN-BROKEN under
# nix-daemon at this pin; flake-hub CI will miss the cache on it
# until upstream resolves that. wasm-simd alone is what consumers
# actually pull cached today (commits 9534234, b276465 in
# oleks/mcp-chrome sync the built wasm back into the tree).
mcp-chrome-wasm-simd = mcp-chrome.packages.${sys}.wasm-simd;
mcp-chrome-extension = mcp-chrome.packages.${sys}.chrome-mcp-extension;
};
# Overlay providing Hyprspace. Requires `pkgs.hyprland` to be present
# (consumer applies the Hyprland flake's overlay first). Kept out of
# `mkPackages` because standalone `nix build .#hyprspace` has no
# Hyprland in scope.
hyprspaceOverlay = final: _prev: {
hyprspace = final.callPackage ./packages/hyprspace.nix {
src = hyprspace;
};
};
# Rustc bootstrap: symlink_file panics with "File exists" during
# s390x cross-compilation. Multiple call sites use t!(symlink_file(...)).
# Patch the symlink_file method body to remove an existing dest first.
# Exported as overlays.s390xRustcSymlink so nixos-ci consumes this single
# definition (and the patch travels with it) instead of duplicating it.
s390xRustcSymlinkOverlay =
final: prev:
let
patchedRustcUnwrapped = prev.rustc-unwrapped.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [
./patches/rustc-symlink-file-eexist.patch
];
});
in
{
rustc-unwrapped = patchedRustcUnwrapped;
rustc = prev.rustc.override {
rustc-unwrapped = patchedRustcUnwrapped;
};
};
# Overlays needed for s390x cross-compilation of attic-client
s390xOverlays = [
# OpenSSL s390x assembly uses z10 instructions (cijne) that the
# nix-bootstrapped assembler doesn't recognize
(final: prev: {
openssl = prev.openssl.overrideAttrs (old: {
configureFlags = (old.configureFlags or [ ]) ++ [ "no-asm" ];
});
})
# musl doesn't support s390x long double (IBM double-double format:
# LDBL_MANT_DIG=106, sizeof=16). Make musl appear unavailable so
# busybox-sandbox-shell uses glibc static instead.
(final: prev: {
busybox-sandbox-shell = prev.busybox-sandbox-shell.override {
musl = prev.musl // {
meta = prev.musl.meta // {
platforms = [ ];
};
};
};
})
# libarchive tests fail in k8s pod sandboxes
(final: prev: {
libarchive = prev.libarchive.overrideAttrs (_: {
doCheck = false;
});
})
# nix 2.28 is a direct dependency of attic-client — disable tests
# and fix missing RPATH for boost/zstd/libarchive
(final: prev: {
nixVersions = prev.nixVersions // {
nix_2_28 = prev.nixVersions.nix_2_28.overrideAttrs (old: {
doCheck = false;
doInstallCheck = false;
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ final.patchelf ];
postFixup = (old.postFixup or "") + ''
for rpath in ${final.boost}/lib ${final.zstd.out}/lib ${final.libarchive.out}/lib; do
patchelf --add-rpath "$rpath" $out/bin/nix
for lib in $out/lib/lib*.so; do
[ -f "$lib" ] && patchelf --add-rpath "$rpath" "$lib"
done
done
'';
});
};
})
# LLVM test failures in CI pod environment — override libllvm
# (not llvm) so it propagates through rustc bootstrap chain
(final: prev: {
llvmPackages = prev.llvmPackages // {
libllvm = prev.llvmPackages.libllvm.overrideAttrs (old: {
doCheck = false;
doInstallCheck = false;
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ prev.gitMinimal ];
});
};
})
# Rustc symlink_file "File exists" fix (defined + exported above).
s390xRustcSymlinkOverlay
];
# Native builds
native = flake-utils.lib.eachSystem buildSystems (
system:
let
pkgs = import nixpkgs { inherit system; };
packages = mkPackages pkgs;
in
{
packages = packages // {
default = packages.hello-world;
};
formatter = pkgs.nixfmt-rfc-style;
devShells.default = pkgs.mkShell {
name = "oleks-hub-shell";
buildInputs = [ self.packages.${system}.default ];
nativeBuildInputs = with pkgs; [
nix
fmt
];
shellHook = ''
echo "Welcome to the oleks Flake hub development shell."
'';
};
}
);
# Cross-compiled builds (built from x86_64-linux)
cross = builtins.listToAttrs (
builtins.map (
target:
let
targetOverlays =
{
"s390x-linux" = s390xOverlays;
}
.${target} or [ ];
pkgs = import nixpkgs {
system = "x86_64-linux";
crossSystem.config =
nixpkgs.lib.systems.examples.${
{
"s390x-linux" = "s390x";
}
.${target}
}.config;
overlays = targetOverlays;
};
packages = mkPackages pkgs;
crossOnlyPackages =
{
"s390x-linux" = {
inherit (pkgs)
attic-client
rustc
cargo
rustfmt
sccache
mold
;
nix = pkgs.nixVersions.nix_2_28;
};
}
.${target} or { };
in
{
name = target;
value =
packages
// crossOnlyPackages
// {
default = packages.hello-world;
};
}
) (builtins.attrNames crossTargets)
);
in
native
// {
packages = (native.packages or { }) // cross;
overlays = {
default = final: _prev: mkPackages final;
gcc15-fixes = import ./overlays/gcc15-fixes.nix;
hyprspace = hyprspaceOverlay;
# Single home for the s390x rustc symlink_file patch overlay so
# consumers (nixos-ci) don't re-declare it + the patch file.
s390xRustcSymlink = s390xRustcSymlinkOverlay;
};
# `nix run .#<app>` — local-parity entrypoints (emmett#44, cluster#192,
# ATTIC-CLOSURE archetype, cluster#104). The stage/publish/push-staged
# apps come straight from parity-lib's mkAtticClosurePublish, so CI and a
# local run share one audited implementation and cannot drift. There is NO
# registry artifact — these apps build the package closures and warm the
# Attic cache with them.
#
# TWO HALVES (emmett#44): STAGE `nix build`s every package in the arch's
# list into the local /nix store (cluster-independent, runs on emmett);
# PUBLISH additionally `attic push`es each closure to the cache that lives
# next to the cluster. Local runs DRY-RUN (stage + show the pushes) unless
# `--publish`/PUBLISH=1.
#
# nix run .#stage-x86_64-linux stage amd64 closures, no publish
# nix run .#publish stage amd64 then push if PUBLISH=1
# nix run .#publish -- --publish actually push to attic
# nix run .#push-staged replay already-staged amd64 paths
#
# arm64 leg: aarch64-linux cannot be built on emmett (linux/amd64) and the
# native packages have no cross path, so it MUST run on an aarch64 node
# (.woodpecker/arm64.yaml runs `PUBLISH=1 nix run .#publish-aarch64-linux`).
#
# The package set per arch mirrors flake-hub's CI warm list (was
# ci/publish.py packages_for): the always-on core plus arch-conditional
# extras. Cross-only/known-broken targets stay out (see comments).
apps =
let
# The Attic cache token lives at `pass infra/attic/ci_token` and the
# cache is reached via the armer hairpin endpoint — preserve both so
# the push is byte-for-byte the pre-parity behaviour.
atticEndpoint = "https://nix-cache-upload.oleks.space";
atticPass = "infra/attic/ci_token";
# Package names to warm into Attic for a given native arch.
# Native arches only (amd64/arm64); mcp-chrome-extension stays OUT
# (known-broken under nix-daemon at this pin, see oleks/mcp-chrome #1).
packageNamesFor =
arch:
[
"hello-world"
"geesefs"
"xonsh"
]
++ nixpkgs.lib.optionals (arch == "x86_64-linux" || arch == "aarch64-linux") [
"woodpecker-peek"
"mcp-chrome-wasm-simd"
"gitea-local-fork"
"google-antigravity"
"google-antigravity-no-fhs"
"google-antigravity-ide"
"google-antigravity-ide-no-fhs"
"google-antigravity-cli"
];
drvsFor = arch: map (n: self.packages.${arch}.${n}) (packageNamesFor arch);
buildersFor = arch: parity.lib.mkParityBuilders (import nixpkgs { system = arch; });
atticAppsFor =
arch:
(buildersFor arch).mkAtticClosurePublish {
drvs = drvsFor arch;
inherit arch;
endpoint = atticEndpoint;
passEntry = atticPass;
};
amd64Apps = atticAppsFor "x86_64-linux";
arm64Apps = atticAppsFor "aarch64-linux";
in
nixpkgs.lib.genAttrs buildSystems (system:
# amd64 is the emmett-buildable arch: expose its stage/publish/
# push-staged plus the top-level `publish`. Also surface the arm64
# stage/publish under their arch-suffixed names for the node-bound
# CI leg (.woodpecker/arm64.yaml).
{
inherit (amd64Apps)
"stage-x86_64-linux"
"publish-x86_64-linux"
"publish"
"push-staged"
;
"stage-aarch64-linux" = arm64Apps."stage-aarch64-linux";
"publish-aarch64-linux" = arm64Apps."publish-aarch64-linux";
});
};
}