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
64 changes: 44 additions & 20 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,43 @@ permissions:
contents: read

jobs:
build:
uses: ./.github/workflows/gradle.yml
deploy:
needs: build
test:
uses: ./.github/workflows/test.yml
build-native:
name: Build native lib
strategy:
matrix:
include:
- target: publishAllPublicationsToSonatypeRepository
os: macos-latest
# FIXME: Our custom gradle plugin does not currently setup platform specific tasks
# - target: publishIosArm64PublicationToSonatypeRepository
# os: macos-latest
# - target: publishAndroidDebugPublicationToSonatypeRepository
# os: ubuntu-latest
# - target: publishAndroidReleasePublicationToSonatypeRepository
# os: ubuntu-latest
# - target: publishKotlinMultiplatformPublicationToSonatypeRepository
# os: ubuntu-latest
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Install cross-compiler
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
- name: Build native lib
run: |
./gradlew \
-PGITHUB_PUBLISH_TOKEN=${{ secrets.GITHUB_TOKEN }} \
-Ppowersync.binaries.cross-arch=true \
:core:cmakeJvmBuild
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.os }}
path: core/build/binaries/desktop/sqlite/
deploy:
needs: [test, build-native]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Validate Gradle Wrapper
Expand All @@ -39,20 +57,26 @@ jobs:
with:
java-version: '17'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3

- name: Download native binaries
uses: actions/download-artifact@v4
with:
path: core/binaries/desktop
merge-multiple: true
- name: Display downloaded files
run: ls -lR core/binaries/desktop
- name: Gradle publish
run: |
./gradlew \
${{ matrix.target }} \
-PGITHUB_PUBLISH_TOKEN="${{ secrets.GITHUB_TOKEN }}" \
-PsigningInMemoryKey="${{ secrets.SIGNING_KEY }}" \
-PsigningInMemoryKeyId="${{ secrets.SIGNING_KEY_ID }}" \
-PsigningInMemoryKeyPassword="${{ secrets.SIGNING_PASSWORD }}" \
-PcentralPortal.username="${{secrets.SONATYPE_USERNAME}}" \
-PcentralPortal.password="${{secrets.SONATYPE_PASSWORD}}"
-PcentralPortal.password="${{secrets.SONATYPE_PASSWORD}}" \
-Ppowersync.binaries.provided="true" \
publishAllPublicationsToSonatypeRepository
# This will change Package.swift in Github packages to direct to new maven central KMMBridge zip file
call-kmmbridge-publish:
needs: deploy
Expand Down
File renamed without changes.
7 changes: 5 additions & 2 deletions PowerSyncKotlin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import co.touchlab.faktory.artifactmanager.ArtifactManager
import co.touchlab.faktory.capitalized
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.ir.backend.js.compile
import java.net.URL
import java.security.MessageDigest

