diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 47049b6..e8a5706 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,31 +16,24 @@ jobs: runs-on: ${{matrix.os}} steps: - name: Checkout the repo - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/setup-java@v5 + - uses: actions/setup-java@dd06d9cba3e5552c54d9f8ea23572deb30010f7c # v6.0.0 with: distribution: "temurin" java-version: "17" + - name: Setup Gradle + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 + - name: Install msys2 if: matrix.os == 'windows-latest' - uses: msys2/setup-msys2@v2 + uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0 with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain libsqlite - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 - - - name: Cache konan - uses: actions/cache@v4 - with: - path: ~/.konan - key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} - restore-keys: | - ${{ runner.os }}-gradle- + install: mingw-w64-x86_64-sqlite3 + release: false - name: Update Environment Variables if: matrix.os == 'windows-latest' @@ -48,12 +41,7 @@ jobs: run: | echo "c:\msys64\mingw64\bin" >> $GITHUB_PATH - - name: Build - if: matrix.os != 'macOS-latest' + - name: Build and test run: ./gradlew build --no-daemon --stacktrace - - - name: Build and Test - if: matrix.os == 'macOS-latest' - run: ./gradlew build allTests --no-daemon --stacktrace env: GRADLE_OPTS: -Dorg.gradle.configureondemand=true -Dkotlin.incremental=false -Dorg.gradle.jvmargs="-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=512m" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 813972c..a303426 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,36 +1,23 @@ name: release -on: workflow_dispatch +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+" jobs: - release: + publish: runs-on: macos-latest steps: - name: Checkout the repo - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: touchlab/read-property@0.1 - id: version-name - with: - file: ./gradle.properties - property: VERSION_NAME - - - name: Echo Version - run: echo "${{ steps.version-name.outputs.propVal }}" - - - uses: actions/setup-java@v5 + - uses: actions/setup-java@dd06d9cba3e5552c54d9f8ea23572deb30010f7c # v6.0.0 with: distribution: "temurin" java-version: "17" - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 - - name: Cache konan - uses: actions/cache@v4 - with: - path: ~/.konan - key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} - restore-keys: | - ${{ runner.os }}-gradle- + - name: Setup Gradle + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Publish Artifacts to Maven Central run: ./gradlew publish --no-daemon --stacktrace --no-build-cache @@ -39,11 +26,18 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} + release: + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Create Release - if: ${{ contains(steps.version-name.outputs.propVal, 'SNAPSHOT') == false }} - uses: touchlab/release-action@v1.10.0 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: - tag: ${{ steps.version-name.outputs.propVal }} + generate_release_notes: true env: GRADLE_OPTS: -Dkotlin.incremental=false -Dorg.gradle.jvmargs="-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=512m" diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..b0cd23e --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,67 @@ +# Releasing + +SQLiter publishes `co.touchlab:sqliter-driver` to Maven Central. Releases are cut by pushing a release +tag. + +## Conventions + +- Tags are the bare version, no `v` prefix — `1.4.0`, not `v1.4.0`. +- The tag and `VERSION_NAME` must be identical. +- `main` sits on a `-SNAPSHOT` between releases. + +## Choosing the version + +Standard semver against the published API surface: + +- **Patch** — bug fixes, no public declarations added or changed. +- **Minor** — public declarations added. +- **Major** — public declarations removed or changed incompatibly. + +## Releasing + +Steps 1–6 are local. Nothing is published until you push the tag in step 7. + +1. **Confirm the working tree is clean and `main` is current.** +2. **Set the release version** in `gradle.properties`: + + ``` + VERSION_NAME=X.Y.Z + ``` + +3. **Commit.** + + ```bash + git commit -am "Prepare version X.Y.Z" + ``` + +4. **Tag that commit.** + + ```bash + git tag -a X.Y.Z -m "Version X.Y.Z" + ``` + +5. **Set the next development version.** Bump the patch and re-add the suffix in + `gradle.properties`: + + ``` + VERSION_NAME=-SNAPSHOT + ``` + + So releasing `1.4.1` leaves `main` on `VERSION_NAME=1.4.2-SNAPSHOT`. + +6. **Commit.** + + ```bash + git commit -am "Prepare next development version" + ``` + +7. **Push the branch first, then the tag.** Pushing the tag triggers the release, so push it last: + + ```bash + git push origin main + git push origin X.Y.Z + ``` + + Pushing requires bypassing main branch protections, if you're not set up to do this, you probably shouldn't be + publishing anyway + diff --git a/gradle.properties b/gradle.properties index fbaaede..3683cc7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ kotlin.code.style=official GROUP=co.touchlab -VERSION_NAME=1.4.0 +VERSION_NAME=1.4.1-SNAPSHOT KOTLIN_VERSION=2.2.10 kotlin.native.ignoreDisabledTargets=true diff --git a/sqliter-driver/build.gradle.kts b/sqliter-driver/build.gradle.kts index 0f9ec9a..02f9ea1 100644 --- a/sqliter-driver/build.gradle.kts +++ b/sqliter-driver/build.gradle.kts @@ -50,9 +50,11 @@ kotlin { target.compilerOptions { freeCompilerArgs.addAll( when { + // lld's default --no-allow-shlib-undefined fails the link with K/N's glibc. The symbols are + // only referenced by libsqlite3 itself and the system loader resolves them at runtime. HostManager.hostIsLinux -> listOf( "-linker-options", - "-lsqlite3 -L/usr/lib/x86_64-linux-gnu -L/usr/lib" + "-lsqlite3 -L/usr/lib/x86_64-linux-gnu -L/usr/lib --allow-shlib-undefined" ) HostManager.hostIsMingw -> listOf("-linker-options", "-lsqlite3 -Lc:\\msys64\\mingw64\\lib") @@ -83,11 +85,14 @@ mavenPublishing { publishToMavenCentral(automaticRelease = true) } -listOf( - "linuxX64Test", - "linuxArm64Test", - "linkDebugTestLinuxX64", - "linkDebugTestLinuxArm64", - "mingwX64Test", - "linkDebugTestMingwX64", -).forEach { tasks.findByName(it)?.enabled = false } +val disabledTestLinks = mutableListOf("linkDebugTestLinuxArm64") + +if (!HostManager.hostIsLinux) { + disabledTestLinks += "linkDebugTestLinuxX64" +} + +if (!HostManager.hostIsMingw) { + disabledTestLinks += "linkDebugTestMingwX64" +} + +disabledTestLinks.forEach { tasks.findByName(it)?.enabled = false } diff --git a/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt b/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt index c98594a..9bb59e2 100644 --- a/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt +++ b/sqliter-driver/src/nativeTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt @@ -28,20 +28,35 @@ class DatabaseConfigurationTest : BaseDatabaseTest(){ @Test fun databasePathRemovesExtraSlashes() { - val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "//tmp//") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + if (Platform.osFamily != OsFamily.WINDOWS) { + val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "//tmp//") + assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + } else { + // On Windows: produces "//tmp//\testdb" there, not "/tmp/testdb". + println("Skipped for windows see issue #140") + } } @Test fun databasePathRemovesFileUrlPrefix() { - val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "file:///tmp/") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + if (Platform.osFamily != OsFamily.WINDOWS) { + val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "file:///tmp/") + assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + } else { + // On Windows: produces "/tmp/\testdb" there, not "/tmp/testdb". + println("Skipped for windows see issue #140") + } } @Test fun databasePathRemovesFileUrlPrefixInCaps() { - val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "FILE:///tmp/") - assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + if (Platform.osFamily != OsFamily.WINDOWS) { + val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, "FILE:///tmp/") + assertEquals("/tmp/$TEST_DB_NAME", dbPathString) + } else { + // On Windows: produces "/tmp/\testdb" there, not "/tmp/testdb". + println("Skipped for windows see issue #140") + } } @Test