-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
277 lines (259 loc) · 10.9 KB
/
Makefile
File metadata and controls
277 lines (259 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# infra bootstrap makefile
#
# tl;dr:
#
# 1. Run 'make bootstrap' to install nix and direnv
# 2. Run 'make verify' to check your installation
# 3. Run 'make setup-user' to generate age keys for secrets (first time only)
# 4. Run 'nix develop' to enter the development environment
# 5. Use 'just ...' to run configuration tasks
#
# This Makefile helps bootstrap a development environment with nix and direnv.
# After bootstrap is complete, see the justfile for managing configurations.
.DEFAULT_GOAL := help
#-------
##@ help
#-------
# based on "https://gist.github.com/prwhite/8168133?permalink_comment_id=4260260#gistcomment-4260260"
.PHONY: help
help: ## Display this help. (Default)
@grep -hE '^(##@|[A-Za-z0-9_ \-]*?:.*##).*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; /^##@/ {print "\n" substr($$0, 5)} /^[A-Za-z0-9_ \-]*?:.*##/ {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
help-sort: ## Display alphabetized version of help (no section headings).
@grep -hE '^[A-Za-z0-9_ \-]*?:.*##.*$$' $(MAKEFILE_LIST) | sort | \
awk 'BEGIN {FS = ":.*?## "}; /^[A-Za-z0-9_ \-]*?:.*##/ {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
HELP_TARGETS_PATTERN ?= test
help-targets: ## Print commands for all targets matching a given pattern. Copy this example into your shell:
help-targets: ## Copy this example into your shell:
help-targets: ## eval "$(make help-targets HELP_TARGETS_PATTERN=bootstrap | sed 's/\x1b\[[0-9;]*m//g')"
@make help-sort | awk '{print $$1}' | grep '$(HELP_TARGETS_PATTERN)' | xargs -I {} printf "printf '___\n\n{}:\n\n'\nmake -n {}\nprintf '\n'\n"
# catch-all pattern rule
#
# This rule matches any targets that are not explicitly defined in this
# Makefile. It prevents 'make' from failing due to unrecognized targets, which
# is particularly useful when passing arguments or targets to sub-Makefiles. The
# '@:' command is a no-op, indicating that nothing should be done for these
# targets within this Makefile.
#
%:
@:
#-------
##@ bootstrap
#-------
.PHONY: bootstrap-prep-darwin
bootstrap-prep-darwin: ## Install darwin prerequisites (Xcode CLI tools + Homebrew) before 'make bootstrap'
@printf "Installing darwin prerequisites...\n\n"
@printf "Step 1: Xcode Command Line Tools\n"
@if xcode-select -p &>/dev/null; then \
printf " ● Xcode CLI tools already installed\n"; \
else \
printf " Installing Xcode CLI tools (this will open a dialog)...\n"; \
xcode-select --install; \
printf " ⏳ Wait for installation to complete, then re-run this target\n"; \
exit 1; \
fi
@printf "\nStep 2: Homebrew\n"
@if command -v brew &>/dev/null; then \
printf " ● Homebrew already installed\n"; \
else \
printf " Installing Homebrew...\n"; \
/bin/bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; \
fi
@printf "\n● Darwin prerequisites complete!\n"
@printf "Next: Run 'make bootstrap' to install Nix\n"
.PHONY: bootstrap
bootstrap: ## Main bootstrap target that runs all necessary setup steps
bootstrap: install-nix install-direnv
@printf "\n● Bootstrap of nix and direnv complete!\n\n"
@printf "Next steps:\n"
@echo "1. Start a new shell session (to load nix in PATH)"
@echo "2. Run 'make verify' to check your installation"
@echo "3. Run 'make setup-user' to generate age keys (first time setup)"
@echo "4. Run 'nix develop' to enter the development environment"
@echo ""
@printf "Optional: Auto-activate development environment with direnv\n"
@echo " - See https://direnv.net/docs/hook.html to add direnv to your shell"
@echo " - Start a new shell session"
@echo " - cd out and back into the project directory"
@echo " - Run 'direnv allow' to activate"
@echo ""
@printf "For detailed documentation, see docs/new-user-host.md\n"
.PHONY: install-nix
# Download platform-specific binary directly from GitHub Releases.
# This bypasses both the Fastly CDN (HTTP 618 errors) and the shell wrapper
# (which has template placeholders that aren't filled in for raw source files).
# To update version, change NIX_INSTALLER_VERSION below.
# Note: versioning jumped from 0.27.0 to 3.11.3, then back to 2.33.0 when
# NixOS/nix-installer removed the 3.x tags (repo renamed from experimental-nix-installer).
# https://github.com/NixOS/nix-installer/releases
#
# The nix-installer 2.33.0 defaults include settings equivalent to:
# --extra-conf "experimental-features = nix-command flakes"
# --extra-conf "auto-optimise-store = true"
# --extra-conf "always-allow-substitutes = true"
# --extra-conf "max-jobs = auto"
# --extra-conf "extra-nix-path = nixpkgs=flake:nixpkgs"
# --extra-conf "bash-prompt-prefix = (nix:\$name)\\040"
#
# We add trusted-users to allow flake-specified substituters and public keys:
# --extra-conf "trusted-users = root @admin @wheel"
# This enables accepting flake nixConfig without prompts or warnings.
#
# If using the upstream nix installer (https://nixos.org/download/) which lacks
# these defaults, add the --extra-conf flags above to the install command.
NIX_INSTALLER_VERSION := 2.33.0
install-nix: ## Install Nix using the NixOS community installer
@echo "Installing Nix..."
@if command -v nix >/dev/null 2>&1; then \
echo "Nix is already installed."; \
else \
case "$$(uname -s)-$$(uname -m)" in \
Linux-x86_64) PLATFORM="x86_64-linux" ;; \
Linux-aarch64) PLATFORM="aarch64-linux" ;; \
Darwin-x86_64) PLATFORM="x86_64-darwin" ;; \
Darwin-arm64) PLATFORM="aarch64-darwin" ;; \
*) echo "Unsupported platform: $$(uname -s)-$$(uname -m)"; exit 1 ;; \
esac; \
INSTALLER_URL="https://github.com/NixOS/nix-installer/releases/download/$(NIX_INSTALLER_VERSION)/nix-installer-$$PLATFORM"; \
echo "Platform: $$PLATFORM"; \
echo "Downloading from: $$INSTALLER_URL"; \
max_attempts=3; \
attempt=1; \
while [ $$attempt -le $$max_attempts ]; do \
echo "Attempt $$attempt of $$max_attempts..."; \
if curl --proto '=https' --tlsv1.2 -sSf -L --retry 3 --retry-delay 5 \
"$$INSTALLER_URL" -o /tmp/nix-installer && chmod +x /tmp/nix-installer; then \
/tmp/nix-installer install --no-confirm \
--extra-conf "trusted-users = root @admin @wheel" && break; \
fi; \
attempt=$$((attempt + 1)); \
if [ $$attempt -le $$max_attempts ]; then \
echo "Download or install failed, waiting 10 seconds before retry..."; \
sleep 10; \
fi; \
done; \
if [ $$attempt -gt $$max_attempts ]; then \
echo "Failed to install nix after $$max_attempts attempts"; \
exit 1; \
fi; \
fi
.PHONY: install-direnv
install-direnv: ## Install direnv (requires nix to be installed first)
@echo "Installing direnv..."
@if command -v direnv >/dev/null 2>&1; then \
echo "direnv is already installed."; \
else \
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#direnv; \
fi
@echo ""
@echo "See https://direnv.net/docs/hook.html if you would like to add direnv to your shell"
#-------
##@ verify
#-------
.PHONY: verify
verify: ## Verify nix installation and environment setup
@printf "\nVerifying installation...\n\n"
@printf "Checking nix installation: "
@if command -v nix >/dev/null 2>&1; then \
printf "● nix found at %s\n" "$$(command -v nix)"; \
nix --version; \
else \
printf "⊘ nix not found\n"; \
printf "Run 'make install-nix' to install nix\n"; \
exit 1; \
fi
@printf "\nChecking nix flakes support: "
@if nix flake --help >/dev/null 2>&1; then \
printf "● flakes enabled\n"; \
else \
printf "⊘ flakes not enabled\n"; \
exit 1; \
fi
@printf "\nChecking direnv installation: "
@if command -v direnv >/dev/null 2>&1; then \
printf "● direnv found\n"; \
else \
printf "⚠️ direnv not found (optional but recommended)\n"; \
printf "Run 'make install-direnv' to install\n"; \
fi
@printf "\nChecking flake validity: "
@if nix flake metadata . >/dev/null 2>&1; then \
printf "● flake is valid\n"; \
else \
printf "⊘ flake has errors\n"; \
exit 1; \
fi
@printf "\nChecking required tools in devShell: "
@if nix develop --command bash -c 'command -v just && command -v python && command -v uv && command -v pixi && command -v ruff' >/dev/null 2>&1; then \
printf "● just, python, uv, pixi, ruff available\n"; \
else \
printf "⊘ some tools missing from devShell\n"; \
exit 1; \
fi
@printf "\n/etc/nix/nix.conf:\n"
@printf "==================\n"
@cat /etc/nix/nix.conf 2>/dev/null || printf "(file not found)\n"
@printf "==================\n"
@if [ -f /etc/nix/nix.custom.conf ]; then \
printf "\n/etc/nix/nix.custom.conf:\n"; \
printf "==================\n"; \
cat /etc/nix/nix.custom.conf; \
printf "==================\n"; \
fi
@printf "\n● All verification checks passed!\n\n"
#-------
##@ setup
#-------
.PHONY: setup-user
setup-user: ## Generate age key for sops-nix secrets (first time user setup)
@printf "\nGenerating age key for secrets management...\n\n"
@. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && \
if [ -f ~/.config/sops/age/keys.txt ]; then \
printf "⚠️ Age key already exists at ~/.config/sops/age/keys.txt\n"; \
printf "To regenerate, manually delete the file first\n"; \
printf "\nYour public key is:\n"; \
nix shell nixpkgs#age -c age-keygen -y ~/.config/sops/age/keys.txt 2>/dev/null || printf "Error reading existing key\n"; \
else \
mkdir -p ~/.config/sops/age; \
nix shell nixpkgs#age -c age-keygen -o ~/.config/sops/age/keys.txt; \
chmod 600 ~/.config/sops/age/keys.txt; \
printf "\n● Age key generated successfully!\n\n"; \
printf "Your public key is:\n"; \
nix shell nixpkgs#age -c age-keygen -y ~/.config/sops/age/keys.txt; \
printf "\n⚠️ IMPORTANT: Back up your private key to Bitwarden!\n"; \
printf "1. Copy the content of ~/.config/sops/age/keys.txt\n"; \
printf "2. Store in Bitwarden as secure note: 'age-key-<username>'\n"; \
printf "3. Send your PUBLIC key (shown above) to the admin\n"; \
printf "\nSee docs/new-user-host.md for complete setup instructions\n"; \
fi
.PHONY: check-secrets
check-secrets: ## Check if you can decrypt shared secrets (requires age key and admin setup)
@printf "\nChecking secrets access...\n\n"
@if [ ! -f ~/.config/sops/age/keys.txt ]; then \
printf "⊘ No age key found. Run 'make setup-user' first\n"; \
exit 1; \
fi
@if [ -f secrets/shared.yaml ]; then \
if nix develop --command sops -d secrets/shared.yaml >/dev/null 2>&1; then \
printf "● Successfully decrypted shared secrets!\n"; \
printf "You have proper access to the secrets system\n"; \
else \
printf "⊘ Cannot decrypt shared secrets\n"; \
printf "Possible reasons:\n"; \
printf "1. Admin hasn't added your key to .sops.yaml yet\n"; \
printf "2. Admin hasn't run 'sops updatekeys' after adding you\n"; \
printf "3. Your age key is incorrect\n"; \
printf "\nSend your public key to admin:\n"; \
age-keygen -y ~/.config/sops/age/keys.txt; \
exit 1; \
fi; \
else \
printf "No secrets/shared.yaml found. Secrets not yet configured for this project.\n"; \
fi
#-------
##@ clean
#-------
.PHONY: clean
clean: ## Clean any temporary files or build artifacts
@echo "Cleaning up..."
@rm -rf result result-*