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
62 changes: 62 additions & 0 deletions docs/PLUGIN-PUBLISH.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,67 @@ cd plugins
./gradlew :android:publishPlugins
```

## Local publishing for testing (mavenLocal)

Use this when you want to consume Forma from **another** Gradle project **without**
`includeBuild("../plugins")` and **without** Portal credentials.

### Publish

```bash
# From repo root (recommended wrapper):
./scripts/publish-local.sh # version 0.1.3
./scripts/publish-local.sh 0.1.3-LOCAL # recommended for experiments

# Or:
cd plugins
./gradlew publishAllToMavenLocal
./gradlew publishAllToMavenLocal -PformaLocalVersion=0.1.3-LOCAL
```

What gets installed under `~/.m2/repository/tools/forma/`:

| Artifact | Notes |
|----------|--------|
| `core` | JVM library (`tools.forma:core`) |
| `android`, `target`, `validation`, `owners`, `config`, `deps` | plugin jars + Gradle plugin markers |

`:core` is published first so `:android`’s Maven POM can resolve
`tools.forma:core` from mavenLocal.

**Do not** pass `-PformaLocalVersion` for real Portal releases — keep Portal
on the plain `0.1.3` (or next release) version string.

### Consume from a test project

```kotlin
// settings.gradle.kts
pluginManagement {
repositories {
mavenLocal()
google()
mavenCentral()
gradlePluginPortal()
}
}

// build.gradle.kts or settings plugins {}
plugins {
id("tools.forma.android") version "0.1.3-LOCAL"
}
```

Also put `mavenLocal()` in `dependencyResolutionManagement.repositories` (or
`buildscript.repositories` / project `repositories`) so `tools.forma:core`
and sibling plugin jars resolve.

### vs composite includeBuild

| Mode | When |
|------|------|
| `includeBuild("../plugins")` | Day-to-day Forma development (sample `application/`) — no publish step |
| `publishAllToMavenLocal` | External smoke tests, versioned consumer repros, AGP upgrade spikes |

## Consumer coordinates

Unchanged for apps:
Expand All @@ -150,3 +211,4 @@ recommended path for Forma development (see
| GH #132 | Target-shaped publish config (implemented) |
| GH #133 | Shared Portal user (admin; documented, not automated) |
| F-024 | Coordinate plan when `forma-core` is extracted (`tools.forma:core` vs android plugins) |
| F-018 | Gradle/AGP modernization; use local publish for upgrade smoke tests |
12 changes: 12 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

Newest entries first.

## 2026-07-13 — Local maven publishing for plugin testing

- **Scope:** tooling for F-018 AGP/Gradle smoke tests + external consumers
- **Changes:**
- `plugins/core`: `maven-publish` → `tools.forma:core` (+ sources)
- `plugins/build.gradle.kts`: `publishAllToMavenLocal` aggregate; `-PformaLocalVersion=…`
- `scripts/publish-local.sh` helper
- `docs/PLUGIN-PUBLISH.md` § Local publishing
- **Verify:** `./gradlew publishAllToMavenLocal -PformaLocalVersion=0.1.3-LOCAL` → **BUILD SUCCESSFUL**; artifacts under `~/.m2/repository/tools/forma/*`; android POM lists `tools.forma:core:0.1.3-LOCAL`
- **Note:** sample `application/` still uses `includeBuild`; mavenLocal is for external test consumers
- **Next:** commit with F-018 branch or standalone docs/tooling PR if desired

## 2026-07-13 — F-021 Extract dependency-type / restriction engine into forma-core

- **Ticket:** F-021 → `done`
Expand Down
26 changes: 25 additions & 1 deletion plugins/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,36 @@ plugins {

// Shared Plugin Portal metadata for all subprojects (F-016 / GH #132).
// Subprojects call formaPublishedPlugin(name = …) instead of copying gradlePlugin blocks.
// Local testing: -PformaLocalVersion=0.1.3-LOCAL (mavenLocal only; never use for Portal)
val publishedVersion =
(findProperty("formaLocalVersion") as String?)?.takeIf { it.isNotBlank() } ?: "0.1.3"

formaPluginConfiguration {
group = "tools.forma"
version = "0.1.3"
version = publishedVersion
website = "https://forma.tools/"
vcsUrl = "https://github.com/formatools/forma.git"
displayName = "Forma - Meta Build System with Gradle and Android support"
description = "Best way to structure your Gradle Project"
tags = listOf("kotlin", "android", "structure", "target", "rules", "project")
}

/**
* Publish every plugin module + :core to ~/.m2/repository for consumer testing
* without includeBuild / Plugin Portal credentials.
*
* ./gradlew publishAllToMavenLocal
* ./gradlew publishAllToMavenLocal -PformaLocalVersion=0.1.3-LOCAL
*/
tasks.register("publishAllToMavenLocal") {
group = "publishing"
description =
"Publish Forma plugins (android, target, …) and :core to the local Maven cache"
// :core first so plugin POMs resolve tools.forma:core when installed from mavenLocal
dependsOn(":core:publishToMavenLocal")
subprojects
.filter { it.name != "core" }
.forEach { sp ->
dependsOn("${sp.path}:publishToMavenLocal")
}
}
23 changes: 20 additions & 3 deletions plugins/core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
plugins {
kotlin("jvm")
`maven-publish`
}

