Skip to content

Commit c7fc6ae

Browse files
authored
Merge pull request #962 from synonymdev/chore/add-just
chore: add just launcher
2 parents 25fa61c + d81b5f0 commit c7fc6ae

8 files changed

Lines changed: 287 additions & 44 deletions

File tree

.agents/commands/release.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,13 @@ Print the path to the release notes file so the user can share it for review.
205205
### 7. Build Mainnet Release
206206

207207
```bash
208-
./gradlew assembleMainnetRelease
208+
just release
209209
```
210210

211211
Expected APK path: `app/build/outputs/apk/mainnet/release/bitkit-mainnet-release-{newVersionCode}-universal.apk`
212+
Expected AAB path: `app/build/outputs/bundle/mainnetRelease/bitkit-mainnet-release-{newVersionCode}.aab`
212213

213-
Verify the file exists. If the build fails, stop and report the error to the user.
214+
Verify both files exist. If the build fails, stop and report the error to the user.
214215

215216
### 8. Upload APK to Draft Release
216217

.cursor/rules/rules.main.mdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ alwaysApply: true
7575
---
7676

7777
## Rules for Android Unit tests and Instrumentation tests:
78-
- run unit tests for specific files like this: `./gradlew :app:testDevDebugUnitTest --tests "to.bitkit.repositories.LightningRepoTest"`
78+
- run unit tests for specific files like this: `just test file "to.bitkit.repositories.LightningRepoTest"`
7979
- write unit tests in the same style and using same libraries as: `CurrencyRepoTest`, `LightningRepoTest`, `WalletRepoTest`
8080
- in unit tests, use asserts from `kotlin.test` and mockito-kotlin for mocks

.env.example

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copy to .env and uncomment only what you need.
2+
3+
# GITHUB_ACTOR=
4+
# GITHUB_TOKEN=
5+
# TX_TOKEN=
6+
7+
# KEYSTORE_FILE=
8+
# KEYSTORE_PASSWORD=
9+
# KEY_ALIAS=
10+
# KEY_PASSWORD=
11+
12+
# E2E_BACKEND=local
13+
# E2E_HOMEGATE_URL=http://127.0.0.1:6288
14+
15+
# TREZOR_BRIDGE=true
16+
# TREZOR_BRIDGE_URL=http://10.0.2.2:21325

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ local.properties
1818
# Secrets
1919
google-services.json
2020
.env
21+
.env.*
22+
!.env.example
2123
*.keystore
2224
!debug.keystore
2325
keystore.*

AGENTS.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,46 @@ Durable shared agent command specs live in `.agents/commands/`. For PR creation,
1010

1111
```sh
1212
# compile
13-
./gradlew compileDevDebugKotlin
13+
just compile
14+
15+
# Build, install, launch dev app on connected target
16+
just run
1417

1518
# Build for dev
16-
./gradlew assembleDevDebug
19+
just build
1720

1821
# Run unit tests
19-
./gradlew testDevDebugUnitTest
22+
just test
2023

2124
# Run specific unit test file
22-
./gradlew testDevDebugUnitTest --tests LightningRepoTest
25+
just test file LightningRepoTest
2326

2427
# Run instrumented tests
25-
./gradlew connectedDevDebugAndroidTest
28+
just test android
2629

2730
# Build for E2E tests (UI hooks enabled, local Electrum by default)
28-
E2E=true ./gradlew assembleDevRelease
31+
just e2e
2932

3033
# Build for E2E tests with geoblocking disabled
31-
GEO=false E2E=true ./gradlew assembleDevRelease
34+
just e2e no geo
3235

3336
# Build for E2E tests using network Electrum (not local; staging/mainnet based on flavor)
34-
E2E=true E2E_BACKEND=network ./gradlew assembleTnetRelease
37+
just e2e network assembleTnetRelease
3538

3639
# Lint using detekt
37-
./gradlew detekt
40+
just lint
3841

3942
# Auto-format using detekt
40-
./gradlew detekt --auto-correct
43+
just format
4144

4245
# Update detekt baseline
43-
./gradlew detektBaseline
46+
just lint baseline
4447

4548
# Install dev build
46-
./gradlew installDevDebug
49+
just install
4750

4851
# Clean build artifacts
49-
./gradlew clean
52+
just clean
5053
```
5154

