Compare commits

...

5 Commits

Author SHA1 Message Date
dependabot[bot]
ab970e281c
Merge d48b0a2f65 into fa9b42cf10 2026-10-29 17:18:59 +00:00
Kingkor Roy Tirtho
fa9b42cf10 cd(build): add support for building WebView native libraries on Linux and Windows 2026-10-29 16:03:55 +06:00
Kingkor Roy Tirtho
8d4ea82a7e fix(build): add headless mode for Linux and update CI to prepare dependencies 2026-10-29 15:01:43 +06:00
Kingkor Roy Tirtho
eb972c8633 fix(dependencies): update Android target SDK and various library versions 2026-10-29 11:25:22 +06:00
dependabot[bot]
d48b0a2f65
chore(deps): bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-09 23:42:25 +00:00
3 changed files with 153 additions and 47 deletions

View File

@ -12,6 +12,19 @@ on:
- stable - stable
- beta - beta
- nightly - nightly
platform:
description: 'Platform to build (nightly only; stable and beta always build everything)'
required: true
type: choice
default: 'all'
options:
- all
- android
- linux-x86_64
- linux-aarch64
- windows
- macos
- ios
dry_run: dry_run:
description: 'Dry run (build & upload artifacts only, skip creating release)' description: 'Dry run (build & upload artifacts only, skip creating release)'
required: false required: false
@ -29,16 +42,94 @@ permissions:
# Never cancel a running release when another is dispatched, and let stable, beta and nightly run side by side # Never cancel a running release when another is dispatched, and let stable, beta and nightly run side by side
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.release_type }} group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.release_type }}-${{ inputs.platform }}
cancel-in-progress: false cancel-in-progress: false
env: env:
COMPOSE_WEBVIEW_REPO: KRTirtho/ComposeNativeWebview COMPOSE_WEBVIEW_REPO: KRTirtho/ComposeNativeWebview
COMPOSE_WEBVIEW_COMMIT: cbd36f88927298a28a2d64c6acf7ec3b2def6f9d # fix/linux-wayland-input
COMPOSE_WEBVIEW_COMMIT: b11ac748de1219f9432338c067a2c5dafef3072a
jobs: jobs:
validate-inputs:
name: Validate Inputs
runs-on: ubuntu-latest
steps:
- name: Single platform builds are nightly only
if: ${{ inputs.platform != 'all' && inputs.release_type != 'nightly' }}
run: |
echo "::error::Building a single platform is only supported for nightly releases"
exit 1
# ComposeNativeWebview's JNI backends are gitignored and only built for the host OS, so a
# publish from macOS alone ships a jar without the Linux / Windows WebView libraries (the
# WebView then renders nothing). Build them on their own OS and hand them to prepare-deps.
build-webview-natives:
name: WebView Natives (${{ matrix.name }})
needs: validate-inputs
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
include:
- name: linux-x64
os: ubuntu-latest
- name: linux-aarch64
os: ubuntu-24.04-arm
- name: windows-x64
os: windows-latest
steps:
- name: Checkout ComposeNativeWebview
uses: actions/checkout@v7
with:
repository: ${{ env.COMPOSE_WEBVIEW_REPO }}
ref: ${{ env.COMPOSE_WEBVIEW_COMMIT }}
token: ${{ secrets.GITHUB_TOKEN }}
path: compose-webview
- name: Set up JDK 21
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: 21
- name: Build Linux WebView native library
if: runner.os == 'Linux'
working-directory: compose-webview
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libgtk-3-dev libcairo2-dev \
libsoup-3.0-dev libwebkit2gtk-4.1-dev
bash webview-compose/src/jvmMain/native/linux/build.sh
- name: Build Windows WebView native library
if: runner.os == 'Windows'
working-directory: compose-webview
shell: cmd
run: webview-compose\src\jvmMain\native\windows\build.bat
- name: Verify WebView native library
working-directory: compose-webview
shell: bash
run: |
case "${{ matrix.name }}" in
linux-*) files="${{ matrix.name }}/libcompose_webview_linux.so" ;;
windows-x64) files="win32-x64/compose_webview_windows.dll win32-x64/WebView2Loader.dll" ;;
esac
for f in $files; do
test -f "webview-compose/src/jvmMain/resources/nucleus/native/$f" || { echo "::error::Missing $f"; exit 1; }
done
- name: Upload WebView native library
uses: actions/upload-artifact@v7
with:
name: webview-natives-${{ matrix.name }}
path: compose-webview/webview-compose/src/jvmMain/resources/nucleus/native/
retention-days: 1
prepare-deps: prepare-deps:
name: Prepare Dependencies name: Prepare Dependencies
needs: [validate-inputs, build-webview-natives]
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Checkout ComposeNativeWebview - name: Checkout ComposeNativeWebview
@ -49,6 +140,15 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
path: compose-webview path: compose-webview
# Downloaded after checkout, so they are newer than the native sources and
# the build keeps them instead of trying to rebuild on the wrong OS.
- name: Download WebView native libraries
uses: actions/download-artifact@v8
with:
pattern: webview-natives-*
merge-multiple: true
path: compose-webview/webview-compose/src/jvmMain/resources/nucleus/native
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v6 uses: actions/setup-java@v6
with: with:
@ -70,6 +170,16 @@ jobs:
chmod +x gradlew chmod +x gradlew
./gradlew publishToMavenLocal ./gradlew publishToMavenLocal
- name: Verify published JVM jar carries every WebView backend
run: |
jar=$(ls ~/.m2/repository/dev/nucleusframework/composewebview-jvm/*/composewebview-jvm-*.jar | grep -v -e sources -e javadoc | head -1)
contents=$(unzip -l "$jar")
for f in linux-x64/libcompose_webview_linux.so linux-aarch64/libcompose_webview_linux.so \
win32-x64/compose_webview_windows.dll win32-x64/WebView2Loader.dll \
darwin-aarch64/libcompose_webview_macos.dylib darwin-x64/libcompose_webview_macos.dylib; do
grep -q "nucleus/native/$f" <<< "$contents" || { echo "::error::$jar is missing $f"; exit 1; }
done
- name: Upload maven local - name: Upload maven local
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v7
with: with:
@ -78,7 +188,8 @@ jobs:
build-android: build-android:
name: Android name: Android
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'android' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -152,7 +263,8 @@ jobs:
build-linux: build-linux:
name: Linux Desktop name: Linux Desktop
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'linux-x86_64' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -161,17 +273,17 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y rpm fuse build-essential zlib1g-dev patchelf zstd
- name: Download maven local - name: Download maven local
uses: actions/download-artifact@v8 uses: actions/download-artifact@v8
with: with:
name: maven-local name: maven-local
path: ~/.m2/repository/ path: ~/.m2/repository/
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y rpm fuse build-essential zlib1g-dev patchelf zstd
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v6 uses: actions/setup-java@v6
with: with:
@ -265,7 +377,8 @@ jobs:
build-linux-arm64: build-linux-arm64:
name: Linux Desktop (aarch64) name: Linux Desktop (aarch64)
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'linux-aarch64' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: ubuntu-24.04-arm runs-on: ubuntu-24.04-arm
steps: steps:
@ -281,17 +394,17 @@ jobs:
with: with:
packages: tools platform-tools ndk;28.2.13676358 packages: tools platform-tools ndk;28.2.13676358
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y rpm fuse build-essential zlib1g-dev patchelf zstd
- name: Download maven local - name: Download maven local
uses: actions/download-artifact@v8 uses: actions/download-artifact@v8
with: with:
name: maven-local name: maven-local
path: ~/.m2/repository/ path: ~/.m2/repository/
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y rpm fuse build-essential zlib1g-dev patchelf zstd
- name: Set up JDK 21 - name: Set up JDK 21
uses: actions/setup-java@v6 uses: actions/setup-java@v6
with: with:
@ -385,7 +498,8 @@ jobs:
build-windows: build-windows:
name: Windows Desktop name: Windows Desktop
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'windows' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: windows-latest runs-on: windows-latest
steps: steps:
@ -448,7 +562,8 @@ jobs:
build-macos: build-macos:
name: macOS Desktop name: macOS Desktop
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'macos' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: macos-latest runs-on: macos-latest
steps: steps:
@ -516,7 +631,8 @@ jobs:
build-ios: build-ios:
name: iOS name: iOS
needs: prepare-deps needs: [validate-inputs, prepare-deps]
if: ${{ inputs.platform == 'all' || inputs.platform == 'ios' }}
timeout-minutes: 120 timeout-minutes: 120
runs-on: macos-latest runs-on: macos-latest
steps: steps:
@ -585,8 +701,11 @@ jobs:
create-release: create-release:
name: Create GitHub Release name: Create GitHub Release
if: ${{ !inputs.dry_run }} # Skipped platform jobs count as skipped, not failed, so a single platform build still releases
if: ${{ !inputs.dry_run && !cancelled() && !contains(needs.*.result, 'failure') }}
needs: needs:
- validate-inputs
- prepare-deps
- build-android - build-android
- build-linux - build-linux
- build-linux-arm64 - build-linux-arm64
@ -599,7 +718,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
# The build resolves its plugins from mavenLocal, so Gradle needs the same setup as the build jobs
- name: Download maven local - name: Download maven local
uses: actions/download-artifact@v8 uses: actions/download-artifact@v8
with: with:
@ -639,6 +757,7 @@ jobs:
uses: actions/download-artifact@v8 uses: actions/download-artifact@v8
- name: Generate release notes - name: Generate release notes
if: ${{ inputs.platform == 'all' }}
run: | run: |
echo "## Downloads" > release-notes.md echo "## Downloads" > release-notes.md
echo "" >> release-notes.md echo "" >> release-notes.md
@ -658,9 +777,12 @@ jobs:
tag_name: ${{ steps.vars.outputs.tag }} tag_name: ${{ steps.vars.outputs.tag }}
# A new tag (stable) would otherwise point at the default branch instead of the built commit # A new tag (stable) would otherwise point at the default branch instead of the built commit
target_commitish: ${{ github.sha }} target_commitish: ${{ github.sha }}
fail_on_unmatched_files: true # A single platform build only has its own artifacts
name: ${{ steps.vars.outputs.release_name }} fail_on_unmatched_files: ${{ inputs.platform == 'all' }}
body_path: release-notes.md # A single platform build only replaces that platform's assets (same file names are overwritten),
# so leave the existing release's name and notes alone
name: ${{ inputs.platform == 'all' && steps.vars.outputs.release_name || '' }}
body_path: ${{ inputs.platform == 'all' && 'release-notes.md' || '' }}
draft: ${{ steps.vars.outputs.is_draft }} draft: ${{ steps.vars.outputs.is_draft }}
prerelease: ${{ steps.vars.outputs.is_prerelease }} prerelease: ${{ steps.vars.outputs.is_prerelease }}
files: | files: |

View File

@ -646,6 +646,12 @@ tasks.withType<ComposeHotRun>().configureEach {
jvmArgs( jvmArgs(
"--enable-native-access=ALL-UNNAMED" "--enable-native-access=ALL-UNNAMED"
) )
// Linux: the hot-reload agent starts AWT before main(), and JBR's X11 toolkit pins GTK to
// XWayland, where the embedded WebKit WebView renders black. Tao owns the windows, so the
// reloadable JVM stays headless (DevTools runs in its own JVM and is unaffected).
if (System.getProperty("os.name").lowercase().contains("linux")) {
jvmArgs("-Djava.awt.headless=true")
}
systemProperty( systemProperty(
"compose.application.resources.dir", "compose.application.resources.dir",
project.layout.buildDirectory.dir("compose/tmp/prepareAppResources").get() project.layout.buildDirectory.dir("compose/tmp/prepareAppResources").get()

View File

@ -14,16 +14,12 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
[versions] [versions]
agp = "9.1.0"
android-compileSdk = "37" android-compileSdk = "37"
android-minSdk = "28" android-minSdk = "28"
android-targetSdk = "36" android-targetSdk = "37"
agp = "9.1.0"
androidx-activity = "1.13.0" androidx-activity = "1.13.0"
androidx-appcompat = "1.7.1"
androidx-core = "1.19.0"
androidx-espresso = "3.7.0"
androidx-lifecycle = "2.10.0" androidx-lifecycle = "2.10.0"
androidx-testExt = "1.3.0"
appdirs = "1.5.0" appdirs = "1.5.0"
cache4k = "0.14.0" cache4k = "0.14.0"
carApp = "1.7.0" carApp = "1.7.0"
@ -34,12 +30,10 @@ composeShimmer = "1.5.0"
desugar_jdk_libs = "2.1.5" desugar_jdk_libs = "2.1.5"
haze = "2.0.0-alpha03" haze = "2.0.0-alpha03"
jna = "5.18.1" jna = "5.18.1"
junit = "4.13.2"
kermit = "2.1.0" kermit = "2.1.0"
kmpZip = "1.0.0" kmpZip = "1.0.0"
kotlin = "2.4.21" kotlin = "2.4.21"
kotlinx-coroutines = "1.11.0" kotlinx-coroutines = "1.11.0"
kotlinx-io = "0.9.1"
kotlinx-serialization-json = "1.11.0" kotlinx-serialization-json = "1.11.0"
millennium = "0.1.1" millennium = "0.1.1"
mqttClient = "2.1.1" mqttClient = "2.1.1"
@ -55,27 +49,22 @@ vlcjNative = "4.12.0"
ziplineVersion = "1.28.0" ziplineVersion = "1.28.0"
ktor = "3.5.1" ktor = "3.5.1"
dnssdkt = "1.1.0" dnssdkt = "1.1.0"
runner = "1.7.0"
core = "1.7.0"
filekit = "0.14.2" filekit = "0.14.2"
compose-webview = "0.1.0-SNAPSHOT" compose-webview = "0.1.0-SNAPSHOT"
composeNativeTray = "2.1.6" composeNativeTray = "2.1.6"
koin = "4.2.2" koin = "4.2.2"
multiplatform-nav3-ui = "1.1.1" multiplatform-nav3-ui = "1.1.1"
compose-multiplatform-adaptive = "1.3.0-alpha05"
compose-multiplatform-lifecycle = "2.10.0" compose-multiplatform-lifecycle = "2.10.0"
feather-icons = "1.1.1" feather-icons = "1.1.1"
kotlinx-datetime = "0.8.0" kotlinx-datetime = "0.8.0"
media3 = "1.10.1" media3 = "1.10.1"
androidx-datastore = "1.2.1" androidx-datastore = "1.2.1"
ksp = "2.3.12"
spotube-gradle = "0.1.2" spotube-gradle = "0.1.2"
cryptography = "0.6.0" cryptography = "0.6.0"
reorderable = "3.1.0" reorderable = "3.1.0"
vlcjBundler = "0.2.1" vlcjBundler = "0.2.1"
vanniktechMavenPublish = "0.37.0" vanniktechMavenPublish = "0.37.0"
uniffi = "0.3.7" uniffi = "0.3.7"
kotlinx-atomicfu = "0.33.0"
mokkery = "3.5.1" mokkery = "3.5.1"
jmustache = "1.16" jmustache = "1.16"
@ -98,12 +87,6 @@ kmp-zip = { module = "no.synth:kmp-zip", version.ref = "kmpZip" }
kmp-zip-kotlinx = { module = "no.synth:kmp-zip-kotlinx", version.ref = "kmpZip" } kmp-zip-kotlinx = { module = "no.synth:kmp-zip-kotlinx", version.ref = "kmpZip" }
kmp-zip-okio = { module = "no.synth:kmp-zip-okio", version.ref = "kmpZip" } kmp-zip-okio = { module = "no.synth:kmp-zip-okio", version.ref = "kmpZip" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
junit = { module = "junit:junit", version.ref = "junit" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-testExt-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-testExt" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
compose-uiTooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "composeMultiplatform" } compose-uiTooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "composeMultiplatform" }
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
@ -153,8 +136,6 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
androidx-runner = { group = "androidx.test", name = "runner", version.ref = "runner" }
androidx-core = { group = "androidx.test", name = "core", version.ref = "core" }
filekit-core = { group = "io.github.vinceglb", name = "filekit-core", version.ref = "filekit" } filekit-core = { group = "io.github.vinceglb", name = "filekit-core", version.ref = "filekit" }
filekit-dialogs = { group = "io.github.vinceglb", name = "filekit-dialogs", version.ref = "filekit" } filekit-dialogs = { group = "io.github.vinceglb", name = "filekit-dialogs", version.ref = "filekit" }
filekit-dialogs-compose = { group = "io.github.vinceglb", name = "filekit-dialogs-compose", version.ref = "filekit" } filekit-dialogs-compose = { group = "io.github.vinceglb", name = "filekit-dialogs-compose", version.ref = "filekit" }
@ -170,7 +151,6 @@ feather-icons = { module = "br.com.devsrsouza.compose.icons:feather", version.re
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
androidx-datastore = { module = "androidx.datastore:datastore", version.ref = "androidx-datastore" } androidx-datastore = { module = "androidx.datastore:datastore", version.ref = "androidx-datastore" }
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "androidx-datastore" } androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "androidx-datastore" }
kotlinx-io-okio = { module = "org.jetbrains.kotlinx:kotlinx-io-okio", version.ref = "kotlinx-io" }
cryptography-core = { module = "dev.whyoleg.cryptography:cryptography-core", version.ref = "cryptography" } cryptography-core = { module = "dev.whyoleg.cryptography:cryptography-core", version.ref = "cryptography" }
cryptography-provider-optimal = { module = "dev.whyoleg.cryptography:cryptography-provider-optimal", version.ref = "cryptography" } cryptography-provider-optimal = { module = "dev.whyoleg.cryptography:cryptography-provider-optimal", version.ref = "cryptography" }
reorderable = { module = "sh.calvin.reorderable:reorderable", version.ref = "reorderable" } reorderable = { module = "sh.calvin.reorderable:reorderable", version.ref = "reorderable" }
@ -189,10 +169,8 @@ kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", versio
jetbrainsKotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } jetbrainsKotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
zipline-gradle-plugin = { id = "app.cash.zipline", version.ref = "ziplineVersion" } zipline-gradle-plugin = { id = "app.cash.zipline", version.ref = "ziplineVersion" }
mavenPublish = { id = "maven-publish" }
spotubeGradle = { id = "org.spotube.gradle-plugin", version.ref = "spotube-gradle" } spotubeGradle = { id = "org.spotube.gradle-plugin", version.ref = "spotube-gradle" }
vlcjBundler = { id = "org.spotube.vlcj-bundler", version.ref = "vlcjBundler" } vlcjBundler = { id = "org.spotube.vlcj-bundler", version.ref = "vlcjBundler" }
kotlinxAtomicFu = { id = "org.jetbrains.kotlinx.atomicfu", version.ref = "kotlinx-atomicfu" }
uniffi = { id = "dev.gobley.uniffi", version.ref = "uniffi" } uniffi = { id = "dev.gobley.uniffi", version.ref = "uniffi" }
cargo = { id = "dev.gobley.cargo", version.ref = "uniffi" } cargo = { id = "dev.gobley.cargo", version.ref = "uniffi" }
mokkery = { id = "dev.mokkery", version.ref = "mokkery" } mokkery = { id = "dev.mokkery", version.ref = "mokkery" }