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
26 changes: 22 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ jobs:

build_xcframeworks:
name: Build XCFrameworks
needs:
- fetch_prebuilts
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -91,8 +93,13 @@ jobs:
uses: gradle/actions/setup-gradle@v4
with:
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
- name: Download prebuilts
uses: actions/download-artifact@v5
with:
artifact-ids: ${{ needs.fetch_prebuilts.outputs.artifact_id }}
path: internal/prebuild-binaries/build/output/
- name: Build frameworks
run: "./gradlew internal:PowerSyncKotlin:buildRelease"
run: "./gradlew -PhasPrebuiltAssets=true internal:PowerSyncKotlin:buildRelease"

- uses: actions/upload-artifact@v4
with:
Expand All @@ -105,7 +112,7 @@ jobs:
add_assets:
permissions:
contents: write
needs: [draft_release, build_xcframeworks]
needs: [draft_release, build_xcframeworks, fetch_prebuilts]
name: Add assets to pending release
runs-on: ubuntu-latest
steps:
Expand All @@ -114,14 +121,25 @@ jobs:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
merge-multiple: true
- run: "ls -al"
name: XCFramework
- name: Download prebuilts
uses: actions/download-artifact@v5
with:
artifact-ids: ${{ needs.fetch_prebuilts.outputs.artifact_id }}
path: internal/prebuild-binaries/build/output/

- name: Archive prebuilts
run: |
find internal/prebuild-binaries/build/output
zip -r prebuilt_libraries.zip internal/prebuild-binaries/build/output/

- name: Upload XCFramework
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
gh release upload "${{ needs.draft_release.outputs.tag }}" PowersyncKotlinRelease.zip
gh release upload "${{ needs.draft_release.outputs.tag }}" prebuilt_libraries.zip

- name: "Update release description"
env:
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/docs-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ jobs:
validate-wrappers: true
- name: Build Docs
run: |
./gradlew --scan \
--no-configuration-cache \
-PGITHUB_PUBLISH_TOKEN=${{ secrets.GITHUB_TOKEN }} \
dokkaGenerate
./gradlew --scan dokkaGenerate
shell: bash
- name: Upload static files as artifact
id: deployment
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## 1.9.0 (unreleased)
## 1.9.0