5255
## Architecture Overview
@@ -162,7 +165,7 @@ suspend fun getData(): Result<Data> = withContext(Dispatchers.IO) {
162165

163166
- USE coding rules from `.cursor/default.rules.mdc`
164167
- For multi-step changes, stacked PR surgery, and review follow-up with several small edits, batch validation instead of running the full build/check suite after every edit. Run the relevant Gradle checks once the coherent change set is ready, before updating a PR or pushing.
165-
- Still run `./gradlew compileDevDebugKotlin`, `./gradlew testDevDebugUnitTest`, and `./gradlew detekt` before the final PR update/push for code changes, and fix failures before pushing.
168+
- Still run `just compile`, `just test`, and `just lint` before the final PR update/push for code changes, and fix failures before pushing.
166169
- After fixing validation failures, rerun the narrowest useful check that proves the fix. If only test files changed, prefer the targeted test task and a test-focused lint/detekt check when the project tooling supports it; otherwise use the standard detekt task before pushing.
167170
- Use narrower checks earlier only when they answer an immediate risk, e.g. a single unit test after touching focused business logic or a Kotlin compile after a risky refactor.
168171
- ALWAYS ask clarifying questions to ensure an optimal plan when encountering functional or technical uncertainties in requests

Justfile

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
set dotenv-load
2+
set dotenv-filename := ".env"
3+
set windows-shell := ["sh", "-cu"]
4+
5+
gradle := "./gradlew"
6+
7+
default:
8+
@just list
9+
10+
list:
11+
@printf "%s\n" \
12+
"list" \
13+
"init" \
14+
"compile" \
15+
"run" \
16+
"build [TASK]" \
17+
"release" \
18+
"install" \
19+
"test" \
20+
"test file PATTERN" \
21+
"test android" \
22+
"test lane LANE" \
23+
"lint" \
24+
"lint baseline" \
25+
"format" \
26+
"translations pull" \
27+
"translations push source" \
28+
"translations push all" \
29+
"e2e [network|no geo|TASK] [TASK]" \
30+
"changelog [all|next|hotfix]" \
31+
"clean"
32+
33+
init:
34+
#!/usr/bin/env sh
35+
set -eu
36+
37+
if [ -e .env ]; then
38+
echo ".env already exists"
39+
exit 0
40+
fi
41+
42+
cp .env.example .env
43+
echo "Created .env"
44+
45+
compile:
46+
{{ gradle }} compileDevDebugKotlin
47+
48+
run:
49+
#!/usr/bin/env sh
50+
set -eu
51+
52+
app_id="to.bitkit.dev"
53+
app_dir="app/build/outputs/apk/dev/debug"
54+
55+
if ! command -v adb >/dev/null 2>&1; then
56+
echo "adb is required to run the app." >&2
57+
exit 1
58+
fi
59+
60+
if [ -n "${ANDROID_SERIAL:-}" ]; then
61+
device_id="$ANDROID_SERIAL"
62+
else
63+
echo "Looking for connected Android devices..."
64+
device_id="$(
65+
adb devices -l \
66+
| awk 'NR > 1 && $2 == "device" && $1 !~ /^emulator-/ { print $1; exit }'
67+
)"
68+
69+
if [ -z "$device_id" ]; then
70+
device_id="$(
71+
adb devices -l \
72+
| awk 'NR > 1 && $2 == "device" { print $1; exit }'
73+
)"
74+
fi
75+
fi
76+
77+
if [ -z "$device_id" ]; then
78+
echo "No connected Android device found." >&2
79+
exit 1
80+
fi
81+
82+
device_name="$(
83+
adb -s "$device_id" shell getprop ro.product.model 2>/dev/null \
84+
| tr -d '\r' \
85+
|| true
86+
)"
87+
88+
if [ -z "$device_name" ]; then
89+
device_name="$device_id"
90+
fi
91+
92+
echo "Using $device_name ($device_id)"
93+
echo "Building Debug app..."
94+
{{ gradle }} assembleDevDebug
95+
96+
app_path="$(
97+
find "$app_dir" -maxdepth 1 -name '*-universal.apk' -type f \
98+
| sort \
99+
| tail -n 1
100+
)"
101+
102+
if [ -z "$app_path" ]; then
103+
app_path="$(
104+
find "$app_dir" -maxdepth 1 -name '*.apk' -type f \
105+
| sort \
106+
| tail -n 1
107+
)"
108+
fi
109+
110+
if [ -z "$app_path" ]; then
111+
echo "No APK found in $app_dir." >&2
112+
exit 1
113+
fi
114+
115+
echo "Installing $app_path..."
116+
adb -s "$device_id" install -r "$app_path"
117+
118+
echo "Launching $app_id..."
119+
adb -s "$device_id" shell am force-stop "$app_id"
120+
adb -s "$device_id" shell monkey -p "$app_id" -c android.intent.category.LAUNCHER 1 >/dev/null
121+
122+
pid="$(
123+
adb -s "$device_id" shell pidof -s "$app_id" 2>/dev/null \
124+
| tr -d '\r' \
125+
|| true
126+
)"
127+
128+
if [ -z "$pid" ]; then
129+
echo "Launched $app_id"
130+
exit 0
131+
fi
132+
133+
echo "Streaming logs for $app_id (pid $pid). Press Ctrl-C to stop."
134+
adb -s "$device_id" logcat --pid "$pid"
135+
136+
build task="assembleDevDebug":
137+
{{ gradle }} {{ task }}
138+
139+
release:
140+
{{ gradle }} assembleMainnetRelease bundleMainnetRelease
141+
142+
install:
143+
{{ gradle }} installDevDebug
144+
145+
test target="" value="":
146+
{{ if target == "" { gradle + " testDevDebugUnitTest" } else if target == "android" { gradle + " connectedDevDebugAndroidTest" } else if target == "file" { if value == "" { error("usage: just test file PATTERN") } else { gradle + " testDevDebugUnitTest --tests '" + value + "'" } } else if target == "lane" { if value == "" { error("usage: just test lane LANE") } else { gradle + " connectedDevDebug" + value + "AndroidTest" } } else { error("usage: just test [file PATTERN|android|lane LANE]") } }}
147+
148+
lint target="":
149+
{{ if target == "" { gradle + " detekt --rerun-tasks" } else if target == "baseline" { gradle + " detektBaseline --rerun-tasks" } else { error("usage: just lint [baseline]") } }}
150+
151+
format:
152+
{{ gradle }} detekt --auto-correct --rerun-tasks
153+
154+
translations action value="":
155+
{{ if action == "pull" { "./scripts/pull-translations.sh" } else if action == "push" { if value == "source" { "tx push --source" } else if value == "all" { "./scripts/push-translations.sh" } else { error("usage: just translations pull|push source|push all") } } else { error("usage: just translations pull|push source|push all") } }}
156+
157+
e2e mode="" value="" task="assembleDevRelease":
158+
{{ if mode == "" { "E2E=true " + gradle + " " + task } else if mode == "network" { "E2E=true E2E_BACKEND=network " + gradle + " " + if value == "" { task } else { value } } else if mode == "no" { if value == "geo" { "GEO=false E2E=true " + gradle + " " + task } else { error("usage: just e2e no geo [TASK]") } } else { "E2E=true " + gradle + " " + mode } }}
159+
160+
changelog target="all":
161+
./scripts/preview-changelog.sh --target {{ target }}
162+
163+
clean:
164+
{{ gradle }} clean

0 commit comments

Comments
 (0)