From db60ad5cb2034d4f40b38c73800974f0c5279d2b Mon Sep 17 00:00:00 2001 From: Scott Olcott Date: Fri, 11 Sep 2026 14:28:30 -0600 Subject: [PATCH 1/3] Add a build GitHub Actions workflow Run formatting, lint, and the full Gradle build on pushes to main and on PRs, mirroring the Recipes setup: - JDK 25 (Corretto) to match the pinned daemon JVM. - ktfmtCheck at the root, plus a build-logic pass for ktfmt, checkSortDependencies, and detekt, which are wired up only on the build-logic included build. - ./gradlew build. On ubuntu-latest this compiles the Apple klibs and runs the js/wasmJs browser tests (Chrome ships on the runner) but skips linking the Apple frameworks and running the Apple test binaries. - packages: read plus the GITHUB_TOKEN fallback so the io.github.solcott dataresult/uistate artifacts resolve from GitHub Packages. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/build.yml | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..915cd3f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,51 @@ +name: Build + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + # io.github.solcott:dataresult* and uistate* resolve from GitHub Packages, which authenticates + # even public reads. settings.gradle.kts falls back to GITHUB_ACTOR/GITHUB_TOKEN. + packages: read + +jobs: + build: + # Linux still compiles the iOS/macOS klibs; it only skips linking the frameworks and running + # the Apple test binaries. Switch to macos-latest, as kmp-dataresult does, for full Apple + # coverage. Chrome ships on the runner, so the js/wasmJs browser tests run here. + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v7 + + # Corretto 25 matches gradle/gradle-daemon-jvm.properties, so foojay has nothing to provision. + - name: Set up JDK 25 + uses: actions/setup-java@v6 + with: + distribution: 'corretto' + java-version: '25' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v6 + + # The check half of ktfmtFormat: CI reports, it doesn't rewrite. The root wrapper does not + # cover build-logic, which is a separate included build. + - name: Check formatting + run: ./gradlew ktfmtCheck + + # detekt and the dependency sorter are wired up on build-logic only, so lint it directly. + - name: Check build-logic + run: ./gradlew -p build-logic ktfmtCheck checkSortDependencies detekt + + - name: Build + run: ./gradlew build From 4097011b54ce020873626d25610f38d13aafbdd7 Mon Sep 17 00:00:00 2001 From: Scott Olcott Date: Fri, 11 Sep 2026 14:28:30 -0600 Subject: [PATCH 2/3] Add Renovate configuration Enable Renovate with config:recommended (dependency dashboard, grouped updates, changelog links). Disable the io.github.solcott dataresult and uistate artifacts: they are -SNAPSHOTs on GitHub Packages that Renovate can't read without a token, so they are bumped by hand. Co-Authored-By: Claude Opus 4.8 --- .github/renovate.json5 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/renovate.json5 diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 0000000..4bcfb8e --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,14 @@ +{ + $schema: "https://docs.renovatebot.com/renovate-schema.json", + // Dependency Dashboard issue, monorepo grouping, changelog links. Catalog entries that share a + // version.ref (kotlin, circuit, apollo, compose, ...) already update together in one PR. + extends: ["config:recommended"], + + packageRules: [ + { + description: "kmp-dataresult is a -SNAPSHOT on GitHub Packages, which Renovate can't read without a token. Bump it by hand.", + matchPackageNames: ["io.github.solcott:dataresult*", "io.github.solcott:uistate*"], + enabled: false, + }, + ], +} From 7bfbd47322aa4ddfade055028d85f30503bda1ac Mon Sep 17 00:00:00 2001 From: Scott Olcott Date: Fri, 11 Sep 2026 15:20:02 -0600 Subject: [PATCH 3/3] Raise karma's browser timeout for :shared-compose browser tests The first CI run surfaced a pre-existing fragility: :shared-compose's jsBrowserTest disconnects with "no message in 30000 ms" and then fails claiming it discovered no tests. ComposeGraphSaverTest builds the real graph, which reaches :ui and drags skiko into the bundle (~15 MB), and headless Chrome on the runner spends the whole 30s default just loading it before any test reports. It passes locally, where Chrome is fast. Raise browserNoActivityTimeout (and the disconnect/ping timeouts) via a karma.config.d snippet, and document the trap alongside the related "did not discover any tests" note in AGENTS.md. Co-Authored-By: Claude Opus 4.8 --- AGENTS.md | 7 +++++++ shared-compose/karma.config.d/timeout.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 shared-compose/karma.config.d/timeout.js diff --git a/AGENTS.md b/AGENTS.md index f2af8a0..a17094a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -531,6 +531,13 @@ Consequences worth knowing before you add the first test to a module: only reaches one transitively. Without them the browser test bundle cannot load skiko, and the task reports *"did not discover any tests"* rather than naming the cause. `:shared-compose` is a module that needed all three the moment it gained a test. +- **A heavy browser test bundle blows karma's 30s `browserNoActivityTimeout` on CI**, and reports + the *same* *"did not discover any tests"* — the browser disconnects with "no message in 30000 ms" + before the first test reports, having spent the whole window just downloading skiko. It passes + locally, where Chrome is fast, and fails only on a CI runner. `:shared-compose:jsBrowserTest` is + the live case (it drags in `:ui`, so its bundle is ~15 MB); the timeout is raised in + `shared-compose/karma.config.d/`. `:presenter` and `:ui` load under the default today — add the + same snippet if they start disconnecting. - **The first *native* test binary to link the whole graph needs `linkerOpts("-lsqlite3")`.** The Apollo plugin adds it to `:network`'s own targets and the Apple app gets it from Xcode's `OTHER_LDFLAGS`, but a Kotlin/Native klib records no linker options, so a downstream test diff --git a/shared-compose/karma.config.d/timeout.js b/shared-compose/karma.config.d/timeout.js new file mode 100644 index 0000000..0c08b5d --- /dev/null +++ b/shared-compose/karma.config.d/timeout.js @@ -0,0 +1,14 @@ +// ComposeGraphSaverTest builds the real graph, which reaches :ui and therefore drags skiko into +// the browser test bundle -- ~15 MB of skiko.wasm plus the Compose runtime. On a CI runner, +// headless Chrome needs well over karma's 30s browserNoActivityTimeout default just to download +// and start that bundle before the first test reports, so it disconnects with +// "no message in 30000 ms". The task then fails claiming it "did not discover any tests", which +// points nowhere near the real cause. Give the browser room. +// +// This is the heaviest browser test bundle in the build; :presenter and :ui load under the default +// and so carry no such file. Add the same snippet to them if they start disconnecting on CI. +config.set({ + browserNoActivityTimeout: 300000, + browserDisconnectTimeout: 60000, + pingTimeout: 60000, +});