Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
description = "dryvist org-wide config + reusable Nix dev-hygiene flake-module";

# Lean by design: only what the dev-hygiene module needs (no devenv /
# crate2nix / devshell), so consumers importing flakeModules.dev-hygiene get
# a small flake.lock closure. Plain-source consumers (flake = false, e.g. for
# zizmor.yml) are unaffected by this flake.nix.
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
git-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs =
{ self, ... }@inputs:
{
# Reusable flake-parts modules for consuming Nix repos. The dev-hygiene
# module is pre-bound to this repo's treefmt-nix/git-hooks and its own
# zizmor.yml; see nix/dev-hygiene.nix for the consumer snippet.
flakeModules.dev-hygiene = import ./nix/dev-hygiene.nix {
inherit (inputs) treefmt-nix git-hooks;
zizmorConfig = "${self}/zizmor.yml";
};
};
}
138 changes: 138 additions & 0 deletions nix/dev-hygiene.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Org-wide dev-hygiene flake-parts module.
#
# Wires together, for any consuming Nix repo:
# * treefmt-nix — formatter set (nixfmt, deadnix, statix, prettier, shfmt,
# taplo) with the org's standard options
# * git-hooks — pre-commit hooks (deadnix, statix, file hygiene,
# markdownlint, zizmor) plus treefmt against the local wrapper
# * zizmor — the `unpinned-uses` trusted-publisher policy from this repo's
# own zizmor.yml, injected as `--config` (zizmorConfig)
#
# Consumer:
# {
# inputs.dryvist-github.url = "github:dryvist/.github";
# outputs = inputs@{ flake-parts, ... }:
# flake-parts.lib.mkFlake { inherit inputs; } {
# imports = [ inputs.dryvist-github.flakeModules.dev-hygiene ];
# # ... per-system / project config ...
# };
# }
#
# That's it: no `inputs.treefmt-nix`, no `inputs.git-hooks`, no local
# treefmt config, no local zizmor.yml in consumers.
#
# This file is a function that dryvist/.github's flake.nix calls eagerly with
# its OWN inputs, returning a flake-parts module. `treefmt-nix`/`git-hooks`
# references therefore resolve against dryvist/.github's pinned inputs, not the
# consumer's — so consumers import a pre-bound module with a lean closure.
{
treefmt-nix,
git-hooks,
zizmorConfig,
}:
{ ... }:
{
imports = [
treefmt-nix.flakeModule
git-hooks.flakeModule
];

perSystem =
{
config,
pkgs,
...
}:
{
treefmt = {
projectRootFile = "flake.nix";
programs = {
nixfmt.enable = true;
deadnix.enable = true;
statix.enable = true;
prettier.enable = true;
shfmt.enable = true;
taplo.enable = true;
};
settings = {
# CHANGELOG.md is owned by release-please, which regenerates it with
# `*` bullets each release; excluding it keeps prettier from fighting
# the generator (and failing the treefmt/pre-commit checks). Mirrors
# the markdownlint-cli2 exclude below.
global.excludes = [ "CHANGELOG.md" ];
formatter.prettier.options = [
"--print-width"
"100"
];
formatter.shfmt.options = [
"--indent"
"2"
];
};
};

pre-commit.settings.hooks = {
# Nix-source hygiene
deadnix.enable = true;
statix.enable = true;

# Generic file hygiene
check-yaml.enable = true;
check-toml.enable = true;
check-json.enable = true;
check-merge-conflicts.enable = true;
check-added-large-files = {
enable = true;
args = [ "--maxkb=500" ];
};
end-of-file-fixer.enable = true;
# `--markdown-linebreak-ext=md` preserves Markdown's two-space line
# breaks (where trailing whitespace is semantic, not garbage).
trim-trailing-whitespace = {
enable = true;
args = [ "--markdown-linebreak-ext=md" ];
};

# Secret detection
detect-private-keys.enable = true;

# Markdown linting. markdownlint-cli2 has no native git-hooks.nix
# wrapper, so configure it as a custom hook backed by the nixpkgs
# package. CHANGELOG.md is auto-generated by release-please; its
# commit-hash URLs trigger MD013 and per-release section headings
# trigger MD024.
markdownlint-cli2 = {
enable = true;
name = "markdownlint-cli2";
entry = "${pkgs.markdownlint-cli2}/bin/markdownlint-cli2";
files = "\\.md$";
excludes = [ "^CHANGELOG\\.md$" ];
language = "system";
pass_filenames = true;
};

# treefmt drives the wrapper produced by the treefmt-nix module above,
# so the same formatter set runs whether you call `nix fmt` or
# `pre-commit run`.
treefmt = {
enable = true;
package = config.treefmt.build.wrapper;
};

# GitHub Actions workflow security via zizmor. `--config` points at the
# org-wide trusted-publisher policy shipped alongside this module in
# dryvist/.github, so consumers don't ship their own zizmor.yml.
zizmor = {
enable = true;
files = "^\\.github/workflows/.*\\.ya?ml$";
args = [
"--persona=regular"
"--min-severity=medium"
"--min-confidence=medium"
"--config"
zizmorConfig
];
};
};
};
}