Skip to content
Open
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
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,50 @@ jobs:
steps.changes.outputs.windows != 'true'
shell: pwsh
run: '"No Windows desktop or build-system changes; native Windows validation was skipped." >> $env:GITHUB_STEP_SUMMARY'

macos-sqlite-runtime:
name: Intel macOS SQLite runtime
runs-on: macos-15-intel
timeout-minutes: 45
steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Detect SQLite packaging changes
id: changes
continue-on-error: true
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
with:
filters: |
sqlite:
- ".github/workflows/ci.yml"
- "gradle/**"
- "gradle.properties"
- "build.gradle.kts"
- "settings.gradle.kts"
- "ui/build.gradle.kts"
- "ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/app/DesktopSqliteRuntime.kt"
- "ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/Main.kt"
- "ui/src/desktopTest/kotlin/dev/obiente/nextcloudnative/app/DesktopSqliteRuntimeTest.kt"

- name: Set up JDK 21
if: >-
github.event_name == 'workflow_dispatch' ||
steps.changes.outcome != 'success' ||
steps.changes.outputs.sqlite == 'true'
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: "21"
cache: gradle

- name: Verify Intel macOS SQLite in tests and the packaged app
if: >-
github.event_name == 'workflow_dispatch' ||
steps.changes.outcome != 'success' ||
steps.changes.outputs.sqlite == 'true'
run: |
./gradlew --no-daemon :ui:desktopTest --tests '*DesktopSqliteRuntimeTest' :ui:createDistributable
launcher=$(find ui/build/compose/binaries/main/app -type f -path '*/Contents/MacOS/nati.ve' -print -quit)
test -n "$launcher"
"$launcher" --verify-sqlite-runtime
8 changes: 8 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ jobs:
fi
exit "${status}"

- name: Verify packaged macOS SQLite runtime
if: matrix.platform == 'macos'
shell: bash
run: |
launcher=$(find ui/build/compose/binaries/main/app -type f -path '*/Contents/MacOS/nati.ve' -print -quit)
test -n "$launcher"
"$launcher" --verify-sqlite-runtime

- name: Verify unsigned Windows MSI
if: matrix.platform == 'windows'
shell: pwsh
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ jobs:
fi
exit "${status}"

- name: Verify packaged macOS SQLite runtime
if: matrix.platform == 'macos'
shell: bash
run: |
launcher=$(find ui/build/compose/binaries/main/app -type f -path '*/Contents/MacOS/nati.ve' -print -quit)
test -n "$launcher"
"$launcher" --verify-sqlite-runtime