- Updated user agent string formats to allow viewing version distributions in the new PowerSync dashboard.
- Sync options: `newClientImplementation` is now the default.
Expand Down
12 changes: 6 additions & 6 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ tasks.getByName<Delete>("clean") {

// Merges individual module docs into a single HTML output
dependencies {
dokka(project(":common:"))
dokka(project(":core:"))
dokka(project(":compose:"))
dokka(project(":integrations:room"))
dokka(project(":integrations:sqldelight"))
dokka(project(":integrations:supabase"))
dokka(projects.common)
dokka(projects.core)
dokka(projects.compose)
dokka(projects.integrations.room)
dokka(projects.integrations.sqldelight)
dokka(projects.integrations.supabase)
dokka(projects.sqlite3multipleciphers)
}

Expand Down
2 changes: 1 addition & 1 deletion compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ kotlin {

sourceSets {
commonMain.dependencies {
api(project(":core"))
api(projects.core)
implementation(compose.runtime)
}
androidMain.dependencies {
Expand Down
4 changes: 4 additions & 0 deletions core-tests-android/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
*;
}

-keep class androidx.test.** {
*;
}

-keep class androidx.tracing.Trace {
public static void beginSection(java.lang.String);
public static void endSection();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,18 @@
package com.powersync

import com.powersync.testutils.IntegrationTestHelpers
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.sqlite.SQLiteException
import androidx.sqlite.execSQL
import app.cash.turbine.turbineScope
import com.powersync.db.schema.Schema
import com.powersync.encryption.AndroidEncryptedDatabaseFactory
import com.powersync.encryption.Key
import com.powersync.testutils.UserRow
import kotlinx.coroutines.*
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class EncryptedDatabaseTest {

private val helpers = IntegrationTestHelpers(
InstrumentationRegistry.getInstrumentation().targetContext
)
@Test
fun testEncryptedDatabase() =
runTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext

val database = PowerSyncDatabase(
factory = AndroidEncryptedDatabaseFactory(
context,
Key.Passphrase("mykey")
),
schema = Schema(UserRow.table),
dbFilename = "encrypted_test",
)

assertEquals("chacha20", database.get("PRAGMA cipher") { it.getString(0)!! })

database.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf("Test", "test@example.org"),
)
database.close()

val unencryptedFactory = DatabaseDriverFactory(context)
val unencrypted = unencryptedFactory.openConnection("encrypted_test", null, false)

try {
unencrypted.execSQL("SELECT * FROM sqlite_schema")
throw IllegalStateException("Was able to read schema from encrypted database without supplying a key")
} catch (_: SQLiteException) {
// Expected
}
unencrypted.close()
}
fun testEncryptedDatabase() = helpers.testEncryptedDatabase()
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.powersync.testutils

import android.content.Context
import androidx.sqlite.SQLiteException
import androidx.sqlite.execSQL
import app.cash.turbine.turbineScope
import com.powersync.DatabaseDriverFactory
import com.powersync.PowerSyncDatabase
import com.powersync.PowerSyncException
import com.powersync.db.schema.Schema
import com.powersync.encryption.AndroidEncryptedDatabaseFactory
import com.powersync.encryption.Key
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -228,4 +232,36 @@ class IntegrationTestHelpers(private val context: Context) {
database.execute("INSERT INTO foo VALUES (?)", parameters = listOf(data))
}
}

fun testEncryptedDatabase() = runTest {
val database = PowerSyncDatabase(
factory = AndroidEncryptedDatabaseFactory(
context,
Key.Passphrase("mykey")
),
schema = Schema(UserRow.table),
dbFilename = "encrypted_test",
)

check(database.get("PRAGMA cipher") { it.getString(0)!! } == "chacha20") {
"Should be able to query PRAGMA cipher"
}

database.execute(
"INSERT INTO users (id, name, email) VALUES (uuid(), ?, ?)",
listOf("Test", "test@example.org"),
)
database.close()

val unencryptedFactory = DatabaseDriverFactory(context)
val unencrypted = unencryptedFactory.openConnection("encrypted_test", null, false)

try {
unencrypted.execSQL("SELECT * FROM sqlite_schema")
throw IllegalStateException("Was able to read schema from encrypted database without supplying a key")
} catch (_: SQLiteException) {
// Expected
}
unencrypted.close()
}
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ development=true
RELEASE_SIGNING_ENABLED=true
# Library config
GROUP=com.powersync
LIBRARY_VERSION=1.8.1
LIBRARY_VERSION=1.9.0
GITHUB_REPO=https://github.com/powersync-ja/powersync-kotlin.git
# POM
POM_URL=https://github.com/powersync-ja/powersync-kotlin/
Expand Down
2 changes: 1 addition & 1 deletion integrations/room/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ kotlin {
}

commonMain.dependencies {
api(project(":core"))
api(projects.common)
api(libs.androidx.room.runtime)
api(libs.androidx.sqlite.bundled)

Expand Down
3 changes: 2 additions & 1 deletion integrations/sqldelight/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ kotlin {

sourceSets {
commonMain.dependencies {
api(projects.core)
api(projects.common)
api(libs.sqldelight.runtime)
implementation(libs.kotlinx.coroutines.core)
}
Expand All @@ -28,6 +28,7 @@ kotlin {
dependencies {
// Separate project because SQLDelight can't generate code in test source sets.
implementation(projects.integrations.sqldelightTestDatabase)
implementation(projects.internal.testutils)

implementation(libs.kotlin.test)
implementation(libs.kotlinx.io)
Expand Down
4 changes: 3 additions & 1 deletion integrations/supabase/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ kotlin {

sourceSets {
commonMain.dependencies {
api(projects.core)
api(projects.common)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.supabase.client)
api(libs.supabase.auth)
Expand All @@ -38,6 +38,8 @@ kotlin {
dependsOn(commonTest.get())

dependencies {
implementation(projects.internal.testutils)

implementation(libs.kotlin.test)
implementation(libs.kotlinx.io)
implementation(libs.test.turbine)
Expand Down