Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ jobs:
with:
distribution: temurin
java-version: "21"
# Sample app: compileSdk 35 (Compose 1.11 / modern AndroidX), targetSdk 35, minSdk 23.
# Sample app: compileSdk/targetSdk 37 (F-087 AndroidX ceiling; core 1.19), minSdk 23.
# setup-android accepts licenses, installs cmdline-tools + listed packages,
# and exports ANDROID_HOME / ANDROID_SDK_ROOT for AGP.
- name: Set up Android SDK
uses: android-actions/setup-android@v3
with:
# Space-separated sdkmanager package ids (semicolons inside package names).
packages: "platform-tools platforms;android-35 platforms;android-34 platforms;android-33 build-tools;35.0.0 build-tools;34.0.0"
# platforms;android-37 may resolve as android-37.0 on newer cmdline-tools — install both forms when available.
packages: "platform-tools platforms;android-37.0 platforms;android-37 platforms;android-36 platforms;android-35 build-tools;37.0.0 build-tools;36.0.0 build-tools;35.0.0"
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build application
Expand Down
2 changes: 1 addition & 1 deletion TICKETS.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Promoted from daily next-actions / historical GH. Workers pick top `todo` in ord

| ID | Status | Title | Notes |
|----|--------|-------|-------|
| F-087 | todo | AndroidX / SDK ceiling after AGP 9 | Raise sample `compileSdk`/`targetSdk` as needed; bump AndroidX (core/activity/lifecycle/compose/…) to latest **compatible** with AGP **9.3** (probe AAR `minCompileSdk` / `minAndroidGradlePluginVersion`). Update catalogs + forces in `application/settings.gradle.kts`. Verify plugins + application + CI. Refs: F-019 note, companion dep ceiling. |
| F-087 | done | AndroidX / SDK ceiling after AGP 9 | compile/target **37**; core **1.19.0**, activity **1.13.0**, lifecycle **2.11.0**, compose **1.11.4**, room **2.8.4**, material **1.14.0**; JVM **11**; navigationevent on activity graph; paging **2.1.2** kept. Host+CI platform 37. |
| F-088 | todo | Fleet tooling phase 2 (F-084 follow-ups) | From `docs/FLEET-TOOLING.md`: Gradle `formaLayoutCheck` / `formaLayoutGenerate` tasks (thin shells over core); optional config-time packageName dir hook; bulk generate driver for includer graph. Defer AST migrate / depgen resurrection unless unblocked in-slice. Close GH **#54** if generate path is user-complete. |
| F-089 | todo | Navigation task cache broken | GH **#110** — fix navigation/safe-args related task cache so config/build cache is correct; reproduce from issue screenshots; add regression note or test if feasible; plugins+app green. |
| F-090 | todo | Exclude modules from dependency validation | GH **#97** — allow-list / opt-out for forked-in libraries (ExoPlayer-class cases) without weakening default matrix. One global configuration path (not per-call-site escape hatch spam). Docs + sample or unit coverage. |
Expand Down
10 changes: 7 additions & 3 deletions application/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import org.gradle.api.JavaVersion

buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
// compileSdk 35+ required by Compose 1.11 / modern AndroidX AAR metadata
compileSdk = 35,
targetSdk = 37,
// F-087: compileSdk 37 for AndroidX core 1.19 AAR metadata (minCompileSdk=37)
compileSdk = 37,
agpVersion = "9.3.0",
// Navigation 2.9 / modern AndroidX ship JVM 11 bytecode — cannot inline into 1.8
javaVersionCompatibility = JavaVersion.VERSION_11,
extraPlugins =
listOf(
libs.plugins.toolsFormaDemoDependencies,
Expand Down
4 changes: 2 additions & 2 deletions application/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ includer { arbitraryBuildScriptNames = true }
rootProject.name = "application"

val coilVersion = "2.7.0"
val sqliteVersion = "2.5.1"
val roomVersion = "2.7.2"
val sqliteVersion = "2.7.0"
val roomVersion = "2.8.4"

val ksp = CustomConfiguration("ksp")

Expand Down
7 changes: 7 additions & 0 deletions build-dependencies/dependencies/src/main/kotlin/Androidx.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,20 @@ object androidx {
core
)

private val navigationevent = deps(
"androidx.navigationevent:navigationevent:${versions.androidx.navigationevent}".dep,
annotation,
core
)

private val activity = deps(
"androidx.activity:activity:${versions.androidx.activity}".dep,
annotation,
core,
lifecycle_runtime,
lifecycle_viewmodel_ktx,
lifecycle_viewmodel_savedstate,
navigationevent,
savedstate
)

Expand Down
37 changes: 20 additions & 17 deletions build-dependencies/dependencies/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ object versions {
}

object androidx {
// Caps: latest that stay on AGP 9.3 + compileSdk 35
// (core 1.17+/activity 1.12+/lifecycle-compose 2.11+ may need higher SDK / AGP line)
const val activity = "1.10.1"
const val annotation = "1.9.1"
// F-087 ceiling: AGP 9.3 + compileSdk/targetSdk 37 (AAR minCompileSdk probed)
// core 1.19 → minCompileSdk 37 + minAGP 9.1; activity 1.13 → minCompileSdk 36
// paging stays 2.x (sample PagedList APIs); OkHttp/Retrofit 4/2 separate
const val activity = "1.13.0"
const val annotation = "1.10.0"
const val arch = "2.2.0"
const val asynclayoutinflater = "1.0.0"
const val appcompat = "1.7.1"
const val appcompat = "1.7.1" // latest stable (1.8 still alpha)
const val cardview = "1.0.0"
const val collection = "1.5.0"
const val core = "1.16.0"
const val collection = "1.6.0"
const val core = "1.19.0"
const val core_common = "2.2.0"
const val coordinatorlayout = "1.3.0"
const val constraintlayout = "2.2.1"
Expand All @@ -25,30 +26,32 @@ object versions {
const val documentfile = "1.0.1"
const val drawerlayout = "1.2.0"
const val interpolator = "1.0.0"
const val fragment = "1.8.9"
const val fragment = "1.8.9" // latest stable (1.9 still alpha)
const val legacy = "1.0.0"
const val lifecycle = "2.10.0"
const val lifecycle = "2.11.0"
const val loader = "1.1.0"
const val localbroadcastmanager = "1.0.0"
// Sample uses paging 2.x APIs (PagedList / PageKeyedDataSource) — do not jump to 3.x
const val navigation = "2.9.8"
const val savedstate = "1.3.1"
const val navigation = "2.9.8" // latest stable (2.10 still alpha)
// activity 1.13+ DialogFragment surface needs navigationevent on compile classpath
const val navigationevent = "1.1.2"
const val savedstate = "1.5.0"
const val slidingpanelayout = "1.2.0"
const val swiperefreshlayout = "1.2.0"
const val sqlite = "2.5.1"
const val sqlite = "2.7.0"
const val paging = "2.1.2"
const val recyclerview = "1.4.0"
const val room = "2.7.2"
const val transition = "1.6.0"
const val room = "2.8.4"
const val transition = "1.7.0"
const val vectordrawable = "1.2.0"
const val versionedparcelable = "1.2.1"
const val viewpager = "1.1.0"
// Compose 1.9.x works with AGP 9.3 + compileSdk 35 + Kotlin 2.3.21
const val compose = "1.9.4"
// Compose BOM line 1.11.x stable (1.12 still beta)
const val compose = "1.11.4"
}

object google {
const val material = "1.13.0"
const val material = "1.14.0"
const val dagger = "2.60.1"
const val play_core = "1.10.3"
const val gson = "2.13.2"
Expand Down
11 changes: 6 additions & 5 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
extraPlugins = listOf(
// classpath only — see PROJECT-CONFIGURATION.md + TARGET-PLUGINS.md
Expand Down Expand Up @@ -295,7 +295,7 @@ Concurrency group `ci-${{ github.workflow }}-${{ github.ref }}` cancels in-progr
CI pins (evolved F-004 → F-018):

1. **All jobs** pin Temurin **21** via `actions/setup-java@v4` (was 17; requires Gradle ≥8.5 — wrappers are **9.6.1**).
2. **Application** installs Android SDK packages matching sample `compileSdk` **35** / target **35**.
2. **Application** installs Android SDK packages matching sample `compileSdk` **37** / target **37**.
3. README badge → `formatools/forma` + `actions/workflows/main.yml/badge.svg`.
4. Gradle setup via `gradle/actions/setup-gradle@v4` (successor of `gradle-build-action`).
5. Dropped unconditional `--scan` (no build-scan account coupling in CI).
Expand All @@ -313,8 +313,9 @@ keys) or full Portal publish via secrets; deeper Gradle remote cache.
| App bytecode / `jvmTarget` | unchanged (sample default `JavaVersion.VERSION_1_8`) — not raised with daemon JDK |
| Gradle | **9.6.1** (all wrappers; F-019) |
| AGP | **9.3.0** sample runtime + plugins compile (F-019) |
| Kotlin | embeddedKotlin from Gradle 9.6.1 (**2.3.21**); KSP **2.3.10**; Compose compiler default **2.3.21** |
| Android SDK | sample min **23** / target **35** / compile **35**; host platforms 35+34+33 + build-tools 33/34 |
| Kotlin | embeddedKotlin from Gradle 9.6.1 (**2.3.21**); KSP **2.3.10**; Compose UI **1.11.4** / compiler default **2.3.21** |
| Android SDK | sample min **23** / target **37** / compile **37** (F-087); host platforms 37+36+35 + build-tools 37/36/35 |
| AndroidX ceiling | core **1.19.0**, activity **1.13.0**, lifecycle **2.11.0**, room **2.8.4**, material **1.14.0** (paging **2.1.2** kept) |
| Forma version | 0.1.3 |

Host bootstrap details: `docs/ENV.md`, `scripts/env-mac.sh` (F-001).
Expand Down
38 changes: 22 additions & 16 deletions docs/ENV.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
# Worker host environment (macOS)

Forma workers need **JDK 21** (build/daemon JVM; F-018) and an **Android SDK**
with platform **34** (sample `compileSdk`; Compose AAR metadata) and optionally
**33** (`targetSdk`). Android app language level / `jvmTarget` stays at the
project’s configured `JavaVersion` (sample default still 1.8) — raising bytecode
is a separate decision from the daemon JDK.
Forma workers need **JDK 21** (build/daemon JVM; F-018/F-019) and an **Android SDK**
with platform **37** (sample `compileSdk` / `targetSdk` after F-087; AndroidX core
1.19 AAR metadata). Platforms **36**/**35** remain useful for intermediate ceilings.
Android app language level / `jvmTarget` stays at the project’s configured
`JavaVersion` (sample default still 1.8) — raising bytecode is a separate decision
from the daemon JDK.

## Quick start (this Mac)

```bash
# Already installed on the Forma worker host (no sudo):
# brew install openjdk@21
# brew install --cask android-commandlinetools
# sdk packages: platforms;android-34, platforms;android-33, platform-tools,
# build-tools 33.0.2 + 34.0.0
# sdk packages: platforms android-37.0 (+ symlink android-37), 36, 35, …
# build-tools 37/36/35, platform-tools

source scripts/env-mac.sh

Expand Down Expand Up @@ -60,11 +61,15 @@ export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME

yes | sdkmanager --licenses
sdkmanager --install \
"platforms;android-34" \
"platforms;android-33" \
"platforms;android-37.0" \
"platforms;android-36" \
"platforms;android-35" \
"platform-tools" \
"build-tools;33.0.2" \
"build-tools;34.0.0"
"build-tools;37.0.0" \
"build-tools;36.0.0" \
"build-tools;35.0.0"
# AGP resolves compileSdk=37 as platforms/android-37
ln -sfn android-37.0 "$ANDROID_HOME/platforms/android-37"

printf 'sdk.dir=%s\n' "$ANDROID_HOME" > application/local.properties
```
Expand All @@ -76,16 +81,17 @@ sudo ln -sfn /usr/local/opt/openjdk@21/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-21.jdk
```

## Verified on 2026-07-20 (F-019 Phase 1 — Gradle 9 + Kotlin 2.3 + AGP 9)
## Verified on 2026-07-21 (F-087 — AndroidX / SDK ceiling)

- `java` / `javac` **21.x** (Homebrew OpenJDK 21) via `scripts/env-mac.sh`
- Gradle wrappers: **9.6.1** (all roots; F-019)
- AGP **9.3.0** lockstep (`plugins/android` compile + sample `agpVersion`)
- Kotlin **2.3.21** (Gradle embedded); KSP **2.3.10**
- Compose compiler default **2.3.21** (+ Kotlin Compose Compiler plugin when `compose=true`)
- Sample SDK: min **23** / target **35** / compile **35** (install platform 35 for full sample builds; 34/33 still useful)
- CI: Temurin **21** all jobs (`.github/workflows/main.yml`)
- F-019 Phase 1 + F-086 ksp/built-in Kotlin done
- Compose UI **1.11.4** / compiler **2.3.21** (+ Kotlin Compose Compiler plugin when `compose=true`)
- Sample SDK: min **23** / target **37** / compile **37** (platform package `android-37.0`, AGP dir `android-37`)
- AndroidX ceiling (stable, AAR-probed): core **1.19.0**, activity **1.13.0**, lifecycle **2.11.0**, room **2.8.4**, material **1.14.0**; paging **2.1.2** kept (API rewrite separate)
- CI: Temurin **21** + platforms 37/36/35 (`.github/workflows/main.yml`)
- F-019 Phase 1 + F-086 ksp/built-in Kotlin + F-087 ceiling

See `docs/PROGRESS.md` for the latest host build tails.

Expand Down
4 changes: 2 additions & 2 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ structure and boundaries, not business logic.
| Tool | Version / notes |
|------|-----------------|
| JDK | **21** build/daemon (F-018); app language level unchanged |
| Android SDK | Platform **35** (`compileSdk` / modern Compose + AndroidX AARs); **34**/**33** still useful |
| Android SDK | Platform **37** (`compileSdk` / modern Compose + AndroidX AARs); **36**/**35** still useful |
| Build tools | 33.0.2 / 34.0.0 as used by the sample |
| Gradle | Use the wrapper in the project (`./gradlew`); **9.6.1** all roots |
| AGP | **9.3.0** (keep consumer `agpVersion` aligned with plugin compile AGP) |
Expand Down Expand Up @@ -442,7 +442,7 @@ Details: [COMPOSE.md](COMPOSE.md). Sample:
| Symptom | Likely cause |
|---------|----------------|
| “Java not found” / old JDK | Use JDK 21 (or 17+ min); export `JAVA_HOME` ([ENV.md](ENV.md)) |
| SDK / `compileSdk` errors | Install platform **35**; set `local.properties` `sdk.dir` |
| SDK / `compileSdk` errors | Install platform **37** (`platforms;android-37.0` + `android-37` symlink); set `local.properties` `sdk.dir` |
| Project not included | Missing `build.gradle.kts`, or nested `settings.gradle.kts` blocked Includer |
| Illegal project dependency | Matrix violation — see [DEPENDENCY-MATRIX.md](DEPENDENCY-MATRIX.md) |
| Empty / wrong package | `packageName` ≠ directory under `src/main/java` |
Expand Down
25 changes: 25 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

Newest entries first.

## 2026-07-21 — F-087: AndroidX / SDK ceiling

- **Ticket:** F-087 → `done`
- **Branch:** `forma/F-087-androidx-ceiling` (from origin/v2)
- **Skills/modes:** Hermes toolchain finish path (F-018 class); AAR metadata probe before pins
- **SDK:** sample min **23** / target **37** / compile **37**
- Host: installed `platforms;android-36`, `platforms;android-37.0`, build-tools 36/37; symlink `platforms/android-37` → `android-37.0` (AGP dir name)
- CI: `.github/workflows/main.yml` packages 37.0/37/36/35 + build-tools 37/36/35
- **AndroidX / related (stable, AAR-probed):**
- core **1.19.0** (minCompileSdk 37, minAGP 9.1) · activity **1.13.0** · lifecycle **2.11.0**
- compose **1.11.4** · room **2.8.4** · sqlite **2.7.0** · material **1.14.0**
- annotation **1.10.0** · collection **1.6.0** · savedstate **1.5.0** · transition **1.7.0**
- navigationevent **1.1.2** added under activity graph (DialogFragment / ComponentActivity surface)
- appcompat **1.7.1**, fragment **1.8.9**, navigation **2.9.8** (latest stable; alphas skipped)
- **paging 2.1.2 kept** (sample PagedList APIs — 3.x = separate rewrite)
- **Bytecode:** `javaVersionCompatibility = JavaVersion.VERSION_11` (navigation 2.9 JVM11 cannot inline into 1.8)
- **Examples:** all `examples/android/*` compile/target 37; compose demo pins → 1.11.4
- **Docs:** ENV, ARCHITECTURE, GETTING-STARTED, SAMPLE-APP toolchain stamps
- **Out of scope:** OkHttp 5 / Retrofit 3; paging 3; alpha appcompat/fragment/navigation/compose
- **Verify (real host, `source scripts/env-mac.sh`):**
- `plugins/ ./gradlew build` → **BUILD SUCCESSFUL** (78 tasks)
- `application/ ./gradlew build` → **BUILD SUCCESSFUL** (2322 tasks)
- **Blockers:** none
- **Next:** F-088 fleet tooling phase 2

## 2026-07-21 — Promote backlog → P9 (Stepan)

- **Action:** User: “Promote all 6 tickets” on empty-board daily next-actions
Expand Down
2 changes: 1 addition & 1 deletion docs/SAMPLE-APP.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ printf 'sdk.dir=%s\n' "$ANDROID_HOME" > application/local.properties
cd application && ./gradlew build
```

Toolchain: AGP **9.3.0**, compileSdk **35**, targetSdk **35**, Gradle **9.6.1**,
Toolchain: AGP **9.3.0**, compileSdk **37**, targetSdk **37**, Gradle **9.6.1**,
build JDK **21** (app language level unchanged). See [ENV.md](ENV.md),
[COMPOSE.md](COMPOSE.md), [ARCHITECTURE.md](ARCHITECTURE.md).

Expand Down
4 changes: 2 additions & 2 deletions examples/android/01-hello-apk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0"
)
}
4 changes: 2 additions & 2 deletions examples/android/02-feature-api-impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
)
}
4 changes: 2 additions & 2 deletions examples/android/03-res-viewbinding/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
)
}
4 changes: 2 additions & 2 deletions examples/android/04-shared-libs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
)
}
4 changes: 2 additions & 2 deletions examples/android/05-widget-ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
)
}
4 changes: 2 additions & 2 deletions examples/android/06-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ buildscript {
androidProjectConfiguration(
project = rootProject,
minSdk = 23,
targetSdk = 35,
compileSdk = 35,
targetSdk = 37,
compileSdk = 37,
agpVersion = "9.3.0",
compose = true,
composeCompilerVersion = "2.3.21",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
composeWidget(
packageName = "tools.forma.examples.android.compose.common.greeting.compose.widget",
dependencies = transitiveDeps(
"androidx.compose.runtime:runtime:1.5.4",
"androidx.compose.ui:ui:1.5.4",
"androidx.compose.foundation:foundation:1.5.4",
"androidx.compose.material:material:1.5.4",
"androidx.compose.ui:ui-tooling-preview:1.5.4",
"androidx.compose.runtime:runtime:1.11.4",
"androidx.compose.ui:ui:1.11.4",
"androidx.compose.foundation:foundation:1.11.4",
"androidx.compose.material:material:1.11.4",
"androidx.compose.ui:ui-tooling-preview:1.11.4",
)
)
Loading
Loading