Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
df86a81
chore(sdd): add planning artifacts for stelekit-bazel migration
tstapler May 17, 2026
10e1d65
feat(build): migrate to Bazel with Bzlmod, KMP targets, Maven lockfile
tstapler Jun 12, 2026
8f48991
feat(bazel): get business_tests passing with KMP expect/actual support
tstapler Jun 12, 2026
9a192b3
feat(bazel): get jvm_tests passing — sandbox X11, JAR resources, temp…
tstapler Jun 12, 2026
65a6417
fix(review): address shipping-gate blockers from code review
tstapler Jun 12, 2026
dfb8c16
fix(review): address all non-blocking review items
tstapler Jun 12, 2026
9beb7ff
feat(bazel): improve caching — compression, BES backend, local disk c…
tstapler Jun 12, 2026
281c43b
feat(ci): replace BuildBuddy with GitHub Actions native Bazel caching
tstapler Jun 12, 2026
b600f18
fix(ci): tighten permissions and apt-get installs after code review
tstapler Jun 12, 2026
c805395
fix(ci): add workflow_dispatch trigger for manual pre-merge validation
tstapler Jun 13, 2026
c6a411b
chore: merge main — resolve add/add MODULE.bazel, gitignore, and test…
tstapler Jun 13, 2026
ef5c52b
fix(bazel): regenerate SQLDelight sources and fix GraphWriterTest whi…
tstapler Jun 13, 2026
b487fd8
fix(bazel/ci): resolve four CI failures from main merge
tstapler Jun 13, 2026
6fa9e7f
fix(bazel/ci): resolve remaining Bazel and Android CI failures
tstapler Jun 14, 2026
b6fc478
chore: merge main — resolve ca301a1e4b performance/BuildConfig conflicts
tstapler Jun 14, 2026
fffe230
fix(bazel/android): use Bazel-specific manifest to avoid AGP 8.13.2 p…
tstapler Jun 14, 2026
b2caac1
fix(bazel/ci): fix android manifest minSdk and show JVM test failures
tstapler Jun 14, 2026
62d5e15
fix(ci): mount X11 socket dir into Bazel sandbox for JVM tests
tstapler Jun 14, 2026
5c7cae7
chore: merge main — add appVersion to BuildInfo via PackageManager
tstapler Jun 14, 2026
820c355
fix(sqldelight): regenerate sources after main added app_version + co…
tstapler Jun 14, 2026
4d2cbcb
fix(ci): pass XAUTHORITY to Bazel JVM tests for xvfb-run auth
tstapler Jun 14, 2026
7c62e85
fix(bazel): compile commonMain+androidMain together for KMP expect/ac…
tstapler Jun 14, 2026
8d54d23
fix(bazel): add common_srcs to android_main for proper KMP expect/act…
tstapler Jun 14, 2026
4d39555
chore: merge main — tags feature, asset browser (#154, #153)
tstapler Jun 14, 2026
6e4b5fb
fix(build): regenerate SQLDelight sources and add PDFBox to Bazel
tstapler Jun 14, 2026
927fd8f
chore(bazel): repin maven_install.json after adding pdfbox:3.0.4
tstapler Jun 14, 2026
cea0c86
fix(bazel): add missing Android deps for feat/assets and feat/tags libs
tstapler Jun 14, 2026
ea8b173
fix(gradle): upgrade Android JGit from 5.13.3 to 7.3.0 to match Bazel
tstapler Jun 14, 2026
3508570
fix(bazel): expose androidMain string resources as android_library dep
tstapler Jun 14, 2026
5ff8d55
fix(bazel): add missing manifest to kmp_android_resources android_lib…
tstapler Jun 14, 2026
fb57f7b
fix(bazel): add kotlin.test, associates, and ExperimentalTime opt-in …
tstapler Jun 14, 2026
2e26100
fix(bazel): remove android_main from deps when in associates (rules_k…
tstapler Jun 14, 2026
58ccf91
fix(bazel): add AllAndroidUnitTests suite + test_class to android_loc…
tstapler Jun 14, 2026
a547563
fix(bazel): add rules_robolectric + android-all data dep so robolectr…
tstapler Jun 14, 2026
056ba5e
feat(ci): add bazel-cache-proxy with GHA backend to all Bazel CI jobs
tstapler Jun 15, 2026
1b93fce
fix(ci): install protobuf-compiler before building bazel-cache-proxy
tstapler Jun 16, 2026
c2b0722
fix(ci): pin bazel-cache-proxy to 7806c5f (NoopBackend fallback fix)
tstapler Jun 16, 2026
797f940
fix(ci): bump Android build timeout to 45 min
tstapler Jun 16, 2026
28ba28e
chore: merge main — detekt charset rule + DebounceManager race fix
tstapler Jun 16, 2026
cb41d6c
fix(merge): regenerate SQLDelight sources and remove duplicate walChe…
tstapler Jun 16, 2026
104462b
Merge remote-tracking branch 'origin/main' into stelekit-bazel
tstapler Jun 16, 2026
e7114bc
fix: detekt ComposableParamOrder and flaky timing threshold
tstapler Jun 16, 2026
df07e5e
revert: restore 2s large-page timing threshold
tstapler Jun 16, 2026
9f97618
perf: move FTS merge from per-save to post-bulk-index
tstapler Jun 16, 2026
5c81a4f
fix: add @OptIn and Unit.right() to compactFtsIndex actor call
tstapler Jun 16, 2026
c60bb91
Merge remote-tracking branch 'origin/main' into stelekit-bazel
tstapler Jun 17, 2026
4f44b17
chore: merge main + regenerate SQLDelight (v0.47.x changes)
tstapler Jun 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SteleKit .bazelrc
# All Bazel flags for local and CI builds.
#
# Machine-specific overrides (ANDROID_HOME path, extra tool paths, etc.) go in
# .bazelrc.user — that file is gitignored and imported below. Copy
# .bazelrc.user.example to .bazelrc.user and edit for your machine.
try-import %workspace%/.bazelrc.user

# ── Bazel server JVM heap ─────────────────────────────────────────────────────
# Caps the Bazel server at 6 GB so Maven resolution doesn't OOM the host.
# Coursier's transitive graph for Compose+AndroidX is large; capping forces GC
# before the machine swaps out. Increase to -Xmx8g on 32 GB machines.
startup --host_jvm_args=-Xmx6g

# ── JVM toolchain ─────────────────────────────────────────────────────────────
build --java_runtime_version=21
build --tool_java_runtime_version=21

# ── Android SDK ───────────────────────────────────────────────────────────────
# android_sdk_repository_extension runs at repo-loading time (before config
# flags), so ANDROID_HOME must be a global repo_env, not scoped to :android.
# The value is supplied by .bazelrc.user locally and by the CI environment on
# GitHub Actions (android-actions/setup-android sets ANDROID_HOME).
build --repo_env=ANDROID_HOME

# --android_sdk and the toolchain flag are kept in :android so that JVM-only
# targets (business_tests, desktop_app) do not trigger Android toolchain
# resolution. Pass --config=android when building Android targets.
build:android --android_sdk=@androidsdk//:sdk

# ── Correctness / hermetic sandbox ────────────────────────────────────────────
build --sandbox_default_allow_network=false
build --incompatible_strict_action_env

# ── X11 socket access for Compose Desktop tests ───────────────────────────────
# Compose Desktop tests require an X display. The Linux sandbox creates a new
# mount namespace and does not include /tmp/.X11-unix by default, so the X11
# socket (DISPLAY=:N → /tmp/.X11-unix/XN) is inaccessible even when DISPLAY is
# inherited. Mount the X11 socket directory into every test sandbox.
# Locally: use whatever X server is running.
# CI: xvfb-run --auto-servernum creates the socket before bazel runs.
test --sandbox_add_mount_pair=/tmp/.X11-unix

# ── CI caching ────────────────────────────────────────────────────────────────
# Bazel caching in CI is handled entirely by bazel-contrib/setup-bazel@0.19.0
# (disk-cache, repository-cache, external-cache inputs) which uses GitHub Actions
# native cache — no third-party service required. See .github/workflows/bazel-ci.yml.

# ── Remote HTTP cache (bazel-cache-proxy) ─────────────────────────────────────
# Enable with --config=remote-cache. CI starts bazel-cache-proxy on port 9090
# backed by the GHA cache API; all jobs on the same PR share the cache.
# PRs write to their own scoped namespace so main's cache is never polluted.
# Local use: start `bazel-cache-proxy serve` with a disk backend, then pass
# --config=remote-cache to any bazel command.
build:remote-cache --remote_cache=http://127.0.0.1:9090
build:remote-cache --remote_upload_local_results
25 changes: 25 additions & 0 deletions .bazelrc.user.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copy this file to .bazelrc.user (gitignored) and edit for your machine.
# .bazelrc.user is imported by .bazelrc via try-import — it is NOT committed.

# ── Android SDK path ──────────────────────────────────────────────────────────
# build --repo_env=ANDROID_HOME=/home/<you>/Android/Sdk # Linux
# build --repo_env=ANDROID_HOME=/Users/<you>/Library/Android/sdk # macOS

# ── Tool PATH (if unzip is outside the hermetic PATH, e.g. Homebrew) ─────────
# build --action_env=PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin:/bin

# ── Local disk cache ─────────────────────────────────────────────────────────
# Persists build action results between sessions and workspace switches.
# Dramatically speeds up incremental builds — similar benefit to ccache for C++.
# Grows unboundedly; run `bazel clean --expunge` or delete the dir to reclaim space.
# build --disk_cache=~/.cache/bazel-disk-cache

# ── Remote cache (optional — for sharing across machines) ────────────────────
# If you build on multiple machines and want a shared cache, you can point at
# any Bazel-compatible remote cache (BuildBuddy free tier, self-hosted bazel-remote, etc.):
# build --remote_cache=grpcs://remote.buildbuddy.io
# build --remote_header=x-buildbuddy-api-key=<YOUR_KEY>
# build --remote_cache_compression=zstd
#
# CI uses GitHub Actions native caching (setup-bazel disk/repo/external-cache)
# so no API key is needed there.
262 changes: 262 additions & 0 deletions .github/workflows/bazel-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
name: Bazel CI

on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:

permissions:
contents: read

# Only one CI run per branch at a time; newer push cancels in-progress run.
concurrency:
group: bazel-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
# ── JVM / Desktop tests ────────────────────────────────────────────────────
bazel-jvm:
name: Bazel JVM tests
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v4

- name: Cache bazel-cache-proxy binary
id: bcp-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/bazel-cache-proxy
key: bcp-${{ runner.os }}-7806c5f

- name: Install bazel-cache-proxy
if: steps.bcp-cache.outputs.cache-hit != 'true'
run: |
sudo apt-get install -y --no-install-recommends protobuf-compiler
cargo install --git https://github.com/tstapler/bazel-cache-proxy --rev 7806c5f bazel-cache-proxy --locked

- name: Start bazel-cache-proxy (GHA backend)
run: |
printf '[backend]\ntype = "gha"\n' > /tmp/bcp.toml
~/.cargo/bin/bazel-cache-proxy serve --config /tmp/bcp.toml &
sleep 2
curl -sf http://127.0.0.1:9090/healthz

- name: Set up Bazel
uses: bazel-contrib/setup-bazel@0.19.0
with:
bazelisk-version: "1.x"
# Persistent disk cache for build action results (compiled Kotlin, JARs).
# Keyed per-job so JVM and Android caches don't collide.
disk-cache: jvm
# Shared Maven/artifact download cache across all jobs (keyed by MODULE.bazel).
repository-cache: true
# Cache large individual external repos (Compose Desktop, AndroidX) separately.
external-cache: true
# Only write cache on main-branch pushes; PRs read but don't pollute.
cache-save: ${{ github.event_name != 'pull_request' }}

- name: Install Xvfb (headless display for Compose Desktop tests)
run: |
sudo apt-get install -y --no-install-recommends xvfb
# Ensure /tmp/.X11-unix exists before Bazel sandbox tries to bind-mount it
# (xvfb-run creates the socket, but Bazel validates the mount source at startup)
mkdir -p /tmp/.X11-unix

- name: Build JVM target
run: bazel build //kmp:desktop_app --config=remote-cache

- name: Run JVM tests
run: |
xvfb-run --auto-servernum bazel test //kmp:jvm_tests \
--config=remote-cache \
--test_output=all \
--sandbox_add_mount_pair=/tmp/.X11-unix \
--test_env=DISPLAY \
--test_env=XAUTHORITY

# ── Android build ──────────────────────────────────────────────────────────
bazel-android:
name: Bazel Android build
runs-on: ubuntu-latest
timeout-minutes: 45
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21 + Android SDK
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"

- name: Set up Android SDK
uses: android-actions/setup-android@v3

- name: Install host tools required by aar_import
run: sudo apt-get install -y --no-install-recommends unzip

- name: Cache bazel-cache-proxy binary
id: bcp-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/bazel-cache-proxy
key: bcp-${{ runner.os }}-7806c5f

- name: Install bazel-cache-proxy
if: steps.bcp-cache.outputs.cache-hit != 'true'
run: |
sudo apt-get install -y --no-install-recommends protobuf-compiler
cargo install --git https://github.com/tstapler/bazel-cache-proxy --rev 7806c5f bazel-cache-proxy --locked

- name: Start bazel-cache-proxy (GHA backend)
run: |
printf '[backend]\ntype = "gha"\n' > /tmp/bcp.toml
~/.cargo/bin/bazel-cache-proxy serve --config /tmp/bcp.toml &
sleep 2
curl -sf http://127.0.0.1:9090/healthz

- name: Set up Bazel
uses: bazel-contrib/setup-bazel@0.19.0
with:
bazelisk-version: "1.x"
disk-cache: android
repository-cache: true
external-cache: true
cache-save: ${{ github.event_name != 'pull_request' }}

- name: Build Android APK
run: bazel build //kmp:android_app --config=android --config=remote-cache

# ── Android unit tests ─────────────────────────────────────────────────────
bazel-android-tests:
name: Bazel Android unit tests
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21 + Android SDK
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"

- name: Set up Android SDK
uses: android-actions/setup-android@v3

- name: Install host tools required by aar_import
run: sudo apt-get install -y --no-install-recommends unzip

- name: Cache bazel-cache-proxy binary
id: bcp-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/bazel-cache-proxy
key: bcp-${{ runner.os }}-7806c5f

- name: Install bazel-cache-proxy
if: steps.bcp-cache.outputs.cache-hit != 'true'
run: |
sudo apt-get install -y --no-install-recommends protobuf-compiler
cargo install --git https://github.com/tstapler/bazel-cache-proxy --rev 7806c5f bazel-cache-proxy --locked

- name: Start bazel-cache-proxy (GHA backend)
run: |
printf '[backend]\ntype = "gha"\n' > /tmp/bcp.toml
~/.cargo/bin/bazel-cache-proxy serve --config /tmp/bcp.toml &
sleep 2
curl -sf http://127.0.0.1:9090/healthz

- name: Set up Bazel
uses: bazel-contrib/setup-bazel@0.19.0
with:
bazelisk-version: "1.x"
disk-cache: android-tests
repository-cache: true
external-cache: true
cache-save: ${{ github.event_name != 'pull_request' }}

- name: Run Android unit tests
run: |
bazel test //kmp/src/androidUnitTest/kotlin:android_unit_tests \
--config=android \
--config=remote-cache \
--test_output=all \
--experimental_ui_max_stdouterr_bytes=4194304

# ── WASM/JS web build ─────────────────────────────────────────────────────
# rules_kotlin does not yet support Kotlin/WASM natively (rules_kotlin#567).
# //kmp:web_app is a genrule that delegates to Gradle's wasmJsBrowserDistribution.
# Gradle's own incremental cache is preserved via the gradle-home cache key.
bazel-web:
name: Bazel web (WASM/JS via Gradle genrule)
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Cache Gradle home
uses: actions/cache@v4
with:
path: ~/.gradle
key: gradle-web-${{ runner.os }}-${{ hashFiles('kmp/build.gradle.kts', 'settings.gradle.kts', 'gradle.properties') }}-${{ github.sha }}
restore-keys: |
gradle-web-${{ runner.os }}-${{ hashFiles('kmp/build.gradle.kts', 'settings.gradle.kts', 'gradle.properties') }}-
gradle-web-${{ runner.os }}-

- name: Cache bazel-cache-proxy binary
id: bcp-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/bazel-cache-proxy
key: bcp-${{ runner.os }}-7806c5f

- name: Install bazel-cache-proxy
if: steps.bcp-cache.outputs.cache-hit != 'true'
run: |
sudo apt-get install -y --no-install-recommends protobuf-compiler
cargo install --git https://github.com/tstapler/bazel-cache-proxy --rev 7806c5f bazel-cache-proxy --locked

- name: Start bazel-cache-proxy (GHA backend)
run: |
printf '[backend]\ntype = "gha"\n' > /tmp/bcp.toml
~/.cargo/bin/bazel-cache-proxy serve --config /tmp/bcp.toml &
sleep 2
curl -sf http://127.0.0.1:9090/healthz

- name: Set up Bazel
uses: bazel-contrib/setup-bazel@0.19.0
with:
bazelisk-version: "1.x"
disk-cache: web
repository-cache: true
external-cache: true
cache-save: ${{ github.event_name != 'pull_request' }}

- name: Build web bundle
run: bazel build //kmp:web_app --config=remote-cache

- name: Upload web distribution artifact
if: github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: web-dist
path: bazel-bin/kmp/web_dist.tar.gz
retention-days: 7
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,15 @@ fdroid/archive/
*.rej
*.bak
*.tmp
*.tempuploads/
*.temp
uploads/

# --------------------
# Bazel
# --------------------
/bazel-bin
/bazel-out
/bazel-testlogs
/bazel-*
# Machine-specific overrides (ANDROID_HOME, tool paths) — see .bazelrc.user.example
.bazelrc.user
Loading
Loading