// Library (not a settings/application plugin). Use same group/version as plugins for the jar.
group = "tools.forma"
version = "0.1.3"
// Library (not a Gradle plugin). Same group/version as plugins for mavenLocal + Portal later.
group = rootProject.group
version = rootProject.version

java {
withSourcesJar()
}

dependencies {
testImplementation(kotlin("test"))
Expand All @@ -13,3 +18,15 @@ dependencies {
tasks.test {
useJUnitPlatform()
}

publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
// Explicit coordinates so consumers resolve tools.forma:core:<version>
groupId = project.group.toString()
artifactId = "core"
version = project.version.toString()
}
}
}
39 changes: 39 additions & 0 deletions scripts/publish-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Publish Forma plugins + forma-core to the local Maven cache (~/.m2) for testing.
#
# Usage:
# ./scripts/publish-local.sh
# ./scripts/publish-local.sh 0.1.3-LOCAL # version override (recommended for experiments)
#
# Then consume from another project WITHOUT includeBuild:
# pluginManagement {
# repositories { mavenLocal(); google(); mavenCentral(); gradlePluginPortal() }
# }
# plugins { id("tools.forma.android") version "0.1.3-LOCAL" }
#
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
# shellcheck disable=SC1091
[[ -f "$ROOT/scripts/env-mac.sh" ]] && source "$ROOT/scripts/env-mac.sh" || true

VERSION_ARG="${1:-}"
EXTRA=()
if [[ -n "$VERSION_ARG" ]]; then
EXTRA+=("-PformaLocalVersion=$VERSION_ARG")
fi

cd "$ROOT/plugins"
echo "=== publishAllToMavenLocal ${VERSION_ARG:+(version $VERSION_ARG)} ==="
./gradlew publishAllToMavenLocal "${EXTRA[@]}" --console=plain

# Resolve version used
VER="${VERSION_ARG:-0.1.3}"
echo
echo "=== installed under ~/.m2 (tools/forma) ==="
find "${HOME}/.m2/repository/tools/forma" -maxdepth 3 -type d 2>/dev/null | head -40 || true
echo
ls -la "${HOME}/.m2/repository/tools/forma/core/${VER}/" 2>/dev/null || \
ls -la "${HOME}/.m2/repository/tools/forma/" 2>/dev/null | head || true
echo
echo "Done. Consumer version: $VER"
echo "Plugin id: tools.forma.android"
Loading