-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjustfile
322 lines (263 loc) · 9.02 KB
/
justfile
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
# List all recipes
default:
@just --list
# Contents (alphabetical)
## CI/CD
## Conda package
## Monorepo
## Nix
## Python package
## Secrets
## Template
## CI/CD
# Set gcloud context
[group('CI/CD')]
gcloud-context:
gcloud config configurations activate "$GCP_PROJECT_NAME"
# Update github vars for repo from environment variables
[group('CI/CD')]
ghvars repo="sciexp/python-nix-template":
@echo "vars before updates:"
@echo
PAGER=cat gh variable list --repo={{ repo }}
@echo
gh variable set CACHIX_CACHE_NAME --repo={{ repo }} --body="$CACHIX_CACHE_NAME"
gh variable set FAST_FORWARD_ACTOR --repo={{ repo }} --body="$FAST_FORWARD_ACTOR"
@echo
@echo "vars after updates (wait 3 seconds for github to update):"
sleep 3
@echo
PAGER=cat gh variable list --repo={{ repo }}
# Update github secrets for repo from environment variables
[group('CI/CD')]
ghsecrets repo="sciexp/python-nix-template":
@echo "secrets before updates:"
@echo
PAGER=cat gh secret list --repo={{ repo }}
@echo
eval "$(teller sh)" && \
gh secret set CACHIX_AUTH_TOKEN --repo={{ repo }} --body="$CACHIX_AUTH_TOKEN" && \
gh secret set CODECOV_TOKEN --repo={{ repo }} --body="$CODECOV_TOKEN" && \
gh secret set FAST_FORWARD_PAT --repo={{ repo }} --body="$FAST_FORWARD_PAT" && \
gh secret set GITGUARDIAN_API_KEY --repo={{ repo }} --body="$GITGUARDIAN_API_KEY" && \
gh secret set UV_PUBLISH_TOKEN --repo={{ repo }} --body="$UV_PUBLISH_TOKEN"
@echo
@echo "secrets after updates (wait 3 seconds for github to update):"
sleep 3
@echo
PAGER=cat gh secret list --repo={{ repo }}
# Run pre-commit hooks (see pre-commit.nix and note the yaml is git-ignored)
[group('CI/CD')]
pre-commit:
pre-commit run --all-files
## Conda package
# Package commands (conda)
[group('conda package')]
conda-build package="python-nix-template":
pixi build --manifest-path=packages/{{package}}/pyproject.toml
# Create and sync conda environment with pixi
[group('conda package')]
conda-env package="python-nix-template":
pixi install --manifest-path=packages/{{package}}/pyproject.toml
@echo "Conda environment is ready. Activate it with 'pixi shell'"
# Update pixi lockfile
[group('conda package')]
pixi-lock package="python-nix-template":
pixi list --manifest-path=packages/{{package}}/pyproject.toml
pixi tree --manifest-path=packages/{{package}}/pyproject.toml
# Update conda environment
[group('conda package')]
conda-lock package="python-nix-template":
pixi project export conda-explicit-spec packages/{{package}}/conda/ --manifest-path=packages/{{package}}/pyproject.toml --ignore-pypi-errors
# Run tests in conda environment with pixi
[group('conda package')]
conda-test package="python-nix-template":
pixi run -e test --manifest-path=packages/{{package}}/pyproject.toml pytest
# Run linting in conda environment with pixi
[group('conda package')]
conda-lint package="python-nix-template":
pixi run -e lint --manifest-path=packages/{{package}}/pyproject.toml ruff check src/
# Run linting and fix errors in conda environment with pixi
[group('conda package')]
conda-lint-fix package="python-nix-template":
pixi run -e lint --manifest-path=packages/{{package}}/pyproject.toml ruff check --fix src/
# Run type checking in conda environment with pixi
[group('conda package')]
conda-type package="python-nix-template":
pixi run -e types --manifest-path=packages/{{package}}/pyproject.toml pyright src/
# Run all checks in conda environment (lint, type, test)
[group('conda package')]
conda-check package="python-nix-template": (conda-lint package) (conda-type package) (conda-test package)
@printf "\n\033[92mAll conda checks passed!\033[0m\n"
## Nix
# Enter the Nix development shell
[group('nix')]
dev:
nix develop
# Validate the Nix flake configuration
[group('nix')]
flake-check:
nix flake check
# Update all flake inputs to their latest versions
[group('nix')]
flake-update:
nix flake update
# Run CI checks locally with `om ci`
[group('nix')]
ci:
om ci
# Build development container image
[group('nix')]
container-build-dev:
nix build .#devcontainerImage
# Run development container with port 8888 exposed
[group('nix')]
container-run-dev:
docker load < $(nix build .#devcontainerImage --print-out-paths)
docker run -it --rm -p 8888:8888 mypackage-dev:latest
# Build production container image
[group('nix')]
container-build:
nix build .#containerImage
# Run production container with port 8888 exposed
[group('nix')]
container-run:
docker load < $(nix build .#containerImage --print-out-paths)
docker run -it --rm -p 8888:8888 mypackage:latest
## Python package
# Package commands
[group('python package')]
uv-build: _ensure-venv
uv build
# Sync and enter uv virtual environment
[group('python package')]
venv: _ensure-venv
uv sync
@echo "Virtual environment is ready. Activate it with 'source .venv/bin/activate'"
# Update lockfile from pyproject.toml
[group('python package')]
uv-lock: _ensure-venv
uv lock
# Run tests
[group('python package')]
test:
pytest
# Run tests in uv virtual environment
[group('python package')]
uv-test: _ensure-venv
uv run pytest
# Run linting
[group('python package')]
lint:
ruff check src/
# Run linting in uv virtual environment
[group('python package')]
uv-lint: _ensure-venv
uvx ruff check src/
# Run linting and fix errors
[group('python package')]
lint-fix:
ruff check --fix src/
# Run linting and fix errors in uv virtual environment
[group('python package')]
uv-lint-fix: _ensure-venv
uvx ruff check --fix src/
# Run type checking in uv virtual environment
[group('python package')]
type:
pyright src/
# Run type checking in uv virtual environment
[group('python package')]
uv-type: _ensure-venv
uv run pyright src/
# Run all checks (lint, type, test)
[group('python package')]
check: lint type test
@printf "\n\033[92mAll checks passed!\033[0m\n"
# Helper recipes
_ensure-venv:
#!/usr/bin/env bash
if [ ! -d ".venv" ]; then
uv venv
fi
## Secrets
# Define the project variable
gcp_project_id := env_var_or_default('GCP_PROJECT_ID', 'development')
# Show existing secrets
[group('secrets')]
show:
@teller show
# Create a secret with the given name
[group('secrets')]
create-secret name:
@gcloud secrets create {{name}} --replication-policy="automatic" --project {{gcp_project_id}}
# Populate a single secret with the contents of a dotenv-formatted file
[group('secrets')]
populate-single-secret name path:
@gcloud secrets versions add {{name}} --data-file={{path}} --project {{gcp_project_id}}
# Populate each line of a dotenv-formatted file as a separate secret
[group('secrets')]
populate-separate-secrets path:
@grep -v '^[[:space:]]*#' {{path}} | while IFS= read -r line; do \
KEY=$(echo $line | cut -d '=' -f 1); \
VALUE=$(echo $line | cut -d '=' -f 2); \
gcloud secrets create $KEY --replication-policy="automatic" --project {{gcp_project_id}} 2>/dev/null; \
printf "$VALUE" | gcloud secrets versions add $KEY --data-file=- --project {{gcp_project_id}}; \
done
# Complete process: Create a secret and populate it with the entire contents of a dotenv file
[group('secrets')]
create-and-populate-single-secret name path:
@just create-secret {{name}}
@just populate-single-secret {{name}} {{path}}
# Complete process: Create and populate separate secrets for each line in the dotenv file
[group('secrets')]
create-and-populate-separate-secrets path:
@just populate-separate-secrets {{path}}
# Retrieve the contents of a given secret
[group('secrets')]
get-secret name:
@gcloud secrets versions access latest --secret={{name}} --project={{gcp_project_id}}
# Create empty dotenv from template
[group('secrets')]
seed-dotenv:
@cp .template.env .env
# Export unique secrets to dotenv format
[group('secrets')]
export:
@teller export env | sort | uniq | grep -v '^$' > .secrets.env
# Check secrets are available in teller shell.
[group('secrets')]
check-secrets:
@printf "Check teller environment for secrets\n\n"
@teller run -s -- env | grep -E 'GITHUB|CACHIX' | teller redact
## Template
# Initialize new project from template
[group('template')]
template-init:
echo "Use: nix --accept-flake-config run github:juspay/omnix -- init github:sciexp/python-nix-template -o new-python-project"
# Verify template functionality by creating and checking a test project
[group('template')]
template-verify:
om init -t .#default ./tmp-verify-template
cd ./tmp-verify-template && nix flake check
rm -rf ./tmp-verify-template
# Release testing with yarn
[group('release')]
test-release:
yarn test-release
# Test release as if on main branch
[group('release')]
test-release-as-main:
yarn test-release:main
# Test release with explicit branch override
[group('release')]
test-release-on-current-branch:
yarn test-release:current
# Test release directly on release branch
[group('release')]
test-release-direct:
yarn test-release:direct
# Test package release
[group('release')]
test-package-release package-name="python-nix-template" branch="main":
yarn workspace {{package-name}} test-release -b {{branch}}