Add home-manager module#2
Open
pathob wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a home-manager module that shares the existing agenix-extras template and unit-trigger helpers with the NixOS module, plus examples, CI coverage, and a smoke test.
Changes:
- Refactors shared template/render/trigger logic into
modules/lib.nix. - Adds
modules/agenix-extras-home.nixand exports it via the flake. - Updates examples, README, tests, and CI to cover home-manager usage.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
modules/lib.nix |
Shared helper implementation for templates, rendering, assertions, and trigger generation. |
modules/agenix-extras.nix |
NixOS module simplified to use shared helpers. |
modules/agenix-extras-home.nix |
New home-manager module for template rendering and user-unit triggers. |
flake.nix |
Adds home-manager input/module export and new check. |
tests/templates-home.nix |
Adds home-manager evaluation smoke test. |
tests/templates.nix |
Updates example module import parameters. |
example/module.nix |
Parameterizes fixture secret paths and separates trigger wiring. |
example/home.nix |
Adds home-manager example wiring. |
example/configuration.nix |
Wires NixOS and home-manager examples together. |
example/flake.nix |
Adds home-manager module input to example flake. |
README.md |
Documents home-manager usage and limitations. |
.github/workflows/ci.yml |
Adds the new home-manager smoke test to CI matrix. |
Comments suppressed due to low confidence (2)
modules/agenix-extras-home.nix:116
- The home-manager renderer unit does not change when a referenced secret's
.agefile changes, because the generated ExecStart script only embeds the runtime secret path, not the ciphertext trigger paths. Since the oneshot isRemainAfterExit=true, a subsequenthome-manager switchcan restart the consuming unit via its X-Restart-Triggers while leaving the rendered template with the old plaintext; the renderer itself needs equivalent trigger content or another mechanism that forces it to rerun when any template input changes.
ExecStart = "${pkgs.writeShellScript "agenix-extras-render" (
extras.activationScriptText {
chmodOwner = false;
pathsExpand = true;
}
)}";
modules/agenix-extras-home.nix:115
- The shared template type still exposes
ownerandgroup, but the home-manager renderer passeschmodOwner = false, so those options are silently ignored for HM templates. Accepting no-op ownership settings makes the advertisedage.templatesinterface misleading; either reject non-default owner/group values in the HM module or implement/document the supported ownership behavior explicitly.
extras.activationScriptText {
chmodOwner = false;
pathsExpand = true;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Layers the same `age.templates` / `restartUnits` / `reloadUnits` interface
onto agenix's home-manager module so dotfile-style setups can use templates
and restart-on-change for user units.
- Factor pure helpers out of modules/agenix-extras.nix into modules/lib.nix;
the NixOS module becomes a thin shell around it.
- modules/agenix-extras-home.nix renders templates via a user systemd
oneshot ordered After=agenix.service, and attaches X-Restart-Triggers /
X-Reload-Triggers on the named user units so home-manager's switch picks
up content changes.
- renderTemplate gains a `pathsExpand` flag so HM paths containing shell
expansions (${XDG_RUNTIME_DIR}/...) get double-quoted rather than escaped
as literals.
- tests/templates-home.nix is a build-time smoke test against
home-manager.lib.homeManagerConfiguration.
- example/ wires both modules side-by-side; module.nix is now a small
parameterised function so the example flake builds standalone.
- README + CI matrix updated.
6d33041 to
7118bf3
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (3)
modules/agenix-extras-home.nix:60
- The ghost-unit check only treats
Unit,Install, and non-XServicekeys as evidence that a target exists. Valid non-service units declared with their type-specific sections (for exampleTimer,Socket, orPath) can be reported as undeclared stubs even though they have a real body.
(unit.Unit or { }) != { }
|| (unit.Install or { }) != { }
|| lib.any (k: !(lib.hasPrefix "X-" k)) (lib.attrNames (unit.Service or { }))
README.md:179
- This describes all Home Manager triggers as
Service.X-Restart-Triggers, but the module emitsX-Reload-TriggersforreloadUnitsas well. The limitation text should distinguish the restart and reload markers so users know what is actually generated.
touch system units. Triggers are encoded as `Service.X-Restart-Triggers` on
the user unit so home-manager's switch detects them as content changes.
README.md:72
- The Home Manager snippet adds a restart trigger for
mbsync.servicewithout showing or mentioning that the unit must also be declared insystemd.user.services.mbsync. As implemented, referencing an unmanaged or misspelled unit creates the stub unit warned about by the module, so this example can lead users to an invalid user unit.
age.secrets.api-token = {
file = ./secrets/api-token.age;
restartUnits = [ "mbsync.service" ]; # user units only
};
| chmodOwner = false; | ||
| pathsExpand = true; | ||
| } | ||
| )}"; |
Comment on lines
+29
to
+34
| lib.mapAttrs ( | ||
| _: kindAttrs: | ||
| lib.mapAttrs ( | ||
| _: u: { Service.${triggerKey} = triggersToServiceKey u.triggers; } | ||
| ) kindAttrs | ||
| ) (extras.triggersFor field "triggers"); |
Comment on lines
+151
to
+153
| extras.activationScriptText { | ||
| chmodOwner = false; | ||
| pathsExpand = true; |
| ]; | ||
|
|
||
| age.identityPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ]; | ||
|
|
Comment on lines
+35
to
+37
| age.secrets.api-token = { | ||
| file = fakeAge; | ||
| restartUnits = [ "mbsync.service" ]; |
Comment on lines
+313
to
+316
| ok = | ||
| lib.hasPrefix "/" t.path | ||
| || (pathsExpand && lib.hasPrefix "${cfg.secretsDir}/" t.path) | ||
| || (pathsExpand && t.path == cfg.secretsDir); |
Comment on lines
+161
to
+162
| (attachTriggers "restartUnits" "X-Restart-Triggers") | ||
| (attachTriggers "reloadUnits" "X-Reload-Triggers") |
Comment on lines
+61
to
+66
| For home-manager as a NixOS submodule: | ||
|
|
||
| ```nix | ||
| { | ||
| home-manager.users.alice = { ... }: { | ||
| imports = [ agenix-extras.homeManagerModules.default ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Layers the same
age.templates/restartUnits/reloadUnitsinterface onto agenix's home-manager module so dotfile-style setups can use templates and restart-on-change for user units.pathsExpandflag so HM paths containing shell expansions (${XDG_RUNTIME_DIR}/...) get double-quoted rather than escaped as literals.