Compare commits

..
3 Commits
Author SHA1 Message Date
Bitsy 275ee97d56 fix(publish): :sdl-core emits a publishable klib + harden retry-cleanup jq
v0.4.0 publish failed on all hosts at :sdl-core:generateMetadataFileFor<Target>Publication
(FileNotFound on sdl-core-<target>Main-<ver>.klib). Root cause: :sdl-core is a
cinterop-only module with ZERO Kotlin sources, so the native main compilation
emits no main klib for maven-publish to consume. Add a minimal internal marker
in nativeMain so every target produces a klib; the sdl3 cinterop klib +.module
metadata ride along (verified via publishMingwX64PublicationToMavenLocal across
all modules).

Also harden cleanup_host_versions' jq: a not-yet-published package returns a
JSON object, not an array, which crashed 'select(.name==$v)' ('Cannot index
string with string') and defeated the retry-cleanup. Guard with type=="array".
2026-07-26 01:04:26 +02:00
Bitsy e5fb04f882 chore(api): refresh klib baselines + exclude sdl-core/material-symbols; add regen to release runbook
Regenerated all tracked klib API dumps (they'd drifted — stale bodies from
before the module split/rename). Exclude :sdl-core (naked SDL cinterop — its
API is the generated sdl3.* bindings, per-OS, not our surface) and
:material-symbols (auto-generated icon codepoint maps; its jvm dump also trips
BCV's ASM on JDK 25, 'class file major version 69') from apiValidation.
macosArm64 is inferred from the linux/mingw ABIs (accurate for the
target-independent Compose surface). Documented 'regenerate baselines before
tagging' in the release runbook; not a hard apiCheck gate until the API
stabilizes. Also fixed two stale com.bitsycore.compose.sdl coord refs in the
TOOLING version map / publish notes (now per-area).
2026-07-26 00:55:04 +02:00
Bitsy 23849330d1 docs(api): regenerate desktop-native-window API dump
The checked-in baseline was stale — generated very early (package
com.compose.desktop.native, only nativeComposeWindow public) and never
regenerated since; the coord rebrand only patched its header. Now that mingw
builds (skiko fork published), apiDump reflects the real surface: nativeComposeApp,
ApplicationScope.Window, AppWindowIcon, windowHasInvalidations, the frame-time
toggles, and the updated nativeComposeWindow signature — all in com.compose.sdl.
2026-07-26 00:45:25 +02:00
6 changed files with 55 additions and 8540 deletions
+1 -1
View File
@@ -193,7 +193,7 @@ jobs:
host_packages | while read -r pkg; do
vid=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
"https://api.github.com/users/$OWNER/packages/maven/$pkg/versions?per_page=100" \
| jq -r --arg v "$VER" '[.[]? | select(.name==$v) | .id] | first // empty')
| jq -r --arg v "$VER" 'if type=="array" then ([.[] | select(.name==$v) | .id] | first // empty) else empty end')
[ -z "$vid" ] && continue
code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: Bearer $GITHUB_TOKEN" \
+12 -3
View File
@@ -158,7 +158,7 @@ single file to edit; know which axis you are changing.
| Version | Where | Notes |
|---------|-------|-------|
| Project release version | The git tag `vX.Y.Z`. `PUBLISH_VERSION` (from the tag) feeds `vPublishVersion` in `build.gradle.kts`, which strips the leading `v`. Group is `com.bitsycore.compose.sdl`. | Set by the tag, not edited by hand. A non-publish build is `0.0.0-SNAPSHOT`. |
| Project release version | The git tag `vX.Y.Z`. `PUBLISH_VERSION` (from the tag) feeds `vPublishVersion` in `build.gradle.kts`, which strips the leading `v`. Groups mirror upstream per area (`com.bitsycore.compose.<area>:<module>`, e.g. `com.bitsycore.compose.ui:ui`); project-only modules use `com.bitsycore.compose.sdl` and `:desktop-native-window` is `com.bitsycore.compose` — see `groupFor()` in the root build. | Set by the tag, not edited by hand. A non-publish build is `0.0.0-SNAPSHOT`. |
| Vendored Compose (native side) | `COMPOSE_CORE_REF` and `COMPOSE_REF` in `scripts/compose-fork/compose.properties`, plus `compose` in `gradle/libs.versions.toml`. | Pin to a durable tag (not a `+dev` commit upstream may GC). Re-sync after changing. |
| JVM parity forcing | `vComposeJvmVersion` in `demo`, `apidemo`, and `material-symbols` `build.gradle.kts`. | Must be a version PUBLISHED to Maven Central. It may lag the vendored native ref (a documented skew) until the matching version is published. |
| Skiko | `skiko` in `gradle/libs.versions.toml`. | macOS/Linux use official Skiko (`org.jetbrains.skiko`); mingwX64 uses the bitsycore fork (`com.bitsycore.skiko:skiko:0.150.1-mingw.1` from GitHub Packages), published out of band by the fork repo's own workflow. Must expose the `org.jetbrains.skiko.node` `RenderNode` / `GraphicsContext` API the vendored compose-core uses (the fork keeps upstream's `org.jetbrains.skiko.*` package names; only the Maven coord is rebranded). Verify with a throwaway `skikoRendererMain` compile if unsure. |
@@ -191,12 +191,21 @@ Run this on each upstream bump; it is the flow that keeps the sync tax low.
Only Windows compiles the full common-metadata variant table, and the root
KotlinMultiplatform publications live there; a macOS-only publish leaves the
roots without mingwX64 variants (this bit v0.1.15).
3. `git tag vX.Y.Z && git push origin vX.Y.Z`. This triggers `.github/workflows/publish.yml`.
3. Refresh the klib API baselines: on a Windows host (JDK 21, matching CI) run
`./gradlew apiDump` and commit any diff. Not a hard gate yet — the API is
pre-stable and `apiCheck` isn't wired — but regenerating each release keeps
the baselines honest so the eventual gate is a no-op. `macosArm64` is inferred
from the linux/mingw ABIs (accurate for the target-independent Compose
surface); `:sdl-core` (cinterop) and `:material-symbols` (generated icon maps)
are excluded via `apiValidation.ignoredProjects`. Best host: Windows — it
builds the mingw slice (the fork's unique surface) for real and only infers
macos; the macos ABI is target-independent for the tracked pure-Kotlin modules.
4. `git tag vX.Y.Z && git push origin vX.Y.Z`. This triggers `.github/workflows/publish.yml`.
What the publish job does, so you can read a failure:
- Each host publishes only its own target's publications to GitHub Packages
under `com.bitsycore.compose.sdl:*`. Windows additionally publishes the root
under their per-area `com.bitsycore.compose.*` coords. Windows additionally publishes the root
KotlinMultiplatform metadata, the `jvm` publication, and the bridge plugin
(only Windows declares every target).
- The `MODULES` list in the workflow must stay in sync with the modules in
+6 -1
View File
@@ -12,7 +12,12 @@ plugins {
apiValidation {
@OptIn(ExperimentalBCVApi::class)
klib { enabled = true }
ignoredProjects.addAll(listOf("demo", "apidemo"))
// demo/apidemo: apps, no published API. sdl-core: naked SDL cinterop — its
// "API" is the generated sdl3.* bindings (per-OS, can't infer macos), not our
// surface. material-symbols: auto-generated icon codepoint maps + its jvm
// dump trips BCV's ASM on newer JDKs (class file major 69). Track the
// hand-authored Compose surface, not generated/binding code.
ignoredProjects.addAll(listOf("demo", "apidemo", "sdl-core", "material-symbols"))
}
// Version is driven by PUBLISH_VERSION (set from the git tag in the publish
@@ -6,4 +6,30 @@
// - Show declarations: true
// Library unique name: <com.bitsycore.compose:desktop-native-window>
final fun com.compose.desktop.native/nativeComposeWindow(kotlin/String = ..., kotlin/Int = ..., kotlin/Int = ..., com.compose.desktop.native/GpuMode = ..., kotlin/Function2<com.compose.desktop.native/RenderBackend, kotlin/Int, kotlin/Boolean>? = ..., kotlin/Function3<com.compose.desktop.native/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.desktop.native/nativeComposeWindow|nativeComposeWindow(kotlin.String;kotlin.Int;kotlin.Int;com.compose.desktop.native.GpuMode;kotlin.Function2<com.compose.desktop.native.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.desktop.native.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
abstract interface com.compose.sdl/ApplicationScope { // com.compose.sdl/ApplicationScope|null[0]
abstract fun exitApplication() // com.compose.sdl/ApplicationScope.exitApplication|exitApplication(){}[0]
}
final class com.compose.sdl/AppWindowIcon { // com.compose.sdl/AppWindowIcon|null[0]
constructor <init>(kotlin.collections/List<kotlin/String>, kotlin.collections/List<kotlin/String> = ...) // com.compose.sdl/AppWindowIcon.<init>|<init>(kotlin.collections.List<kotlin.String>;kotlin.collections.List<kotlin.String>){}[0]
final val dark // com.compose.sdl/AppWindowIcon.dark|{}dark[0]
final fun <get-dark>(): kotlin.collections/List<kotlin/String> // com.compose.sdl/AppWindowIcon.dark.<get-dark>|<get-dark>(){}[0]
final val light // com.compose.sdl/AppWindowIcon.light|{}light[0]
final fun <get-light>(): kotlin.collections/List<kotlin/String> // com.compose.sdl/AppWindowIcon.light.<get-light>|<get-light>(){}[0]
}
final val com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop // com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop|#static{}com_compose_sdl_AppWindowIcon$stableprop[0]
final var com.compose.sdl/disableInfiniteAnimations // com.compose.sdl/disableInfiniteAnimations|{}disableInfiniteAnimations[0]
final fun <get-disableInfiniteAnimations>(): kotlin/Boolean // com.compose.sdl/disableInfiniteAnimations.<get-disableInfiniteAnimations>|<get-disableInfiniteAnimations>(){}[0]
final fun <set-disableInfiniteAnimations>(kotlin/Boolean) // com.compose.sdl/disableInfiniteAnimations.<set-disableInfiniteAnimations>|<set-disableInfiniteAnimations>(kotlin.Boolean){}[0]
final var com.compose.sdl/useVirtualFrameTime // com.compose.sdl/useVirtualFrameTime|{}useVirtualFrameTime[0]
final fun <get-useVirtualFrameTime>(): kotlin/Boolean // com.compose.sdl/useVirtualFrameTime.<get-useVirtualFrameTime>|<get-useVirtualFrameTime>(){}[0]
final fun <set-useVirtualFrameTime>(kotlin/Boolean) // com.compose.sdl/useVirtualFrameTime.<set-useVirtualFrameTime>|<set-useVirtualFrameTime>(kotlin.Boolean){}[0]
final fun (com.compose.sdl/ApplicationScope).com.compose.sdl/Window(kotlin/Function0<kotlin/Unit>, kotlin/String?, kotlin/Int, kotlin/Int, com.compose.sdl/GpuMode?, com.compose.sdl/AppWindowIcon?, kotlin/Function2<com.compose.sdl/RenderBackend, kotlin/Int, kotlin/Boolean>?, kotlin/Function3<com.compose.sdl/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl/Window|Window@com.compose.sdl.ApplicationScope(kotlin.Function0<kotlin.Unit>;kotlin.String?;kotlin.Int;kotlin.Int;com.compose.sdl.GpuMode?;com.compose.sdl.AppWindowIcon?;kotlin.Function2<com.compose.sdl.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.sdl.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppWindowIcon$stableprop_getter|com_compose_sdl_AppWindowIcon$stableprop_getter(){}[0]
final fun com.compose.sdl/nativeComposeApp(kotlin/Function3<com.compose.sdl/ApplicationScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.sdl/nativeComposeApp|nativeComposeApp(kotlin.Function3<com.compose.sdl.ApplicationScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
final fun com.compose.sdl/nativeComposeWindow(kotlin/String = ..., kotlin/Int = ..., kotlin/Int = ..., com.compose.sdl/GpuMode = ..., com.compose.sdl/AppWindowIcon? = ..., kotlin/Function2<com.compose.sdl/RenderBackend, kotlin/Int, kotlin/Boolean>? = ..., kotlin/Function3<com.compose.sdl/ComposeWindowScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.compose.sdl/nativeComposeWindow|nativeComposeWindow(kotlin.String;kotlin.Int;kotlin.Int;com.compose.sdl.GpuMode;com.compose.sdl.AppWindowIcon?;kotlin.Function2<com.compose.sdl.RenderBackend,kotlin.Int,kotlin.Boolean>?;kotlin.Function3<com.compose.sdl.ComposeWindowScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
final fun com.compose.sdl/windowHasInvalidations(): kotlin/Boolean // com.compose.sdl/windowHasInvalidations|windowHasInvalidations(){}[0]
@@ -0,0 +1,9 @@
package com.compose.sdl.core
// :sdl-core is the NAKED sdl3 cinterop (the bindings live in package `sdl3`, generated
// from src/nativeInterop/cinterop/sdl3.def). This marker exists so the native `main`
// compilation has at least one Kotlin declaration and therefore emits a publishable
// main klib. A cinterop-only module with zero Kotlin sources produces no main klib, and
// maven-publish's generateMetadataFileFor<Target>Publication then fails with
// FileNotFoundException on sdl-core-<target>Main-<version>.klib. Do not delete.
internal const val SDL_CORE_MODULE = "sdl-core"
File diff suppressed because it is too large Load Diff