Expand Down Expand Up @@ -28,8 +29,10 @@ kotlin {
explicitApi()

targets.withType<KotlinNativeTarget> {
compilations.getByName("main") {
compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
compilations.named("main") {
compileTaskProvider {
compilerOptions.freeCompilerArgs.add("-Xexport-kdoc")
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ kotlin {
publishLibraryVariants("release", "debug")
}

jvm()

iosX64()
iosArm64()
iosSimulatorArm64()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.powersync.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.powersync.DatabaseDriverFactory

@Composable
public actual fun rememberDatabaseDriverFactory(): DatabaseDriverFactory =
remember {
DatabaseDriverFactory()
}
8 changes: 6 additions & 2 deletions connectors/supabase/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ kotlin {
publishLibraryVariants("release", "debug")
}

jvm()

targets.withType<KotlinNativeTarget> {
compilations.getByName("main") {
compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
compilations.named("main") {
compileTaskProvider {
compilerOptions.freeCompilerArgs.add("-Xexport-kdoc")
}
}
}

Expand Down
1 change: 1 addition & 0 deletions core/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
binaries/
174 changes: 168 additions & 6 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import app.cash.sqldelight.core.capitalize
import com.powersync.plugins.sonatype.setupGithubRepository
import de.undercouch.gradle.tasks.download.Download
import org.gradle.internal.os.OperatingSystem
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import java.util.*

plugins {
alias(libs.plugins.kotlinMultiplatform)
Expand All @@ -13,12 +16,12 @@ plugins {
alias(libs.plugins.mokkery)
}

val sqliteVersion = "3450000"
val sqliteVersion = "3450200"
val sqliteReleaseYear = "2024"

val sqliteSrcFolder =
project.layout.buildDirectory
.dir("interop/sqlite")
.dir("native/sqlite")
.get()

val downloadSQLiteSources by tasks.registering(Download::class) {
Expand Down Expand Up @@ -50,8 +53,13 @@ val unzipSQLiteSources by tasks.registering(Copy::class) {
val buildCInteropDef by tasks.registering {
dependsOn(unzipSQLiteSources)

val interopFolder =
project.layout.buildDirectory
.dir("interop/sqlite")
.get()

val cFile = sqliteSrcFolder.file("sqlite3.c").asFile
val defFile = sqliteSrcFolder.file("sqlite3.def").asFile
val defFile = interopFolder.file("sqlite3.def").asFile

doFirst {
defFile.writeText(
Expand All @@ -69,18 +77,21 @@ kotlin {
androidTarget {
publishLibraryVariants("release", "debug")
}
jvm()

iosX64()
iosArm64()
iosSimulatorArm64()

targets.withType<KotlinNativeTarget> {
compilations.getByName("main") {
compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
compilations.named("main") {
compileTaskProvider {
compilerOptions.freeCompilerArgs.add("-Xexport-kdoc")
}
cinterops.create("sqlite") {
val cInteropTask = tasks[interopProcessingTaskName]
cInteropTask.dependsOn(buildCInteropDef)
defFile =
definitionFile =
buildCInteropDef
.get()
.outputs.files.singleFile
Expand Down Expand Up @@ -118,6 +129,11 @@ kotlin {
implementation(libs.ktor.client.okhttp)
}

jvmMain.dependencies {
implementation(libs.ktor.client.okhttp)
implementation(libs.sqlite.jdbc)
}

iosMain.dependencies {
implementation(libs.ktor.client.ios)
}
Expand Down Expand Up @@ -159,6 +175,7 @@ android {
.get()
.toInt()

@Suppress("UnstableApiUsage")
externalNativeBuild {
cmake {
arguments.addAll(
Expand All @@ -177,6 +194,151 @@ android {
}
}

val os = OperatingSystem.current()
val binariesAreProvided = project.findProperty("powersync.binaries.provided") == "true"
val crossArch = project.findProperty("powersync.binaries.cross-arch") == "true"
val binariesFolder = project.layout.buildDirectory.dir("binaries/desktop")

if (binariesAreProvided && crossArch) {
error("powersync.binaries.provided and powersync.binaries.cross-arch must not be both defined.")
}

val getBinaries = if (binariesAreProvided) {
// Binaries for all OS must be provided (manually or by the CI) in binaries/desktop

val verifyPowersyncBinaries = tasks.register("verifyPowersyncBinaries") {
val directory = projectDir.resolve("binaries/desktop")
val binaries = listOf(
directory.resolve("libpowersync-sqlite_aarch64.so"),
directory.resolve("libpowersync-sqlite_x64.so"),
directory.resolve("libpowersync-sqlite_aarch64.dylib"),
directory.resolve("libpowersync-sqlite_x64.dylib"),
directory.resolve("powersync-sqlite_x64.dll"),
)
doLast {
binaries.forEach {
if (!it.exists()) error("File $it does not exist")
if (!it.isFile) error("File $it is not a regular file")
}
}
outputs.files(*binaries.toTypedArray())
}
verifyPowersyncBinaries
} else {
// Building locally for the current OS

val localProperties = Properties()
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.inputStream().use { localProperties.load(it) }
}
val cmakeExecutable = localProperties.getProperty("cmake.path") ?: "cmake"

fun registerCMakeTasks(
suffix: String,
vararg defines: String,
): TaskProvider<Exec> {
val cmakeConfigure = tasks.register<Exec>("cmakeJvmConfigure${suffix.capitalize()}") {
dependsOn(unzipSQLiteSources)
group = "cmake"
workingDir = layout.buildDirectory.dir("cmake/$suffix").get().asFile
inputs.files(
"src/jvmMain/cpp",
"src/jvmNative/cpp",
sqliteSrcFolder,
)
outputs.dir(workingDir)
executable = cmakeExecutable
args(listOf(file("src/jvmMain/cpp/CMakeLists.txt").absolutePath, "-DSUFFIX=$suffix", "-DCMAKE_BUILD_TYPE=Release") + defines.map { "-D$it" })
doFirst {
workingDir.mkdirs()
}
}

val cmakeBuild = tasks.register<Exec>("cmakeJvmBuild${suffix.capitalize()}") {
dependsOn(cmakeConfigure)
group = "cmake"
workingDir = layout.buildDirectory.dir("cmake/$suffix").get().asFile
inputs.files(
"src/jvmMain/cpp",
"src/jvmNative/cpp",
sqliteSrcFolder,
workingDir,
)
outputs.dir(workingDir.resolve(if (os.isWindows) "output/Release" else "output"))
executable = cmakeExecutable
args("--build", ".", "--config", "Release")
}

return cmakeBuild
}

val (aarch64, x64) = when {
os.isMacOsX -> {
val aarch64 = registerCMakeTasks("aarch64", "CMAKE_OSX_ARCHITECTURES=arm64")
val x64 = registerCMakeTasks("x64", "CMAKE_OSX_ARCHITECTURES=x86_64")
aarch64 to x64
}
os.isLinux -> {
val aarch64 = registerCMakeTasks("aarch64", "CMAKE_C_COMPILER=aarch64-linux-gnu-gcc", "CMAKE_CXX_COMPILER=aarch64-linux-gnu-g++")
val x64 = registerCMakeTasks("x64", "CMAKE_C_COMPILER=x86_64-linux-gnu-gcc", "CMAKE_CXX_COMPILER=x86_64-linux-gnu-g++")
aarch64 to x64
}
os.isWindows -> {
val x64 = registerCMakeTasks("x64")
null to x64
}
else -> error("Unknown operating system: $os")
}

val arch = System.getProperty("os.arch")
val cmakeJvmBuilds = when {
crossArch -> listOfNotNull(aarch64, x64)
arch == "aarch64" -> listOfNotNull(aarch64)
arch == "amd64" -> listOfNotNull(x64)
else -> error("Unknown architecture: $arch")
}

tasks.register<Copy>("cmakeJvmBuild") {
dependsOn(cmakeJvmBuilds)
group = "cmake"
from(cmakeJvmBuilds)
into(binariesFolder.map { it.dir("sqlite") })
}
}

val downloadPowersyncDesktopBinaries = tasks.register<Download>("downloadPowersyncDesktopBinaries") {
val coreVersion = libs.versions.powersync.core.get()
val linux_aarch64 = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v$coreVersion/libpowersync_aarch64.so"
val linux_x64 = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v$coreVersion/libpowersync_x64.so"
val macos_aarch64 = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v$coreVersion/libpowersync_aarch64.dylib"
val macos_x64 = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v$coreVersion/libpowersync_x64.dylib"
val windows_x64 = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v$coreVersion/powersync_x64.dll"
if (binariesAreProvided) {
src(listOf(linux_aarch64, linux_x64, macos_aarch64, macos_x64, windows_x64))
} else {
val (aarch64, x64) = when {
os.isLinux -> linux_aarch64 to linux_x64
os.isMacOsX -> macos_aarch64 to macos_x64
os.isWindows -> null to windows_x64
else -> error("Unknown operating system: $os")
}
val arch = System.getProperty("os.arch")
src(when {
crossArch -> listOfNotNull(aarch64, x64)
arch == "aarch64" -> listOfNotNull(aarch64)
arch == "amd64" -> listOfNotNull(x64)
else -> error("Unknown architecture: $arch")
})
}
dest(binariesFolder.map { it.dir("powersync") })
onlyIfModified(true)
}

tasks.named<ProcessResources>(kotlin.jvm().compilations["main"].processResourcesTaskName) {
from(getBinaries, downloadPowersyncDesktopBinaries)
}

afterEvaluate {
val buildTasks =
tasks.matching {
Expand Down
2 changes: 1 addition & 1 deletion core/src/androidMain/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
add_library(
${PACKAGE_NAME}
SHARED
sqlite_bindings.cpp
../../jvmNative/cpp/sqlite_bindings.cpp
"${SQLITE3_SRC_DIR}/sqlite3.c"
)

Expand Down
Loading
Loading