diff --git a/CLAUDE.md b/CLAUDE.md index 1ab8ab6..8008bc2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -759,15 +759,12 @@ BRAND_DIR=branding/cfaun pnpm build:events instead of `@/assets/logo.png`. The latter still works for non-brand assets (`@/assets/bitcoin.svg`, etc.) — it's only the logo that moved. -**NixOS deployment:** `flake.nix` exposes -`lib.mkWebapp { pkgs, brandDir ? ./branding/default, app ? "main" }`. -Server-deploy hosts call it from their `services/webapp.nix`: -`inputs.webapp.lib.mkWebapp { inherit pkgs; brandDir = ./../branding; app = "events"; }`. -Builder pins `pkgs.pnpm_10` regardless of consumer's nixpkgs (keeps -pnpmDeps hash stable downstream), uses `autoPatchelfHook` to handle -prebuilt sharp binaries, and sets `CI=true` to bypass pnpm's -interactive modules-purge prompt. Per-host migration tracked in -aiolabs/server-deploy#8. +**NixOS deployment:** brand directories will eventually live in +`deploy/server-deploy/hosts//branding/`, with each host's +`services/webapp.nix` calling `inputs.webapp.lib.mkWebapp { brandDir = +./../branding; }`. `flake.nix` exposing `lib.mkWebapp` is a follow-up +to this PR. Until it lands, server-deploy continues to build webapp +through its existing path. See aiolabs/server-deploy#8. ## Payment Rails Pattern diff --git a/branding/README.md b/branding/README.md index b84ba6c..37bb1ce 100644 --- a/branding/README.md +++ b/branding/README.md @@ -105,33 +105,6 @@ Outputs land in `public/icons/` (gitignored). ## Integration with NixOS deployment -`flake.nix` exposes `lib.mkWebapp { pkgs, brandDir ? ./branding/default, app ? "main" }` for downstream consumers. Per-host wiring in `deploy/server-deploy/hosts//services/webapp.nix` looks like: - -```nix -{ inputs, pkgs, ... }: -{ - services.webapp.apps = { - main = inputs.webapp.lib.mkWebapp { inherit pkgs; brandDir = ./../branding; }; - events = inputs.webapp.lib.mkWebapp { inherit pkgs; brandDir = ./../branding; app = "events"; }; - wallet = inputs.webapp.lib.mkWebapp { inherit pkgs; brandDir = ./../branding; app = "wallet"; }; - }; -} -``` - -`brandDir` is either a path inside this flake (`./branding/`) or an external path (e.g. `./../branding` from server-deploy). Either way Nix copies it into the build sandbox. - -Builder details: -- Uses `pkgs.pnpm_10` regardless of consumer's nixpkgs, so the pnpmDeps hash stays stable across downstream nixpkgs versions. -- `pkgs.autoPatchelfHook` + `stdenv.cc.cc.lib` patch the prebuilt `@img/sharp-libvips-linux-*` binaries. -- `CI=true` bypasses pnpm 10's interactive modules-purge prompt in the sandbox. +See [aiolabs/webapp#95](https://git.atitlan.io/aiolabs/webapp/issues/95) for the full architecture. In short: `deploy/server-deploy/hosts//branding/` will hold per-host brands, and each host's `services/webapp.nix` will call `inputs.webapp.lib.mkWebapp { brandDir = ./../branding; }` once `lib.mkWebapp` is exposed from `flake.nix` (separate follow-up issue). The architectural payoff: brand and code become independent axes. Logo changes ship via server-deploy commits + redeploys — no webapp release, no `flake.lock` bump. - -For local sanity: - -```bash -nix build .#main # hub with aiolabs default brand -nix build .#events # events standalone with aiolabs default -# events with a custom brand (the impure way, ad-hoc): -nix build --impure --expr 'let pkgs = import {}; flake = builtins.getFlake (toString ./.); in flake.lib.mkWebapp { inherit pkgs; brandDir = /path/to/brand; app = "events"; }' -``` diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 8f6b10e..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1780749050, - "narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a799d3e3886da994fa307f817a6bc705ae538eeb", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index b937be4..0000000 --- a/flake.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ - description = "AIO webapp — modular Vue 3 + Vite shell with Lightning + Nostr standalones"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - let - apps = [ "main" "events" "wallet" "chat" "market" "forum" "tasks" "restaurant" "libra" ]; - - mkWebapp = { pkgs, brandDir ? ./branding/default, app ? "main" }: - let - buildScript = if app == "main" then "build" else "build:${app}"; - outDir = if app == "main" then "dist" else "dist-${app}"; - in - pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "aio-webapp-${app}"; - version = "0.0.0"; - - src = ./.; - - # Pin pnpm major version (10.x) regardless of consumer's nixpkgs - # so the pnpmDeps hash stays stable for downstream callers that - # bring their own pkgs. package.json's packageManager field - # declares pnpm@10.33.0; pnpm_10 satisfies that. - pnpm = pkgs.pnpm_10; - - pnpmDeps = pkgs.fetchPnpmDeps { - inherit (finalAttrs) pname version src; - inherit (finalAttrs) pnpm; - fetcherVersion = 3; - hash = "sha256-FUN2lMHsaBTkk1tljDysYZAoQD+5MIBIEvGnRUWiF4s="; - }; - - nativeBuildInputs = [ - pkgs.nodejs - finalAttrs.pnpm - pkgs.pnpmConfigHook - pkgs.autoPatchelfHook - ]; - - # sharp's prebuilt libvips binaries (under @img/sharp-libvips-*) - # are dynamically linked; autoPatchelfHook needs the runtime libs. - buildInputs = [ - pkgs.stdenv.cc.cc.lib - ]; - - # Brand kit env knobs read by vite-branding.ts and - # pwa-assets.config.ts. brandDir is either ./branding/default - # (a path inside this flake's source) or an external path that - # nix has copied into the build sandbox. - env = { - BRAND_DIR = "${brandDir}"; - BRAND_APP = if app == "main" then "" else app; - # Avoid pnpm 10's interactive modules-purge prompt in the - # sandbox (ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY). - CI = "true"; - }; - - buildPhase = '' - runHook preBuild - pnpm run ${buildScript} - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - mkdir -p $out - cp -r ${outDir} $out/ - runHook postInstall - ''; - - meta = with pkgs.lib; { - description = "AIO webapp${if app == "main" then "" else " (${app} standalone)"}"; - homepage = "https://git.atitlan.io/aiolabs/webapp"; - license = licenses.mit; - platforms = platforms.linux; - }; - }); - in - { - # System-agnostic builder. Downstream NixOS hosts call this from - # their services/webapp.nix with their own brandDir. - lib.mkWebapp = mkWebapp; - } - // flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - # One package per standalone, all using the aiolabs default brand. - # `nix build .#` exercises the builder for sanity / CI. - appPackages = pkgs.lib.genAttrs apps (app: mkWebapp { inherit pkgs app; }); - in - { - packages = appPackages // { - default = appPackages.main; - }; - }); -}