- name: Verify unsigned Windows MSI
if: matrix.platform == 'windows'
shell: pwsh
Expand Down
11 changes: 11 additions & 0 deletions PLATFORMS.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,14 @@ bundles; the DMG does not migrate an existing bundle automatically.
These names describe source packaging configuration, not confirmation that a
release containing it has been published. Check the
[release artifacts](https://github.com/Obiente/native/releases) for availability.

## Desktop SQLite runtime verification

The JVM SQLite dependency is constrained to 2.6.2 because the 2.7.0 and 2.7.1
artifacts omit the Intel macOS native library. `DesktopSqliteRuntimeTest` checks
the native resources for each packaged desktop architecture and opens an
in-memory database on the test host. An Intel macOS CI job validates relevant
dependency and packaging changes. Nightly and prerelease macOS packages run their
launcher with `--verify-sqlite-runtime`, before creating application services.
This check does not inspect accounts or modify user databases. A resource check
on one OS does not establish runtime validation on another OS.
7 changes: 7 additions & 0 deletions changes/unreleased/459-intel-macos-sqlite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
category: fix
issue: 459
pull: 469
platforms: desktop
user-facing: yes

Restore the bundled SQLite library for Intel Macs so folder-sync and media-backup databases can open, and verify native runtime resources before packaging.
7 changes: 7 additions & 0 deletions changes/unreleased/media-route-account-ownership.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
category: security
issue: 172
pull: none
platforms: android, desktop
user-facing: yes

Media viewer routes are scoped to their owning account and cleared when that account is removed, preventing retained media from reopening through another account or after removal.
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ media3 = "1.10.1"
libvlc = "3.7.5"
javafx = "21.0.12"
jse = "1.1.0"
sqlite = "2.7.0"
# SQLite 2.7 JVM artifacts omit the Intel macOS native library.
sqlite = { strictly = "2.6.2" }

[libraries]
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
Expand Down
6 changes: 3 additions & 3 deletions tools/test-marketing-capture-workflow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ for stale_gate in \
fi
done

scope_detector_count="$(grep -Ec '^ - name: Detect (build scopes|Windows desktop changes)$' "$ci")"
scope_detector_count="$(grep -Ec '^ - name: Detect (build scopes|Windows desktop changes|SQLite packaging changes)$' "$ci")"
continued_detector_count="$(grep -Fc 'continue-on-error: true' "$ci")"
if [[ "$scope_detector_count" -ne 2 || "$continued_detector_count" -ne 2 ]]; then
printf 'Build scope detection must degrade safely for both build jobs.\n' >&2
if [[ "$scope_detector_count" -ne 3 || "$continued_detector_count" -ne 3 ]]; then
printf 'Build scope detection must degrade safely for all three build jobs.\n' >&2
exit 1
fi
require_text "$ci" "steps.changes.outcome != 'success'"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.obiente.nextcloudnative.app

import androidx.sqlite.driver.bundled.BundledSQLiteDriver

/** Runs before application services and only uses an in-memory database. */
internal fun verifyDesktopSqliteRuntime() {
BundledSQLiteDriver().open(":memory:").use { connection ->
connection.prepare("SELECT sqlite_version()").use { statement ->
check(statement.step()) { "SQLite runtime verification returned no version." }
check(statement.getText(0).isNotBlank()) { "SQLite runtime verification returned an empty version." }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ import javax.swing.SwingUtilities
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

fun main(arguments: Array<String>) = runDesktopEntryPoint(arguments)
fun main(arguments: Array<String>) {
if (arguments.contentEquals(arrayOf("--verify-sqlite-runtime"))) {
dev.obiente.nextcloudnative.app.verifyDesktopSqliteRuntime()
return
}
runDesktopEntryPoint(arguments)
}

@OptIn(ExperimentalComposeUiApi::class)
internal fun runDesktopEntryPoint(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.obiente.nextcloudnative.app

import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import kotlin.test.Test
import kotlin.test.assertNotNull

class DesktopSqliteRuntimeTest {
@Test fun distributedDriverIncludesEverySupportedDesktopBinary() {
val loader = BundledSQLiteDriver::class.java.classLoader
listOf(
"linux_x64/libsqliteJni.so",
"linux_arm64/libsqliteJni.so",
"osx_x64/libsqliteJni.dylib",
"osx_arm64/libsqliteJni.dylib",
"windows_x64/sqliteJni.dll",
).forEach { binary ->
assertNotNull(loader.getResource("natives/$binary"), "Missing SQLite runtime: $binary")
}
}

@Test fun nativeDriverCanOpenAndQueryTheRuntime() = verifyDesktopSqliteRuntime()
}
6 changes: 3 additions & 3 deletions website/public/screenshots/capture-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@
"captureSourceHashes": {
"build.gradle.kts": "de2d98f7fce24b2bc67423bb06aa88d251e1458b1fa3c9c9700dbb14289edbf0",
"gradle.properties": "99c3ee1a9d68a2548830e7dca0cc4b02f4acf408bfc394a0acd55e7865c53739",
"gradle/libs.versions.toml": "10ef19d481e525d0ad1e94c9a74abe0a4caca6572cf7d2d0dadabfba3974ab5a",
"gradle/libs.versions.toml": "69ed47ea88842a0097cc7dc5273016d8954e668763618976a9b781efe2915dda",
"gradle/wrapper/gradle-wrapper.properties": "aef287d114ce3153c3d535697a61928f5034990d570cbb2e93df549e9671483d",
"settings.gradle.kts": "0acbe4b907815189abfedb2256c8659558e5a7e6995a3681a2bdfb05e335fd1a",
"tools/marketing-capture-inputs.txt": "3c96e83e1ba2d715b1cda9cedf036fc97b78c3ca63b7fc930325ed536940c1f3",
Expand Down Expand Up @@ -656,7 +656,7 @@
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudResponseLimits.kt": "fead6cbf4f723ea46f99c9155b190967205d24f198687b7bfd5a213c474374b8",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudSession.kt": "792a381fd5eefc44e13eb73ee95a80f8d52e8dcec9d3876ba06ec5392b5c1f81",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudSessionLoading.kt": "12339db06d73f7bb689de6cbf4a4a2ec8e1ffe8c6f10ca627390829b3907a716",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudStatusMessages.kt": "22883b8d93d9b1efa389f4857fe5a1e20140fb4a6914d2b93ac94a59d4470d93",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudStatusMessages.kt": "9236bf9c8f959d794e5756ac260232e24a6fb4e9372bb04cc6d2028d71f1ec05",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NotesApi.kt": "e3c685b02592ea791b0c9a478a098fc5bf428893aa4764110c793a78040f341e",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NotesFolderOperations.kt": "db6a04cfcd3b25b17c996cdc6dba21847d14f5970e06e6c24a3e2c85139dbe1d",
"ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/OfficeDocumentWorkflow.kt": "2ddc486b9a948ed1ff5de48d64471df54d55f2bdb055e2446da79b5fb656cdf3",
Expand Down Expand Up @@ -835,7 +835,7 @@
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/DynamicBoardInteractionPreviewMain.kt": "7402f5b4bf3bbf3cf20761eaa10eca9131fb6e63da2988d0aa6038942d706c53",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/FileSyncTrayVisualQaMain.kt": "4ce39ce3a53b72a32ca7489ef65cf301e9d8279f4be9ef9afc3ace701075c301",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/FileSyncWorkspaceVisualQaMain.kt": "af79af05554e41806121b49f7fe8e31a67127636f0faec78f44ac812726c86e0",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/Main.kt": "37681a229096d46fd1eb06a8f969c22a2903e765b6b4eefb887be7b8dea461ad",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/Main.kt": "b6f26394074b06186397d381dc7b20dc4690c36fd37865df5134377188520936",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/MarketingCaptureMain.kt": "bd7f6b8870c0030f061c5e466849b597f3388df6e9b4c5a6987000bb0dc0fbdf",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/MarketingCaptureOwnership.kt": "c5bd9b63793a8884cf6b74cadf3061dc0ac295a982c97ae7f0a906ac3ae6f3c9",
"ui/src/desktopMain/kotlin/dev/obiente/nextcloudnative/nativeui/preview/NativeTiffMarketingCapture.kt": "6970352c6e42d09b793c55ea296991d756d232f216d8d152aa00319b2ddb8d20",
Expand Down