From 30fc52dfe91df10222e6205b0c0dc6dfb1a563bd Mon Sep 17 00:00:00 2001 From: td Date: Wed, 3 Jun 2026 15:48:46 +0100 Subject: [PATCH 1/3] chore: dart workflows --- nix/dart/default.nix | 35 ++++++++++++++++++++++++++ nix/dart/devshell.nix | 46 ++++++++++++++++++++++++++++++++++ nix/dart/pre-commit-hooks.nix | 43 ++++++++++++++++++++++++++++++++ nix/dart/workflow.nix | 47 +++++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 nix/dart/default.nix create mode 100644 nix/dart/devshell.nix create mode 100644 nix/dart/pre-commit-hooks.nix create mode 100644 nix/dart/workflow.nix diff --git a/nix/dart/default.nix b/nix/dart/default.nix new file mode 100644 index 0000000..caf96cc --- /dev/null +++ b/nix/dart/default.nix @@ -0,0 +1,35 @@ +{ + flake-parts-lib, + lib, + importApply, + ... +}@args: +importingFlake: { + imports = [ + (importApply ./devshell.nix args) + (importApply ./pre-commit-hooks.nix args) + + ./workflow.nix + ]; + + options.perSystem = flake-parts-lib.mkPerSystemOption ({ + options.famedly.standards.dart.projects = lib.mkOption { + description = '' + Dart projects in the repository that should be equipped with our + standards. + + This must be a relative path starting with `.`. Simply use `.` if the + whole project is a Dart project. + ''; + default = { }; + + example = '' + { + "." = { }; + } + ''; + + type = lib.types.attrsOf (lib.types.submodule { }); + }; + }); +} diff --git a/nix/dart/devshell.nix b/nix/dart/devshell.nix new file mode 100644 index 0000000..4bb226a --- /dev/null +++ b/nix/dart/devshell.nix @@ -0,0 +1,46 @@ +{ inputs, ... }: +importingFlake: { + perSystem = + { + config, + lib, + self', + pkgs, + system, + ... + }: + lib.mkMerge [ + { + devshells.dart = { + packages = + (lib.attrValues { + inherit (pkgs) + dart + ; + }) + + # TODO: Find a nice way to inherit all settings from the + # general devshell, not just package. + ++ config.devshells.general.packages; + }; + + # Install .envrc files that set up the correct devenv into all + # Dart projects. + filegen.settings.files = lib.mapAttrsToList (project: _: { + type = "copy"; + target = "${project}/.envrc"; + source = pkgs.writeText ".envrc" '' + use flake .#dart + ''; + clobber = true; + }) config.famedly.standards.dart.projects; + } + + (lib.mkIf (lib.hasSuffix "linux" system) { + devshells.dart.packages = lib.attrValues { + inherit (pkgs) + ; + }; + }) + ]; +} diff --git a/nix/dart/pre-commit-hooks.nix b/nix/dart/pre-commit-hooks.nix new file mode 100644 index 0000000..f9d4cd7 --- /dev/null +++ b/nix/dart/pre-commit-hooks.nix @@ -0,0 +1,43 @@ +{ + flakeModules, + inputs, + flake-parts-lib, + lib, + ... +}: +importingFlake: { + config.perSystem = + { + self', + pkgs, + config, + ... + }: + let + dart = lib.getExe' self'.packages.famedly-dart-toolchain "dart"; + in + { + prek-pre-commit.workspaces = lib.mapAttrs (name: _: { + default_language_version.dart = "system"; + + repos = [ + { + repo = "local"; + hooks = [ + { + id = "dart-analyze"; + name = "dart-analyze"; + description = "Run dart analyze on all targets"; + + entry = "${dart} analyze --fatal-infos --fatal-warnings --fatal-lints"; + + language = "system"; + types = [ "dart" ]; + pass_filenames = false; + } + ]; + } + ]; + }) config.famedly.standards.dart.projects; + }; +} diff --git a/nix/dart/workflow.nix b/nix/dart/workflow.nix new file mode 100644 index 0000000..46762e1 --- /dev/null +++ b/nix/dart/workflow.nix @@ -0,0 +1,47 @@ +{ config, ... }: +let + allowed-actions = config.famedly.standards.allowed-action-versions; +in +{ + perSystem = + { ... }: + { + githubActions.workflows.dart-test = { + name = "Dart test workflow"; + + on = { + push = { + branches = [ "main" ]; + tags = [ "*" ]; + }; + + pullRequest = { + branches = [ "*" ]; + types = [ + "opened" + "reopened" + "synchronize" + "ready_for_review" + ]; + }; + }; + + concurrency = { + group = "\${{ github.workflow }}-\${{ github.ref }}"; + cancelInProgress = true; + }; + + defaults.run.shell = "nu --no-config-file --no-history {0}"; + env.DART_TERM_COLOR = "always"; + + jobs.test = { + runsOn = "ubuntu-latest-4core"; + + steps = [ + { uses = allowed-actions."actions/checkout".uses; } + { uses = allowed-actions."cachix/install-nix-action".uses; } + ]; + }; + }; + }; +} From 8f1e46a84da951284198cbbadd837ae1bd6c57ee Mon Sep 17 00:00:00 2001 From: td Date: Wed, 3 Jun 2026 15:55:15 +0100 Subject: [PATCH 2/3] chore: cleanup --- nix/dart/default.nix | 1 - nix/dart/devshell.nix | 46 --------------------------- nix/dart/workflows/default.nix | 34 ++++++++++++++++++++ nix/dart/{ => workflows}/workflow.nix | 0 4 files changed, 34 insertions(+), 47 deletions(-) delete mode 100644 nix/dart/devshell.nix create mode 100644 nix/dart/workflows/default.nix rename nix/dart/{ => workflows}/workflow.nix (100%) diff --git a/nix/dart/default.nix b/nix/dart/default.nix index caf96cc..af7310a 100644 --- a/nix/dart/default.nix +++ b/nix/dart/default.nix @@ -6,7 +6,6 @@ }@args: importingFlake: { imports = [ - (importApply ./devshell.nix args) (importApply ./pre-commit-hooks.nix args) ./workflow.nix diff --git a/nix/dart/devshell.nix b/nix/dart/devshell.nix deleted file mode 100644 index 4bb226a..0000000 --- a/nix/dart/devshell.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ inputs, ... }: -importingFlake: { - perSystem = - { - config, - lib, - self', - pkgs, - system, - ... - }: - lib.mkMerge [ - { - devshells.dart = { - packages = - (lib.attrValues { - inherit (pkgs) - dart - ; - }) - - # TODO: Find a nice way to inherit all settings from the - # general devshell, not just package. - ++ config.devshells.general.packages; - }; - - # Install .envrc files that set up the correct devenv into all - # Dart projects. - filegen.settings.files = lib.mapAttrsToList (project: _: { - type = "copy"; - target = "${project}/.envrc"; - source = pkgs.writeText ".envrc" '' - use flake .#dart - ''; - clobber = true; - }) config.famedly.standards.dart.projects; - } - - (lib.mkIf (lib.hasSuffix "linux" system) { - devshells.dart.packages = lib.attrValues { - inherit (pkgs) - ; - }; - }) - ]; -} diff --git a/nix/dart/workflows/default.nix b/nix/dart/workflows/default.nix new file mode 100644 index 0000000..af7310a --- /dev/null +++ b/nix/dart/workflows/default.nix @@ -0,0 +1,34 @@ +{ + flake-parts-lib, + lib, + importApply, + ... +}@args: +importingFlake: { + imports = [ + (importApply ./pre-commit-hooks.nix args) + + ./workflow.nix + ]; + + options.perSystem = flake-parts-lib.mkPerSystemOption ({ + options.famedly.standards.dart.projects = lib.mkOption { + description = '' + Dart projects in the repository that should be equipped with our + standards. + + This must be a relative path starting with `.`. Simply use `.` if the + whole project is a Dart project. + ''; + default = { }; + + example = '' + { + "." = { }; + } + ''; + + type = lib.types.attrsOf (lib.types.submodule { }); + }; + }); +} diff --git a/nix/dart/workflow.nix b/nix/dart/workflows/workflow.nix similarity index 100% rename from nix/dart/workflow.nix rename to nix/dart/workflows/workflow.nix From 4d88daaebf97ba6ad485878da757d5a6ed89d84a Mon Sep 17 00:00:00 2001 From: td Date: Wed, 3 Jun 2026 16:19:03 +0100 Subject: [PATCH 3/3] chore: hm this is going to break everything, do not merge, we need to move actions to running inside nix, this right now just generates the github workflow --- .config/filegen-manifest.json | 14 +++++++--- nix/dart/default.nix | 2 +- nix/dart/pre-commit-hooks.nix | 47 ++++++++++++++++++++++++++++++--- nix/dart/workflows/workflow.nix | 15 ++++++++--- nix/default.nix | 1 + 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/.config/filegen-manifest.json b/.config/filegen-manifest.json index 4a6d1dd..6245d9d 100644 --- a/.config/filegen-manifest.json +++ b/.config/filegen-manifest.json @@ -5,7 +5,7 @@ "clobber": true, "deactivate": null, "ignore-modification": null, - "source": "/nix/store/7lmqw9hjcp0wrrcr1fn8vgyjcpsiryns-pre-commit-config.yaml", + "source": "/nix/store/yhbigqfbyr91f9si3b6y6ib5558ddzx3-pre-commit-config.yaml", "target": "./.pre-commit-config.yaml", "type": "copy" }, @@ -13,7 +13,15 @@ "clobber": true, "deactivate": null, "ignore-modification": null, - "source": "/nix/store/lai6c0kl9c0r0j1ld4j8ilrw53k3bxmq-rust-test.yml", + "source": "/nix/store/1i9xz4fis8a12qlv03ss9smrhhv8nicn-dart-test.yml", + "target": "./.github/workflows/dart-test.yml", + "type": "copy" + }, + { + "clobber": true, + "deactivate": null, + "ignore-modification": null, + "source": "/nix/store/59cxdgpnmw5y43fhn7q2bcvz0jv5v9b3-rust-test.yml", "target": "./.github/workflows/rust-test.yml", "type": "copy" }, @@ -21,7 +29,7 @@ "clobber": true, "deactivate": null, "ignore-modification": null, - "source": "/nix/store/glxwjx24212kdvwwwpzcqkhdzck96cvi-envrc", + "source": "/nix/store/qxl4d2ablir1lzshp9manp44nkl0328x-envrc", "target": "./.envrc", "type": "copy" } diff --git a/nix/dart/default.nix b/nix/dart/default.nix index af7310a..5cbecca 100644 --- a/nix/dart/default.nix +++ b/nix/dart/default.nix @@ -8,7 +8,7 @@ importingFlake: { imports = [ (importApply ./pre-commit-hooks.nix args) - ./workflow.nix + ./workflows/workflow.nix ]; options.perSystem = flake-parts-lib.mkPerSystemOption ({ diff --git a/nix/dart/pre-commit-hooks.nix b/nix/dart/pre-commit-hooks.nix index f9d4cd7..1378bdd 100644 --- a/nix/dart/pre-commit-hooks.nix +++ b/nix/dart/pre-commit-hooks.nix @@ -8,13 +8,43 @@ importingFlake: { config.perSystem = { - self', pkgs, config, ... }: let - dart = lib.getExe' self'.packages.famedly-dart-toolchain "dart"; + dart = lib.getExe pkgs.dart; + grep = lib.getExe pkgs.gnugrep; + + check-conventional-commits = pkgs.writeShellScript "check-conventional-commits" '' + set -eu + + commit_message_file="$1" + accepted_prefixes='ci|fix|feat|chore|test|perf|refactor|style|builds|docs|revert' + + if ! ${grep} -Eq "^($accepted_prefixes)(\([[:alnum:]_.-]+\))?!?: .+" "$commit_message_file"; then + echo "Commit message must start with one of: $accepted_prefixes" + exit 1 + fi + ''; + + dart-analyze = pkgs.writeShellScript "dart-analyze" '' + set -eu + + if [ -f pubspec.yaml ] && ${grep} -Eq '^flutter:' pubspec.yaml; then + command=flutter + else + command=${dart} + fi + + ${dart} format lib/ --set-exit-if-changed + "$command" pub get + "$command" analyze + + if command -v dart_code_metrics >/dev/null 2>&1; then + dart_code_metrics analyze lib || true + fi + ''; in { prek-pre-commit.workspaces = lib.mapAttrs (name: _: { @@ -24,12 +54,23 @@ importingFlake: { { repo = "local"; hooks = [ + { + id = "check-conventional-commits"; + name = "check-conventional-commits"; + description = "Check commit messages follow conventional commits"; + + entry = "${check-conventional-commits}"; + + language = "system"; + stages = [ "commit-msg" ]; + } + { id = "dart-analyze"; name = "dart-analyze"; description = "Run dart analyze on all targets"; - entry = "${dart} analyze --fatal-infos --fatal-warnings --fatal-lints"; + entry = "${dart-analyze}"; language = "system"; types = [ "dart" ]; diff --git a/nix/dart/workflows/workflow.nix b/nix/dart/workflows/workflow.nix index 46762e1..f389cb0 100644 --- a/nix/dart/workflows/workflow.nix +++ b/nix/dart/workflows/workflow.nix @@ -1,10 +1,19 @@ -{ config, ... }: +{ config, lib, ... }: let allowed-actions = config.famedly.standards.allowed-action-versions; in { perSystem = - { ... }: + { config, ... }: + let + run-pre-commit = project: '' + nix develop .#general --command sh -c ${lib.escapeShellArg "cd ${lib.escapeShellArg project} && prek run --all-files"} + ''; + dart-project-steps = lib.mapAttrsToList (project: _: { + name = "Run Dart pre-commit checks (${project})"; + run = run-pre-commit project; + }) config.famedly.standards.dart.projects; + in { githubActions.workflows.dart-test = { name = "Dart test workflow"; @@ -40,7 +49,7 @@ in steps = [ { uses = allowed-actions."actions/checkout".uses; } { uses = allowed-actions."cachix/install-nix-action".uses; } - ]; + ] ++ dart-project-steps; }; }; }; diff --git a/nix/default.nix b/nix/default.nix index 502066c..ed7b994 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -11,6 +11,7 @@ importingFlake: { flakeModules.prek-pre-commit (importApply ./general args) + (importApply ./dart args) (importApply ./rust args) ]; }