mobilizon/flake.nix

473 lines
14 KiB
Nix

{
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);
};
}