-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjustfile
More file actions
328 lines (266 loc) · 11.2 KB
/
justfile
File metadata and controls
328 lines (266 loc) · 11.2 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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
set dotenv-load := false
compose := "docker compose"
backend_env := "if [ ! -f .env ]; then cp .env.example .env; fi"
backend_venv := "uv sync --frozen"
backend_python := ".venv/bin/python"
backend_pants := "pants"
backend_test_pants := "pants --process-execution-local-parallelism=4"
backend_pants_targets := "::"
backend_python_targets := "conftest.py manage.py content core digest_engine entities ingestion messaging newsletters notifications pipeline projects trends users tests"
frontend_env := "if [ ! -f frontend/.env.local ]; then cp frontend/.env.example frontend/.env.local; fi"
pnpm_setup := "corepack enable && corepack prepare pnpm@11.1.0 --activate"
pnpm_exec := "pnpm"
turbo_exec := "pnpm turbo"
frontend_filter := "--filter=@digestengine/frontend"
django_manage := "docker compose exec django python manage.py"
host_backend_test_env := "uv sync --frozen && set -a && . ./.env.test && set +a &&"
# -----------------------------------------------------------------------------
# Setup
# -----------------------------------------------------------------------------
# Install backend Python dependencies and initialize the root env file
backend-install:
@{{backend_env}}
@command -v pants >/dev/null 2>&1 || { echo "Pants is required. Install it from https://www.pantsbuild.org/stable/docs/getting-started/installing-pants"; exit 1; }
@uv python install 3.13
@uv sync --frozen
# Bootstrap a fresh clone with uv, pnpm, env files, and git hooks
bootstrap:
@bash scripts/bootstrap_dev.sh
# Ensure pnpm is enabled, then install frontend dependencies
frontend-install:
@{{frontend_env}}
@{{pnpm_setup}}
@{{pnpm_exec}} install {{frontend_filter}}
# Install pre-commit hooks when running inside a git checkout
install-hooks:
@if git rev-parse --git-dir >/dev/null 2>&1; then {{backend_venv}} && {{backend_python}} -m pre_commit install --install-hooks; fi
# Install backend, frontend, and git hook dependencies
install: backend-install frontend-install install-hooks
# Remove generated caches, coverage output, and frontend build artifacts
clean:
@find . \
\( -path './.git' -o -path './.venv' -o -path './node_modules' -o -path './frontend/node_modules' \) -prune -o \
-type d \( -name '__pycache__' -o -name '.pytest_cache' -o -name '.ruff_cache' \) -exec rm -rf {} +
@rm -rf .coverage .turbo htmlcov frontend/.next frontend/coverage frontend/storybook-static frontend/node_modules/.cache
# -----------------------------------------------------------------------------
# Development And Builds
# -----------------------------------------------------------------------------
# App development tasks stay separate between the backend stack and the product frontend.
# Start the backend development stack with Django, workers, and dependencies
backend-dev:
@{{backend_env}}
@{{compose}} up django celery-worker celery-beat postgres redis qdrant nginx
# Start only the app frontend development server
frontend-dev:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run dev {{frontend_filter}}
# Start Storybook for local frontend component development
storybook-dev:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run storybook {{frontend_filter}}
# Build the static Storybook site for production
storybook-build:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run build-storybook {{frontend_filter}}
# Start the full local docker-compose development stack
dev:
@{{backend_env}}
@{{compose}} up
# Build the backend Docker image used by the local stack
backend-build:
@DOCKER_BUILDKIT=0 docker compose build django
# Build the frontend production bundle
frontend-build:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run build {{frontend_filter}}
# Build the frontend TypeScript application through Turbo
typescript-build:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run build
# Build both backend and frontend deliverables
build: backend-build typescript-build
# -----------------------------------------------------------------------------
# Quality Checks
# -----------------------------------------------------------------------------
# Run the frontend TypeScript typecheck
frontend-typecheck:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run typecheck
# Lint and validate the backend Python and template code
backend-lint:
@{{backend_venv}}
@{{backend_pants}} lint {{backend_pants_targets}}
@{{backend_python}} -m djlint core/templates --check
@{{host_backend_test_env}} {{backend_pants}} check {{backend_pants_targets}}
@{{backend_python}} -m pre_commit run --all-files check-yaml
@{{host_backend_test_env}} {{backend_python}} manage.py check
# Lint and typecheck the frontend TypeScript app
frontend-lint:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run typecheck lint lint:style {{frontend_filter}}
# Run all lint and validation tasks
lint: backend-lint frontend-lint helm-lint
# Auto-fix backend lint issues where supported, then re-run backend validation
backend-lint-fix:
@{{backend_venv}}
@{{backend_python}} -m ruff check {{backend_python_targets}} --fix
@{{backend_python}} -m djlint core/templates --reformat
@{{backend_python}} -m pre_commit run --all-files end-of-file-fixer
@{{backend_python}} -m pre_commit run --all-files trailing-whitespace
@just backend-lint
# Auto-fix frontend lint issues where supported
frontend-lint-fix:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run lint:fix lint:style:fix {{frontend_filter}}
# Run all available lint auto-fixes
lint-fix: backend-lint-fix frontend-lint-fix
# Format frontend source files with Prettier
frontend-format:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run format
# Check frontend formatting without modifying files
frontend-format-check:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run format:check
# Run the frontend test suite
frontend-test:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run test:run {{frontend_filter}}
# Run Storybook browser tests for frontend components
frontend-storybook-test:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run test:storybook {{frontend_filter}}
# Run the complete frontend test suite including Storybook browser tests
frontend-test-all:
@{{frontend_env}}
@{{pnpm_setup}}
@{{turbo_exec}} run test:all
# Run the backend test suite
backend-test:
@{{host_backend_test_env}} {{backend_test_pants}} test {{backend_pants_targets}}
# Run backend tests with terminal coverage output
backend-test-coverage:
@{{host_backend_test_env}} {{backend_test_pants}} test --use-coverage {{backend_pants_targets}}
# Generate backend HTML coverage output
backend-test-coverage-html:
@{{host_backend_test_env}} {{backend_test_pants}} --coverage-py-report='["console", "html"]' test --use-coverage {{backend_pants_targets}}
# Run the main backend and frontend test suites
test: backend-test frontend-test
# -----------------------------------------------------------------------------
# Compose Runtime
# -----------------------------------------------------------------------------
# Start the full docker-compose stack in the foreground
up:
@{{backend_env}}
@{{compose}} up
# Start the full docker-compose stack in detached mode
up-detached:
@{{backend_env}}
@{{compose}} up -d
# Stop the full docker-compose stack
stop:
@{{backend_env}}
@{{compose}} down
# Rebuild and restart the full docker-compose stack
restart:
@{{backend_env}}
@{{compose}} down
@{{compose}} up --build
# Restart the full docker-compose stack without rebuilding images
restart-no-build:
@{{backend_env}}
@{{compose}} down
@{{compose}} up
# Rebuild and restart only the Django service
restart-django:
@{{backend_env}}
@{{compose}} build django
@{{compose}} up -d django
# Reset local docker volumes and remove orphaned containers
reset-volumes:
@{{backend_env}}
@{{compose}} down -v --remove-orphans
# -----------------------------------------------------------------------------
# Django And Data Tasks
# -----------------------------------------------------------------------------
# Create a Django superuser in the running backend container
createsuperuser:
@{{backend_env}}
@{{compose}} exec django python manage.py createsuperuser
# Change the password for a Django user in the running backend container
changepassword username:
@{{backend_env}}
@{{compose}} exec django python manage.py changepassword {{username}}
# Apply Django database migrations in the running backend container
migrate:
@{{backend_env}}
@{{django_manage}} migrate
# Seed demo data into the running backend container
seed:
@{{backend_env}}
@{{compose}} exec django python manage.py seed_demo
# Bootstrap RSS and Reddit source configs for one project in the running backend container
bootstrap-live-sources project_id:
@{{backend_env}}
@{{django_manage}} bootstrap_live_sources \
--project-id {{project_id}} \
${RSS_FEEDS:+--rss-feed "$RSS_FEEDS"} \
${SUBREDDITS:+--subreddit "$SUBREDDITS"} \
${REDDIT_LISTING:+--reddit-listing "$REDDIT_LISTING"} \
${REDDIT_LIMIT:+--reddit-limit "$REDDIT_LIMIT"} \
${RUN_NOW:+--run-now}
# Sync embeddings for all eligible content in the running backend container
embed-all:
@{{backend_env}}
@{{django_manage}} sync_embeddings
# Sync embeddings for a single project in the running backend container
embed-project project_id:
@{{backend_env}}
@{{django_manage}} sync_embeddings --project-id {{project_id}}
# Run the embedding smoke test across the default sample content in the running backend container
embed-smoke:
@{{backend_env}}
@{{django_manage}} embedding_smoke
# Run the embedding smoke test for a single content item in the running backend container
embed-smoke-content content_id:
@{{backend_env}}
@{{django_manage}} embedding_smoke --content-id {{content_id}}
# Open a Django shell in the running backend container
shell:
@{{backend_env}}
@{{django_manage}} shell
# Run the staged disaster recovery rehearsal workflow against the configured cluster
disaster-recovery-rehearsal:
@{{backend_env}}
@bash scripts/disaster_recovery_rehearsal.sh
# -----------------------------------------------------------------------------
# Helm And Kubernetes
# -----------------------------------------------------------------------------
# Lint the Helm chart configuration
helm-lint:
@helm lint deploy/helm/digest-engine
# Render the Helm chart to a temporary output file
helm-template:
@helm template digest-engine deploy/helm/digest-engine -f deploy/helm/digest-engine/values-minikube.yaml > /tmp/digest-engine-helm-template.yaml
# Build and load the local image into Minikube
k8s-build-minikube:
@DOCKER_BUILDKIT=1 docker build -t digest-engine:minikube -f docker/web/Dockerfile .
@minikube image load digest-engine:minikube
# Install or upgrade the Helm release in Minikube
k8s-install-minikube:
@helm upgrade --install digest-engine ./deploy/helm/digest-engine -f ./deploy/helm/digest-engine/values-minikube.yaml
# Uninstall the Helm release from Minikube
k8s-uninstall-minikube:
@helm uninstall digest-engine || true