Skip to content

Chezmoi onchange and secrets#2

Merged
edwinhern merged 23 commits into
mainfrom
chezmoi-onchange-and-secrets
May 8, 2026
Merged

Chezmoi onchange and secrets#2
edwinhern merged 23 commits into
mainfrom
chezmoi-onchange-and-secrets

Conversation

@edwinhern
Copy link
Copy Markdown
Owner

No description provided.

edwinhern and others added 23 commits April 28, 2026 23:42
- brew-bundle: re-runs brew bundle when Brewfile.tmpl content changes
- mise-install: re-runs mise install when mise/config.toml.tmpl changes
- macos-defaults: scaffold keyed off sw_vers --buildVersion; re-runs after
  every macOS update so defaults write commands can be added incrementally

All three short-circuit cleanly when their target tool isn't on PATH (covers
the bootstrap window before mise/brew are installed).
Personal-only encryption pipeline; nothing is encrypted yet because the
recipient public key is empty. Edwin pastes it into the .chezmoi.toml.tmpl
$ageRecipient line after running keygen.

- home/.chezmoi.toml.tmpl: conditional encryption block, gated on
  context==personal AND recipient!=""
- home/.chezmoiignore.tmpl: always ignore key.txt.age (source state, not a
  target). On non-personal contexts, also ignore .secrets.local and the
  decrypt script (defense-in-depth alongside the script's own context check)
- home/run_onchange_before_decrypt-private-key.sh.tmpl: on first apply,
  decrypts key.txt.age to ~/.config/chezmoi/key.txt with prompted passphrase;
  no-ops on subsequent applies and on non-personal contexts
- home/dot_config/zsh/exports.zsh: source ~/.secrets.local instead of
  ~/.secrets (universal runtime path; personal materializes via chezmoi,
  work via hand)
- Drop the layering-model section (per Edwin's preference)
- Tighten install to a single paragraph
- Add common commands cheatsheet incl. chezmoi re-add (the bidirectional
  loop callout from Sayz Lim's article)
- Document the personal-only age encryption flow and the work-machine
  manual ~/.secrets.local pattern explicitly
- home/key.txt.age: passphrase-protected age private key (committed safely
  — requires the passphrase to decrypt)
- home/encrypted_private_dot_secrets.local.age: GitHub PAT + Context7 API key,
  encrypted to the recipient public key in .chezmoi.toml.tmpl
- home/.chezmoi.toml.tmpl: render sourceDir = repo path, plus the inline age
  recipient (committed safely — public keys are public). The conditional
  encryption block now activates because both context==personal and
  recipient!="" are true.
- home/.chezmoidata/defaults.toml: editor.default = nano (nvim not installed)
- README: encrypt-direct workflow via mktemp + chezmoi encrypt — no plaintext
  ever lands at ~/.secrets.local; the temp file is shredded after encrypt
- Removed GitHub Copilot instructions document to streamline repository.
- Updated README to clarify hostname-aware context management for personal and work machines.
- Deleted old .chezmoi.toml.tmpl and replaced it with a new .chezmoi.yaml.tmpl for improved configuration.
- Consolidated package management into a single packages.yaml file for better organization.
- Removed deprecated external plugin configurations and migrated to a new chezmoiexternal.yaml.tmpl.
- Added new run_once and run_onchange scripts for Homebrew and mise tool installations.
- Cleaned up unnecessary scripts and configurations, ensuring a more efficient setup process.
- Updated Git configuration templates to align with new data structure.
- Removed obsolete files and configurations to maintain repository cleanliness.
… chezmoi version

Co-authored-by: Copilot <copilot@github.com>
- run_onchange_03_install-mise-tools.sh.tmpl: fix include path
  (private_dot_config -> dot_config) so the hash trigger actually
  re-runs when the mise config changes.
- run_onchange_02_install-packages.sh.tmpl: drop the deprecated
  homebrew/cask-fonts tap (fonts moved into homebrew/cask in 2024).
- CLAUDE.md: update the title and response rule to reference
  edwinhern/dotfiles-public; remove the bats Test Policy section
  (no bats files exist in the repo).
- README.md: rewrite the install + apply paragraphs to match what
  scripts/install.sh and the run_onchange_* scripts actually do
  (no Brewfile.tmpl, no mise x chezmoi); fix the work-secrets
  paragraph to describe the actual mechanism (no .chezmoiignore.tmpl
  exists).
- makefile: invoke scripts directly instead of via sh/bash so each
  script's shebang is respected and the targets are consistent.
- scripts/install.sh: standardize shebang on /usr/bin/env sh to
  match the other scripts.
The age-encryption framework was removed in 1fd1d57
(refactor: Restructure dotfiles management). The README still
described the old setup in detail, including a "Work machine
secrets" section that referenced a non-existent
home/.chezmoiignore.tmpl.

Replace both sections with a short "Local secrets" note that
matches what the repo actually does: each machine maintains
its own ~/.secrets.local by hand and zsh sources it from
home/dot_config/zsh/exports.zsh. Drop the chezmoi encryption
FAQ link from References since it's no longer relevant.
…erage (#5)

Applies a few principle-driven cleanups:

YAGNI — repo is macOS-only:
- home/.chezmoi.yaml.tmpl: drop the `edwinhern-personal-windows`
  branch from machine detection. There are no Windows scripts under
  home/.chezmoiscripts/ to act on a Windows context.
- home/.chezmoidata/packages.yaml: drop the `windows.winget` block
  for the same reason — no script ever reads it.

Dead template data:
- home/.chezmoi.yaml.tmpl: drop `font.mono` and `editor.default` —
  no template references either field.

Pointless template:
- Rename home/dot_zshenv.tmpl -> home/dot_zshenv. The file contains
  only `export ZDOTDIR="$HOME/.config/zsh"` with zero template
  syntax; the .tmpl suffix forces a needless render pass.

Deprecated flag:
- home/.chezmoiscripts/darwin/run_onchange_02_install-packages.sh.tmpl:
  drop `--no-lock` from `brew bundle`. Homebrew Bundle 4 removed
  lockfiles entirely; the flag is a no-op.

Documentation drift:
- README.md: `Edwins-MacBook-Pro` -> `edwinhern-personal-mac` to
  match the actual hostname check, and `chezmoi.toml.tmpl` ->
  `chezmoi.yaml.tmpl` to match the file that actually exists.

Coverage gap:
- scripts/lint.sh, scripts/format.sh: prettier glob extended to
  `**/*.yaml`. The repo has several .yaml files (packages.yaml,
  dependabot.yaml, the chezmoiexternal partial) that the .yml-only
  glob silently skipped.
…ess, and development packages

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
run_onchange_05_defaults.sh.tmpl (renamed from
run_onchange_after_10-defaults.sh.tmpl to slot into the existing
02/03/04 sequence):

- Sets Finder, Dock, Screenshots, and misc system defaults.
- Dock pinned apps now declarative via dockutil — added dockutil
  to packages.yaml shared formulas. Each app entry is guarded by
  `[ -d "$app" ]` so a missing app silently skips instead of
  crashing the apply.
- Removed `sudo nvram StartupMute=%01` (would block unattended
  apply on machines without TouchID-for-sudo).
- Brave default-browser check now actually works — the previous
  draft captured awk's empty stdout into a variable and ran it
  as a command, so the guard was always a no-op. Pipeline goes
  directly into `if !`.
- Screenshot location uses "$HOME/..." instead of literal "~/..."
  (defaults doesn't expand tilde inside quotes).
- Deduped a double LSQuarantine write.
- Dropped empty `## ` placeholder comments per CLAUDE.md's
  shdoc-compatible-English-comments rule.
- Header comment fixed to reference the new filename.

home/.chezmoiexternal.yaml.tmpl:
- {{ template "chezmoiexternal.d/darwin.yaml.tmpl" . }} →
  {{ template "chezmoiexternal.d/darwin.yaml" . }}.
  The partial in .chezmoitemplates/ is registered by its on-disk
  name (darwin.yaml), not its target name. The .tmpl-suffixed
  invocation has been silently failing — chezmoi reported
  `template "chezmoiexternal.d/darwin.yaml.tmpl" not defined`
  on every apply, which means the zsh plugin externals
  (autosuggestions, syntax-highlighting, etc.) haven't been
  refreshed by chezmoi for an unknown stretch.

home/dot_config/tmux/tmux.conf:
- Enable mouse mode and vi-style copy-mode keybindings.
The "2.0.0" pin was added thinking it was a stable major version,
but chezmoi v2.0.0 is the very first 2.x release from March 2021.
It predates `stdinIsATTY` (added in v2.16.0, July 2022), which
home/.chezmoi.yaml.tmpl depends on for non-interactive fallback.

When mise activates this project's tool versions, `chezmoi init`
runs the pinned v2.0.0 binary and fails with:
  template: chezmoi.yaml:23: function "stdinIsATTY" not defined

Pin to v2.70.2 to match what the system already has installed
and what we've validated against in this branch.

Also incorporate the staged doc-comment fix in
run_onchange_04_install-vscode-extensions.sh.tmpl (header now
references extensions.yaml, matching the include path).
VS Code 1.95+ ships GitHub Copilot Chat as a built-in extension
(currently v0.46.2 on this machine). The marketplace version is
older (v0.45.1), so `code --install-extension github.copilot-chat`
errors with "cannot be downgraded" and aborts the whole apply
under `set -euo pipefail`, preventing run_onchange_05_defaults
from running.

Two changes:

- extensions.yaml: drop github.copilot-chat from shared extensions.
  It's installed automatically with VS Code now and managed via
  VS Code's update channel, not the marketplace install path.

- run_onchange_04_install-vscode-extensions.sh.tmpl: catch
  per-extension failures into a `failed` array and log them at
  the end instead of letting one bad extension halt apply. Future
  cases (a marketplace listing yanked, a corporate policy block,
  etc.) will warn but not break the apply chain.
@edwinhern edwinhern merged commit f5a4f99 into main May 8, 2026
4 checks passed
@edwinhern edwinhern deleted the chezmoi-onchange-and-secrets branch May 8, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant