-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathjustfile
More file actions
557 lines (450 loc) · 17 KB
/
Copy pathjustfile
File metadata and controls
557 lines (450 loc) · 17 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
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# Runtime tags describe warm, incremental runs on a development machine:
# - [quick]: normally finishes within one minute
# - [bounded]: normally finishes within five minutes
# - [long]: may take longer than five minutes
# - [indefinite]: keeps running until stopped
# - [external]: completion depends on a device, network service, or user interaction
# - [variable]: runtime depends on the arguments passed to the wrapper
# Cold caches can move quick commands into bounded and bounded commands into long
# [quick] List available recipes
[default]
list:
@just --list
# ------------------------------------------------------------------------------
# utilities
# ------------------------------------------------------------------------------
# [variable] Run an xtask command
[group('utils')]
xtask *args:
cd rust && cargo --locked xtask {{ args }}
# [bounded] Rebase current branch onto new-base after choosing the old squash-merged base
[group('utils')]
rebase new_base="master":
just xtask rebase "{{ new_base }}"
# Requires MNEMONIC env var (set in .envrc or pass directly)
# [quick, external] Sign a PSBT and output all formats (base64, hex, binary, bbqr-gif, ur-gif)
[group('utils')]
[script('bash')]
sign-psbt psbt:
set -e
if [ -z "$MNEMONIC" ]; then
echo "Error: MNEMONIC env var not set. Set it in .envrc or export it."
exit 1
fi
OUTPUT_DIR="$HOME/Downloads/signed-psbt-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUTPUT_DIR"
echo "Signing PSBT and outputting to: $OUTPUT_DIR"
cd rust
cargo --locked xtask util sign-psbt --psbt "{{ psbt }}" -f base64 -O "$OUTPUT_DIR/signed.base64.txt"
cargo --locked xtask util sign-psbt --psbt "{{ psbt }}" -f hex -O "$OUTPUT_DIR/signed.hex.txt"
cargo --locked xtask util sign-psbt --psbt "{{ psbt }}" -f binary -O "$OUTPUT_DIR/signed.psbt"
cargo --locked xtask util sign-psbt --psbt "{{ psbt }}" -f bbqr-gif -O "$OUTPUT_DIR/signed-bbqr.gif"
cargo --locked xtask util sign-psbt --psbt "{{ psbt }}" -f ur-gif -O "$OUTPUT_DIR/signed-ur.gif"
echo ""
echo "All formats saved to: $OUTPUT_DIR"
ls -la "$OUTPUT_DIR"
open "$OUTPUT_DIR"
alias sp := sign-psbt
# ------------------------------------------------------------------------------
# ci
# ------------------------------------------------------------------------------
# [long] Full build and verification for all platforms
[group('ci')]
full:
just bidd && just ba && just ci && just compile
alias f := full
# [long] Run all CI checks
[group('ci')]
[script('bash')]
[working-directory('rust')]
ci:
set -e
just fmt
cargo fmt --check
just lint
just compile
just test
# [external] Regenerate UniFFI bindings in GitHub Actions for committed branch changes
[group('ci')]
regenerate-bindings:
just xtask regenerate-bindings
alias rb := regenerate-bindings
# [variable, external] Run mobile artifact producer or consumer commands
[group('ci')]
mobile-artifact *args:
just xtask mobile-artifact {{ args }}
# [external] Trigger Android and iOS mobile artifacts for a pushed ref
[group('ci')]
mobile-artifact-trigger ref platform="both":
just mobile-artifact trigger --platform "{{ platform }}" --ref "{{ ref }}"
# [external] Install latest matching Android mobile artifact
[group('ci')]
mobile-artifact-install-android ref:
just mobile-artifact install-android --ref "{{ ref }}"
# [external] Fetch latest matching iOS CoveCore mobile artifact
[group('ci')]
mobile-artifact-fetch-ios-core ref:
just mobile-artifact fetch-ios-core --ref "{{ ref }}"
# ------------------------------------------------------------------------------
# build
# ------------------------------------------------------------------------------
# [bounded] Build Android debug Rust FFI and Kotlin bindings for ARM64 devices
[group('build')]
build-android:
just xtask build-android debug --arm64 && just say "done android"
alias ba := build-android
# [bounded, external] Build Android debug Rust FFI and Kotlin bindings for the connected device ABI
[group('build')]
build-android-connected-device:
just xtask build-android debug --connected-device && just say "done android connected device"
alias bad := build-android-connected-device
# [long] Build Android release APK
[group('build')]
build-android-release:
just xtask build-android release-speed && just say "done android release"
alias bar := build-android-release
# [long, external] Build signed AAB for Google Play, copy to Downloads
[group('build')]
bundle-android: build-android-release
just xtask bundle-android && just say "done android bundle"
alias bua := bundle-android
# [long] Build iOS debug for simulator
[group('build')]
build-ios profile="debug" *flags="":
just xtask build-ios {{ profile }} {{ flags }} && just say "done ios"
alias bi := build-ios
# [long] Build iOS release for device
[group('build')]
build-ios-release:
just xtask build-ios release-speed --device && just say "done ios release"
alias bir := build-ios-release
# keep this path aligned with Xcode archives; passkeys fail in TestFlight if CLI signing diverges
# xtask verifies Apple's AASA CDN before upload
# [long, external] Bump iOS build, build release bindings, then upload to TestFlight
[group('build')]
testflight:
just xtask testflight
# [long] Build iOS debug for device
[group('build')]
build-ios-debug-device:
just xtask build-ios debug --device && just say "done ios device"
alias bidd := build-ios-debug-device
alias gen-swift := build-ios
# [long] Compile both iOS and Android
[group('build')]
@compile:
just compile-ios && just compile-android
# [bounded] Compile iOS for simulator
[group('build')]
[working-directory('ios')]
compile-ios:
xcodebuild -scheme Cove -sdk iphonesimulator -arch arm64 build && just notf "done compile ios"
# [bounded] Compile Android debug
[group('build')]
[working-directory('android')]
compile-android:
./gradlew assembleDevDebug && just notf "done compile android"
# ------------------------------------------------------------------------------
# test
# ------------------------------------------------------------------------------
# [external] Run iOS and Android manual UI tests
[group('test')]
ui-manual:
just android-ui-manual && just ios-ui-background
# Use this for ad hoc device UI testing:
# just android-stay-awake ./gradlew :app:connectedUiTestDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation=org.bitcoinppl.cove.test.LayoutRegressionTest
#
# Focused instrumentation tests should use AndroidDeviceStayAwakeRule when the
# stay-awake behavior belongs in the test itself
# [variable, external] Run an Android device command from android/ with stay-awake enabled
[group('test')]
android-stay-awake *command:
just xtask android-stay-awake -- {{ command }}
# [external] Run manual Android full-launch onboarding UI tests
[group('test')]
android-ui-manual:
just xtask android-ui-manual
alias aum := android-ui-manual
# [bounded] Update Android Compose preview screenshot references
[group('test')]
[working-directory('android')]
android-preview-screenshots-update:
./gradlew :app:updateDevDebugScreenshotTest
# [bounded] Validate Android Compose preview screenshots
[group('test')]
[working-directory('android')]
android-preview-screenshots-validate:
./gradlew :app:validateDevDebugScreenshotTest
# [external] Run manual iOS full-launch UI tests without opening Simulator
[group('test')]
[script('bash')]
ios-ui-background device="iPhone 17" test="CoveUITests/OnboardingFullLaunchUITests":
cd rust && cargo build --locked --package xtask -q && ./target/debug/xtask ios-ui --device "{{ device }}" --test "{{ test }}"
alias iub := ios-ui-background
# [external] Run manual iOS full-launch UI tests with Simulator visible
[group('test')]
[script('bash')]
ios-ui-foreground device="iPhone 17" test="CoveUITests/OnboardingFullLaunchUITests":
cd rust && cargo build --locked --package xtask -q && ./target/debug/xtask ios-ui --foreground --device "{{ device }}" --test "{{ test }}"
alias iuf := ios-ui-foreground
# [bounded] Run all tests
[group('test')]
[working-directory('rust')]
test test="" flags="":
cargo nextest run --locked {{ test }} --workspace {{ flags }}
# [bounded] Run tests the same way as GitHub Actions
[group('test')]
[working-directory('rust')]
test-gh test="" flags="":
cargo test --locked {{ test }} --workspace {{ flags }}
# [bounded] Run tests with cargo test
[group('test')]
[working-directory('rust')]
ctest test="" flags="":
cargo test --locked {{ test }} --workspace -- {{ flags }}
# [indefinite] Run tests with bacon
[group('test')]
[working-directory('rust')]
btest test="":
bacon nextest -- {{ test }} --workspace
# [indefinite] Watch and re-run tests on file changes
[group('test')]
watch-test test="" flags="":
watchexec --exts rs just test {{ test }} {{ flags }}
alias wt := watch-test
alias wtest := watch-test
# ------------------------------------------------------------------------------
# lint
# ------------------------------------------------------------------------------
# [bounded] Lint all platforms
[group('lint')]
@lint *flags="":
just lint-rust {{ flags }} && just lint-swift {{ flags }} && just lint-android {{ flags }}
# [quick] Lint Rust code
[group('lint')]
[working-directory('rust')]
lint-rust *flags="":
cargo clippy --locked --all-targets --all-features -- -D warnings {{ flags }}
# [bounded] Lint Android code
[group('lint')]
[working-directory('android')]
lint-android *flags="":
./gradlew ktlintCheck {{ flags }}
./gradlew detekt
# [bounded] Lint Swift code and Cove-specific SwiftUI structure
[group('lint')]
lint-swift *flags="":
swiftformat --lint ios --swiftversion 6 {{ flags }}
swiftlint lint --config .swiftlint.yml
swift test --package-path tools/cove-swift-lint
swift run --package-path tools/cove-swift-lint cove-swift-lint ios --config .swift-ast-lint.yml
# [quick] Run clippy
[group('lint')]
[working-directory('rust')]
clippy *flags="":
cargo clippy --locked {{ flags }}
# [bounded] Run pedantic clippy checks (excluding must_use, truncation, single_match, if_not_else, needless_continue, option_if_let_else)
[group('lint')]
[working-directory('rust')]
pedantic *flags="":
cargo clippy --locked -- -D clippy::pedantic -D clippy::nursery \
-A clippy::must_use_candidate \
-A clippy::cast_possible_truncation \
-A clippy::single_match \
-A clippy::if_not_else \
-A clippy::needless_continue \
-A clippy::option_if_let_else \
-A clippy::unused_self \
-A clippy::unused_async \
-A clippy::significant_drop_tightening \
-A clippy::missing_const_for_fn \
-A clippy::needless_pass_by_value \
{{ flags }}
# [bounded] Run full pedantic clippy checks without any allows
[group('lint')]
[working-directory('rust')]
pedantic-all *flags="":
cargo clippy --locked -- -D clippy::pedantic -D clippy::nursery {{ flags }}
# ------------------------------------------------------------------------------
# format
# ------------------------------------------------------------------------------
# [quick] Format all platforms
[group('format')]
@fmt:
just fmt-rust && just fmt-swift && just fmt-android
# Format Rust code
[group('format')]
[private]
[working-directory('rust')]
fmt-rust:
cargo fmt --all
# Format Swift code
alias fmt-ios := fmt-swift
alias fi := fmt-swift
[group('format')]
[private]
fmt-swift:
swiftformat ios --swiftversion 6
# Format Android code
[group('format')]
[private]
[working-directory('android')]
fmt-android:
./gradlew ktlintFormat
# ------------------------------------------------------------------------------
# dev
# ------------------------------------------------------------------------------
# [indefinite] Run bacon clippy watcher
[group('dev')]
[working-directory('rust')]
bacon:
bacon clippy
# [indefinite] Run bacon check watcher
[group('dev')]
[working-directory('rust')]
bcheck:
bacon check
# [bounded] Run cargo check
[group('dev')]
[working-directory('rust')]
check *flags="--workspace --all-targets --all-features":
cargo check --locked {{ flags }}
# [indefinite] Watch and rebuild iOS on file changes
[group('dev')]
watch-build profile="debug" *flags="":
watchexec --exts rs just build-ios {{ profile }} {{ flags }}
alias wb := watch-build
# [bounded] Apply cargo fix
[group('dev')]
[working-directory('rust')]
fix *flags="":
cargo fix --locked --workspace {{ flags }}
# ------------------------------------------------------------------------------
# release
# ------------------------------------------------------------------------------
# [quick] Bump version (type: major, minor, patch, build)
[group('release')]
bump type targets="":
just xtask bump-version {{ type }} {{ if targets != "" { "--targets " + targets } else { "" } }}
# ------------------------------------------------------------------------------
# xcode
# ------------------------------------------------------------------------------
# [bounded] Clean Xcode caches
[group('xcode')]
[working-directory('ios')]
xcode-clean:
rm -rf ~/Library/Caches/org.swift.swiftpm
xcodebuild clean
alias xc := xcode-clean
# [long, external] Reset Xcode completely
[confirm("This will kill Xcode and delete caches. Continue?")]
[group('xcode')]
[script('bash')]
[working-directory('ios')]
xcode-reset:
killAll Xcode || true
rm -rf Cove.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
xcrun simctl --set previews delete all
rm -rf ~/Library/Caches/org.swift.swiftpm
rm -rf ~/Library/Developer/Xcode/DerivedData
xcodebuild clean
xcode-build-server config -project *.xcodeproj -scheme Cove
open Cove.xcodeproj
alias xr := xcode-reset
# ------------------------------------------------------------------------------
# util
# ------------------------------------------------------------------------------
# [bounded] Clean all build artifacts
[confirm("Delete all build artifacts?")]
[group('util')]
[script('bash')]
[working-directory('rust')]
clean:
cargo clean
rm -rf ../ios/Cove.xcframework
rm -rf ../ios/Cove
rm -rf target
# [external] Update cargo dependencies
[group('util')]
[working-directory('rust')]
update pkg="":
cargo update {{ pkg }}
# [external] Run Android app
# repeat targets as needed: -D main -D sim
[group('util')]
run-android *args:
just xtask run-android {{ args }} && just notf "done run android"
alias ra := run-android
# [long, external] Rebuild Android bindings, then install and run the Android app
# repeat targets as needed: -D main -D sim
[group('util')]
build-run-android *args:
just ba && just ra {{ args }}
alias bra := build-run-android
# [long, external] Rebuild, install, and run iOS and Android apps
# repeat targets as needed: -d main -d se -D main -D sim
[group('util')]
build-run-all *args:
just xtask build-run-all {{ args }} && just notf "done build run all"
alias brall := build-run-all
# [quick, external] Launch installed Android app
[group('util')]
launch-android:
adb shell am start -W -n org.bitcoinppl.cove.dev/org.bitcoinppl.cove.MainActivity
alias la := launch-android
# [quick, external] Clear Android app data and launch installed app
[group('util')]
reset-run-android:
just reset-android
just launch-android
# [quick, external] Clear Android app data
[group('util')]
reset-android:
adb shell pm clear org.bitcoinppl.cove.dev
alias rra := reset-run-android
alias rea := reset-android
# [quick, external] Download Android screenshots into _scratch and delete them from the device
[group('util')]
download-android-screenshots:
just xtask download-android-screenshots
alias das := download-android-screenshots
# [long, external] Build and clean install Android (rebuilds native libs, clears Gradle cache)
[group('util')]
[working-directory('android')]
install-android-clean:
just ba && ./gradlew --stop && ./gradlew clean installDebug && just notf "done install android clean"
alias iac := install-android-clean
# [external] Run iOS app with existing generated bindings
# repeat targets as needed: -d main -d se
[group('util')]
run-ios *args:
just xtask run-ios {{ args }} && just notf "done run ios"
alias ri := run-ios
# [long, external] Rebuild iOS bindings, then install and run the iOS app
# repeat targets as needed: -d main -d se
[group('util')]
build-run-ios *args:
just xtask build-run-ios {{ args }} && just notf "done build run ios"
alias bri := build-run-ios
alias ib := build-run-ios
# [indefinite, external] Show logcat for Cove process
[group('util')]
logcat:
#!/usr/bin/env bash
pid=$(adb shell pidof org.bitcoinppl.cove.dev | tr -d '[:space:]')
if [ -z "$pid" ]; then
echo "error: org.bitcoinppl.cove.dev is not running" >&2
exit 1
fi
adb logcat --pid="$pid"
# ------------------------------------------------------------------------------
# helpers
# ------------------------------------------------------------------------------
# text-to-speech helper
[private]
say *args:
@say {{ args }} 2>/dev/null || echo {{ args }} || true
@just notf {{ args }} || true
[private]
notf *args:
@command -v notf >/dev/null && notf "{{ args }}" -t "Cove" -T bell,macos || true