{ description = "Mobilizon fork for potsda.mn"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nix-filter.url = "github:numtide/nix-filter"; napalm.url = "github:nix-community/napalm"; napalm.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, nix-filter, napalm, }: let forAllSystems = f: nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f system); nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); filter = nix-filter.lib; in { packages = forAllSystems ( system: let pkgs = nixpkgsFor.${system}; # Directories that are neither needed for building the frontend nor the backend. # For better build caching. unrelatedDirs = [ "flake.lock" (filter.matchExt "nix") "docs" "docker" "docker-compose.test.yml" "docker-compose.yml" "generate-test-data" ]; in { mobilizon = pkgs.callPackage ./. { src = filter { root = ./.; exclude = [ "src" (filter.matchExt "js") (filter.matchExt "ts") (filter.matchExt "json") "tests" "scripts" "public" ] ++ unrelatedDirs; }; src-config = ./config; mobilizon-js = self.packages."${system}".mobilizon-frontend; }; mobilizon-frontend = let nodejs = pkgs.nodejs-18_x; in napalm.legacyPackages."${system}".buildPackage (filter { root = ./.; exclude = [ "lib" "config" "test" "rel" "support" ] ++ unrelatedDirs; }) { inherit nodejs; nativeBuildInputs = [ pkgs.imagemagick ]; npmCommands = [ "npm install" "npm run build" ]; # Keep this in sync with the content of ./patches/ customPatchPackages = { vue-i18n-extract."2.0.7" = pkgs: prev: { preConfigure = '' ${pkgs.git}/bin/git apply -p3 ${./patches/vue-i18n-extract+2.0.7.patch} ''; }; }; }; default = self.packages."${system}".mobilizon; # Update local Mobilizon definition update = pkgs.writeShellScriptBin "update" '' set -eou pipefail ${pkgs.mix2nix}/bin/mix2nix ./mix.lock > mix.nix ''; } ); devShells = forAllSystems ( system: let pkgs = nixpkgsFor.${system}; settingsFormat = pkgs.formats.elixirConf { }; mobilizonConfig = settingsFormat.generate "runtime.exs" { ":mobilizon" = { "Mobilizon.Web.Endpoint" = { server = true; url.host = "mobilizon.dev"; http = { ip = settingsFormat.lib.mkTuple [ 0 0 0 0 0 0 0 1 ]; port = 4000; }; secret_key_base = "2q/l1WDx3RQQy7gZ1k001//6nc66moWUEJQyGuMK/z3zPLYW6FYtIgCkUzGP0+X/"; }; "Mobilizon.Web.Auth.Guardian" = { secret_key = "N8x7/tf0kInLFS2poO22g6OGPiMjSrDEhmk29nFqV35q7hQ0DtBt/cRYCsqBNp2L"; }; ":instance" = { name = "Mobilizon"; description = "Change this to a proper description of your instance"; hostname = "mobilizon.dev"; registrations_open = true; email_from = "noreply@mobilizon.dev"; email_reply_to = "noreply@mobilizon.dev"; }; "Mobilizon.Storage.Repo" = { adapter = settingsFormat.lib.mkAtom "Ecto.Adapters.Postgres"; pool_size = 10; username = "mobilizon"; database = "mobilizon"; socket_dir = "/var/run/postgresql"; }; }; }; in { default = pkgs.mkShell { MIX_ENV = "dev"; PGUSER = "mobilizon"; PGDATABASE = "mobilizon"; buildInputs = with pkgs; [ elixir mix2nix cmake imagemagick nodejs inotify-tools (pkgs.writeShellApplication { name = "build"; runtimeInputs = [ elixir nodejs ]; text = '' mix deps.get mix deps.compile mix phx.digest npm install npm run build ''; }) (pkgs.writeShellApplication { name = "setup"; runtimeInputs = [ elixir postgresql ]; text = '' cat ${mobilizonConfig} > config/runtime.exs # We assume the database already exists sudo -u postgres psql -d mobilizon << SQL create extension if not exists postgis; create extension if not exists unaccent; create extension if not exists pg_trgm; SQL mix ecto.migrate ''; }) (pkgs.writeShellApplication { name = "start"; runtimeInputs = [ elixir ]; text = '' mix phx.server ''; }) (pkgs.writeShellApplication { name = "clean"; runtimeInputs = [ postgresql ]; text = '' rm -rf deps/ _build/ node_modules/ sudo -u postgres psql -c "DROP DATABASE mobilizon;" sudo systemctl restart postgresql.service ''; }) ]; }; } ); nixosModules.devSetup = { config, lib, pkgs, ... }: let cfg = config.mobilizonDevEnvironment; in { options.mobilizonDevEnvironment = { enable = lib.mkEnableOption (lib.mdDoc "development environment for Mobilizon"); user = lib.mkOption { type = lib.types.str; description = "Unix user that runs the backend application to connect to the database"; }; }; config = lib.mkIf cfg.enable { services.postgresql = { enable = true; ensureDatabases = [ "mobilizon" ]; ensureUsers = [ { name = "mobilizon"; ensureDBOwnership = true; } ]; extraPlugins = with config.services.postgresql.package.pkgs; [ postgis ]; identMap = '' map-mobilizon ${cfg.user} mobilizon ''; authentication = '' local all mobilizon ident map=map-mobilizon ''; }; }; }; overlays.default = final: prev: { inherit (self.packages."${prev.system}") mobilizon; }; checks = forAllSystems (system: { inherit (self.packages.${system}) mobilizon update; nixosTest = let pkgsMobilizon = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; }; certs = import "${nixpkgs}/nixos/tests/common/acme/server/snakeoil-certs.nix"; test = import ./integration-test.nix { inherit certs; }; in pkgsMobilizon.nixosTest test; }); lib = { # Patch the logos in the source tree of a mobilizon-frontend package before building. # Can be used to construct the argument for .overrideAttrs on mobilizon-frontend. mobilizonLogosOverride = icons: let inherit (icons) logo favicon; in old: { postPatch = '' cp '${logo}' src/assets/logo.svg magick convert \ -resize x16 \ -gravity center \ -crop 16x16+0+0 \ -flatten \ -colors 256 \ '${favicon}' \ public/img/icons/favicon-16x16.png magick convert \ -resize x32 \ -gravity center \ -crop 32x32+0+0 \ -flatten \ -colors 256 \ '${favicon}' \ public/img/icons/favicon-32x32.png magick convert \ -resize x16 \ -gravity center \ -crop 16x16+0+0 \ -flatten \ -colors 256 \ '${favicon}' \ favicon-16x16.ico magick convert \ -resize x32 \ -gravity center \ -crop 32x32+0+0 \ -flatten \ -colors 256 \ '${favicon}' \ favicon-32x32.ico magick convert \ -resize x48 \ -gravity center \ -crop 48x48+0+0 \ -flatten \ -colors 256 \ '${favicon}' \ favicon-48x48.ico magick convert \ favicon-16x16.ico \ favicon-32x32.ico \ favicon-48x48.ico \ public/favicon.ico rm favicon-16x16.ico favicon-32x32.ico favicon-48x48.ico cp '${favicon}' public/img/icons/favicon.svg cp '${favicon}' public/img/icons/safari-pinned-tab.svg magick convert \ '${favicon}' \ -gravity center \ -extent 630x350 \ public/img/mobilizon_default_card.png magick convert \ -background '#e08c96' \ '${logo}' \ -resize 366x108 \ public/img/mobilizon_logo.png '' + nixpkgs.lib.concatMapStrings ( { resize, filename }: '' magick convert \ -resize x${resize} \ '${favicon}' \ public/img/icons/${filename} '' ) [ { resize = "180"; filename = "apple-touch-icon.png"; } { resize = "180"; filename = "apple-touch-icon-180x180.png"; } { resize = "152"; filename = "apple-touch-icon-152x152.png"; } { resize = "120"; filename = "apple-touch-icon-120x120.png"; } { resize = "76"; filename = "apple-touch-icon-76x76.png"; } { resize = "60"; filename = "apple-touch-icon-60x60.png"; } { resize = "192"; filename = "android-chrome-192x192.png"; } { resize = "512"; filename = "android-chrome-512x512.png"; } { resize = "192"; filename = "android-chrome-maskable-192x192.png"; } { resize = "512"; filename = "android-chrome-maskable-512x512.png"; } { resize = "128"; filename = "badge-128x128.png"; } { resize = "144"; filename = "icon-144x144.png"; } { resize = "168"; filename = "icon-168x168.png"; } { resize = "256"; filename = "icon-256x256.png"; } { resize = "48"; filename = "icon-48x48.png"; } { resize = "72"; filename = "icon-72x72.png"; } { resize = "96"; filename = "icon-96x96.png"; } { resize = "144"; filename = "msapplication-icon-144x144.png"; } { resize = "150"; filename = "mstile-150x150.png"; } { resize = "192"; filename = "android-chrome-192x192.png"; } { resize = "512"; filename = "android-chrome-512x512.png"; } { resize = "192"; filename = "android-chrome-maskable-192x192.png"; } { resize = "512"; filename = "android-chrome-maskable-512x512.png"; } ]; }; }; formatter = forAllSystems (system: nixpkgsFor.${system}.nixfmt-rfc-style); }; }