Raised version #39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build, Test and Release | |
| on: | |
| push: | |
| branches: | |
| - '**' | |
| tags-ignore: | |
| - '**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| id-token: write | |
| jobs: | |
| build: | |
| runs-on: ${{ matrix.os }} | |
| container: ${{ matrix.container && matrix.container || '' }} | |
| env: | |
| APIKEY: ${{ secrets.APIKEY }} | |
| GITHUB_TOKEN: ${{ github.token }} | |
| name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }}${{ matrix.variant && format('-{0}', matrix.variant) || '' }} build${{ matrix.skip_test != true && ( matrix.name != 'android' || matrix.arch == 'x86_64' ) && ' + test' || ''}} | |
| timeout-minutes: 60 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux | |
| variant: remote | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux | |
| variant: local | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux | |
| variant: full | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux | |
| variant: remote | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux | |
| variant: local | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux | |
| variant: full | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux-musl | |
| variant: remote | |
| container: alpine:latest | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux-musl | |
| variant: local | |
| container: alpine:latest | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: linux-musl | |
| variant: full | |
| container: alpine:latest | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux-musl | |
| variant: remote | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux-musl | |
| variant: local | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: ubuntu-22.04-arm | |
| arch: arm64 | |
| name: linux-musl | |
| variant: full | |
| - os: macos-15 | |
| name: macos | |
| variant: remote | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: macos-15 | |
| name: macos | |
| variant: local | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: macos-15 | |
| name: macos | |
| variant: full | |
| - os: macos-15 | |
| arch: x86_64 | |
| name: macos | |
| variant: remote | |
| make: ARCH=x86_64 OMIT_LOCAL_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| arch: x86_64 | |
| name: macos | |
| variant: local | |
| make: ARCH=x86_64 OMIT_REMOTE_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| arch: x86_64 | |
| name: macos | |
| variant: full | |
| make: ARCH=x86_64 | |
| skip_test: true | |
| - os: macos-15 | |
| arch: arm64 | |
| name: macos | |
| variant: remote | |
| make: ARCH=arm64 OMIT_LOCAL_ENGINE=1 | |
| - os: macos-15 | |
| arch: arm64 | |
| name: macos | |
| variant: local | |
| make: ARCH=arm64 OMIT_REMOTE_ENGINE=1 | |
| - os: macos-15 | |
| arch: arm64 | |
| name: macos | |
| variant: full | |
| make: ARCH=arm64 | |
| - os: windows-2022 | |
| arch: x86_64 | |
| name: windows | |
| variant: remote | |
| make: OMIT_LOCAL_ENGINE=1 | |
| - os: windows-2022 | |
| arch: x86_64 | |
| name: windows | |
| variant: local | |
| make: OMIT_REMOTE_ENGINE=1 | |
| - os: windows-2022 | |
| arch: x86_64 | |
| name: windows | |
| variant: full | |
| - os: ubuntu-22.04 | |
| arch: arm64-v8a | |
| name: android | |
| variant: remote | |
| make: PLATFORM=android ARCH=arm64-v8a OMIT_LOCAL_ENGINE=1 | |
| skip_test: true | |
| - os: ubuntu-22.04 | |
| arch: arm64-v8a | |
| name: android | |
| variant: local | |
| make: PLATFORM=android ARCH=arm64-v8a OMIT_REMOTE_ENGINE=1 | |
| skip_test: true | |
| - os: ubuntu-22.04 | |
| arch: arm64-v8a | |
| name: android | |
| variant: full | |
| make: PLATFORM=android ARCH=arm64-v8a | |
| skip_test: true | |
| # armeabi-v7a: remote only (llama.cpp not well supported) | |
| - os: ubuntu-22.04 | |
| arch: armeabi-v7a | |
| name: android | |
| variant: remote | |
| make: PLATFORM=android ARCH=armeabi-v7a OMIT_LOCAL_ENGINE=1 | |
| skip_test: true | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: android | |
| variant: remote | |
| make: PLATFORM=android ARCH=x86_64 OMIT_LOCAL_ENGINE=1 | |
| sqlite-amalgamation-zip: https://sqlite.org/2025/sqlite-amalgamation-3490100.zip | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: android | |
| variant: local | |
| make: PLATFORM=android ARCH=x86_64 OMIT_REMOTE_ENGINE=1 | |
| sqlite-amalgamation-zip: https://sqlite.org/2025/sqlite-amalgamation-3490100.zip | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| name: android | |
| variant: full | |
| make: PLATFORM=android ARCH=x86_64 | |
| sqlite-amalgamation-zip: https://sqlite.org/2025/sqlite-amalgamation-3490100.zip | |
| - os: macos-15 | |
| name: ios | |
| variant: remote | |
| make: PLATFORM=ios OMIT_LOCAL_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| name: ios | |
| variant: local | |
| make: PLATFORM=ios OMIT_REMOTE_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| name: ios | |
| variant: full | |
| make: PLATFORM=ios | |
| skip_test: true | |
| - os: macos-15 | |
| name: ios-sim | |
| variant: remote | |
| make: PLATFORM=ios-sim OMIT_LOCAL_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| name: ios-sim | |
| variant: local | |
| make: PLATFORM=ios-sim OMIT_REMOTE_ENGINE=1 | |
| skip_test: true | |
| - os: macos-15 | |
| name: ios-sim | |
| variant: full | |
| make: PLATFORM=ios-sim | |
| skip_test: true | |
| - os: macos-15 | |
| name: apple-xcframework | |
| make: xcframework | |
| skip_test: true | |
| - os: ubuntu-22.04 | |
| name: android-aar | |
| make: aar | |
| skip_test: true | |
| defaults: | |
| run: | |
| shell: ${{ matrix.container && 'sh' || 'bash' }} | |
| steps: | |
| - name: linux-musl x86_64 install dependencies | |
| if: matrix.name == 'linux-musl' && matrix.arch == 'x86_64' && matrix.container | |
| run: apk update && apk add --no-cache gcc g++ make cmake sqlite sqlite-dev musl-dev linux-headers git curl openssl-dev | |
| - uses: actions/checkout@v4.2.2 | |
| with: | |
| submodules: ${{ !contains(matrix.make, 'OMIT_LOCAL_ENGINE=1') && 'true' || 'false' }} | |
| - uses: msys2/setup-msys2@v2.27.0 | |
| if: matrix.name == 'windows' | |
| with: | |
| msystem: mingw64 | |
| install: >- | |
| git | |
| make | |
| mingw-w64-x86_64-sqlite3 | |
| mingw-w64-x86_64-cc | |
| mingw-w64-x86_64-cmake | |
| - name: linux install dependencies | |
| if: matrix.name == 'linux' | |
| run: sudo apt-get update && sudo apt-get install -y libssl-dev | |
| - name: macos install dependencies | |
| if: matrix.name == 'macos' | |
| run: brew link sqlite --force | |
| - name: linux-musl arm64 setup container | |
| if: matrix.name == 'linux-musl' && matrix.arch == 'arm64' | |
| run: | | |
| docker run -d --name alpine \ | |
| --platform linux/arm64 \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -w /workspace \ | |
| -e APIKEY=${{ secrets.APIKEY }} \ | |
| -e GITHUB_TOKEN=${{ github.token }} \ | |
| alpine:latest \ | |
| tail -f /dev/null | |
| docker exec alpine sh -c "apk update && apk add --no-cache gcc g++ make cmake sqlite sqlite-dev musl-dev linux-headers git curl openssl-dev" | |
| - name: android-aar setup java | |
| if: matrix.name == 'android-aar' | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: unix build sqlite-memory | |
| if: matrix.os != 'windows-2022' && matrix.name != 'apple-xcframework' && matrix.name != 'android-aar' | |
| run: ${{ matrix.name == 'linux-musl' && matrix.arch == 'arm64' && 'docker exec alpine' || '' }} make extension ${{ matrix.make && matrix.make || ''}} | |
| - name: build apple-xcframework | |
| if: matrix.name == 'apple-xcframework' | |
| run: make ${{ matrix.make }} | |
| - name: build android-aar | |
| if: matrix.name == 'android-aar' | |
| run: make ${{ matrix.make }} | |
| - name: windows build sqlite-memory | |
| if: matrix.name == 'windows' | |
| shell: msys2 {0} | |
| run: make extension ${{ matrix.make && matrix.make || ''}} | |
| - name: create keychain for codesign | |
| if: matrix.os == 'macos-15' | |
| run: | | |
| echo "${{ secrets.APPLE_CERTIFICATE }}" | base64 --decode > certificate.p12 | |
| security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" build.keychain | |
| security import certificate.p12 -k build.keychain -P "${{ secrets.CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" build.keychain | |
| - name: codesign and notarize dylib | |
| if: matrix.os == 'macos-15' && matrix.name != 'apple-xcframework' | |
| run: | | |
| codesign --sign "${{ secrets.APPLE_TEAM_ID }}" --timestamp --options runtime dist/memory.dylib | |
| ditto -c -k dist/memory.dylib dist/memory.zip | |
| xcrun notarytool submit dist/memory.zip --apple-id "${{ secrets.APPLE_ID }}" --password "${{ secrets.APPLE_PASSWORD }}" --team-id "${{ secrets.APPLE_TEAM_ID }}" --wait | |
| rm dist/memory.zip | |
| - name: codesign and notarize xcframeworks | |
| if: matrix.name == 'apple-xcframework' | |
| run: | | |
| for variant in remote local full; do | |
| echo "Signing memory-${variant}.xcframework..." | |
| find dist/memory-${variant}.xcframework -name "*.framework" -exec echo "Signing: {}" \; -exec codesign --sign "${{ secrets.APPLE_TEAM_ID }}" --timestamp --options runtime {} \; | |
| codesign --sign "${{ secrets.APPLE_TEAM_ID }}" --timestamp --options runtime dist/memory-${variant}.xcframework | |
| ditto -c -k --keepParent dist/memory-${variant}.xcframework dist/memory-${variant}.xcframework.zip | |
| xcrun notarytool submit dist/memory-${variant}.xcframework.zip --apple-id "${{ secrets.APPLE_ID }}" --password "${{ secrets.APPLE_PASSWORD }}" --team-id "${{ secrets.APPLE_TEAM_ID }}" --wait | |
| rm dist/memory-${variant}.xcframework.zip | |
| done | |
| - name: cleanup keychain for codesign | |
| if: matrix.os == 'macos-15' | |
| run: | | |
| rm certificate.p12 | |
| security delete-keychain build.keychain | |
| - name: android setup test environment | |
| if: matrix.name == 'android' && matrix.arch == 'x86_64' | |
| run: | | |
| echo "::group::enable kvm group perms" | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| echo "::endgroup::" | |
| echo "::group::download sqlite3 amalgamation" | |
| curl -O ${{ matrix.sqlite-amalgamation-zip }} | |
| unzip sqlite-amalgamation-*.zip | |
| rm sqlite-amalgamation-*.zip | |
| SQLITE_DIR=$(ls -d sqlite-amalgamation-*) | |
| echo "::endgroup::" | |
| echo "::group::build sqlite3 shell for android" | |
| $ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.arch }}-linux-android26-clang ${SQLITE_DIR}/shell.c ${SQLITE_DIR}/sqlite3.c -o sqlite3 -ldl | |
| echo "::endgroup::" | |
| echo "::group::build unittest binary for android" | |
| make build/unittest ${{ matrix.make }} SQLITE_AMALGAM=${SQLITE_DIR}/sqlite3.c | |
| echo "::endgroup::" | |
| echo "::group::build e2e binary for android" | |
| make build/e2e ${{ matrix.make }} SQLITE_AMALGAM=${SQLITE_DIR}/sqlite3.c | |
| echo "::endgroup::" | |
| if [ "${{ matrix.variant }}" != "local" ]; then | |
| echo "::group::download sqlite-vector for android e2e" | |
| make build/vector.so ${{ matrix.make }} | |
| echo "::endgroup::" | |
| fi | |
| - name: android test sqlite-memory | |
| if: matrix.name == 'android' && matrix.arch == 'x86_64' | |
| uses: reactivecircus/android-emulator-runner@v2.34.0 | |
| with: | |
| api-level: 26 | |
| arch: ${{ matrix.arch }} | |
| script: | | |
| set -e | |
| adb root | |
| adb remount | |
| adb push ${{ github.workspace }}/sqlite3 /data/local/tmp/ | |
| adb shell "mv -f /data/local/tmp/sqlite3 /system/xbin/" | |
| adb push ${{ github.workspace }}/dist/memory.so /data/local/tmp/ | |
| adb push ${{ github.workspace }}/build/unittest /data/local/tmp/ | |
| adb shell "chmod +x /data/local/tmp/unittest" | |
| echo "Running unit tests..." | |
| adb shell "/data/local/tmp/unittest" | |
| echo "Testing extension loading..." | |
| adb shell "sqlite3 :memory: '.load /data/local/tmp/memory.so' 'SELECT memory_version();'" | |
| echo "Extension loading test passed!" | |
| [ "${{ matrix.variant }}" = "local" ] || adb push ${{ github.workspace }}/build/e2e /data/local/tmp/ | |
| [ "${{ matrix.variant }}" = "local" ] || adb push ${{ github.workspace }}/build/vector.so /data/local/tmp/ | |
| [ "${{ matrix.variant }}" = "local" ] || adb shell "chmod +x /data/local/tmp/e2e" | |
| [ "${{ matrix.variant }}" = "local" ] || echo "Running e2e tests..." | |
| [ "${{ matrix.variant }}" = "local" ] || adb shell "APIKEY=$APIKEY VECTOR_LIB=/data/local/tmp/vector /data/local/tmp/e2e" | |
| [ "${{ matrix.variant }}" = "local" ] || echo "E2E tests passed!" | |
| - name: unix test sqlite-memory | |
| if: matrix.skip_test != true && matrix.os != 'windows-2022' && matrix.name != 'android' | |
| run: ${{ matrix.name == 'linux-musl' && matrix.arch == 'arm64' && 'docker exec alpine' || '' }} make test ${{ matrix.make && matrix.make || ''}} | |
| - name: windows test sqlite-memory | |
| if: matrix.skip_test != true && matrix.name == 'windows' | |
| shell: msys2 {0} | |
| run: make test ${{ matrix.make && matrix.make || ''}} | |
| - name: unix e2e sqlite-memory | |
| if: matrix.skip_test != true && matrix.variant != 'local' && matrix.os != 'windows-2022' && matrix.name != 'android' | |
| run: ${{ matrix.name == 'linux-musl' && matrix.arch == 'arm64' && 'docker exec alpine' || '' }} make e2e ${{ matrix.make && matrix.make || ''}} | |
| - name: windows e2e sqlite-memory | |
| if: matrix.skip_test != true && matrix.variant != 'local' && matrix.name == 'windows' | |
| shell: msys2 {0} | |
| run: make e2e ${{ matrix.make && matrix.make || ''}} | |
| - uses: actions/upload-artifact@v4.6.2 | |
| if: always() | |
| with: | |
| name: memory-${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }}${{ matrix.variant && format('-{0}', matrix.variant) || '' }} | |
| path: | | |
| dist/memory.* | |
| dist/memory-*.xcframework | |
| if-no-files-found: error | |
| release: | |
| runs-on: ubuntu-22.04 | |
| name: release | |
| needs: build | |
| if: github.ref == 'refs/heads/main' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@v4.2.2 | |
| - uses: actions/download-artifact@v4.2.1 | |
| with: | |
| path: artifacts | |
| - name: zip artifacts | |
| run: | | |
| VERSION=$(make version) | |
| for folder in "artifacts"/*; do | |
| if [ -d "$folder" ]; then | |
| name=$(basename "$folder") | |
| if [[ "$name" == "memory-apple-xcframework" ]]; then | |
| for variant in remote local full; do | |
| (cd "$folder" && zip -rq "../../memory-apple-xcframework-${variant}-${VERSION}.zip" memory-${variant}.xcframework) | |
| done | |
| elif [[ "$name" == "memory-android-aar" ]]; then | |
| cp "$folder"/*.aar "${name}-${VERSION}.aar" | |
| else | |
| tar -czf "${name}-${VERSION}.tar.gz" -C "$folder" . | |
| (cd "$folder" && zip -rq "../../${name}-${VERSION}.zip" .) | |
| fi | |
| fi | |
| done | |
| - name: release tag version from sqlite-memory.h | |
| id: tag | |
| run: | | |
| VERSION=$(make version) | |
| if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| LATEST_RELEASE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/releases/latest) | |
| LATEST=$(echo "$LATEST_RELEASE" | jq -r '.name') | |
| if [[ "$VERSION" != "$LATEST" || "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| else | |
| echo "::warning file=src/sqlite-memory.h::To release a new version, please update the SQLITE_DBMEMORY_VERSION in src/sqlite-memory.h to be different than the latest $LATEST" | |
| fi | |
| exit 0 | |
| fi | |
| echo "❌ SQLITE_DBMEMORY_VERSION not found in sqlite-memory.h" | |
| exit 1 | |
| - uses: actions/checkout@v4.2.2 | |
| if: steps.tag.outputs.version != '' | |
| with: | |
| repository: sqliteai/sqlite-wasm | |
| path: sqlite-wasm | |
| submodules: recursive | |
| token: ${{ secrets.RELEASE_PAT }} | |
| - name: release sqlite-wasm | |
| if: steps.tag.outputs.version != '' | |
| run: | | |
| cd sqlite-wasm | |
| git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" | |
| git config --global user.name "$GITHUB_ACTOR" | |
| cd modules/sqlite-memory | |
| git checkout ${{ github.sha }} | |
| cd ../.. | |
| git add modules/sqlite-memory | |
| PKG=sqlite-wasm/package.json | |
| TMP=sqlite-wasm/package.tmp.json | |
| jq --arg version "$(cat modules/sqlite/VERSION)-sync.$(cd modules/sqlite-sync && make version)-vector.$(cd modules/sqlite-vector && make version)-memory.$(cd modules/sqlite-memory && make version)" '.version = $version' "$PKG" > "$TMP" && mv "$TMP" "$PKG" | |
| git add "$PKG" | |
| git commit -m "Bump sqlite-memory version to ${{ steps.tag.outputs.version }}" | |
| git push origin main | |
| - uses: softprops/action-gh-release@v2.2.1 | |
| if: steps.tag.outputs.version != '' | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| body: | | |
| # sqlite-memory v${{ steps.tag.outputs.version }} | |
| ## Packages | |
| - **Apple XCFramework** (iOS + iOS Simulator + macOS): | |
| - `memory-apple-xcframework-remote` - Remote embeddings only | |
| - `memory-apple-xcframework-local` - Local embeddings (llama.cpp + Metal GPU) | |
| - `memory-apple-xcframework-full` - Both remote and local | |
| - **Android AAR** (arm64-v8a + x86_64): | |
| - `memory-android-aar` - Contains all 3 variants: `memory_remote.so`, `memory_local.so`, `memory_full.so` | |
| ## Build Variants | |
| - **remote**: Remote embeddings only (smallest, requires network) | |
| - **local**: Local embeddings only via llama.cpp (no network required) | |
| - **full**: Both remote and local embeddings (most flexible) | |
| --- | |
| generate_release_notes: true | |
| tag_name: ${{ steps.tag.outputs.version }} | |
| files: memory-*-${{ steps.tag.outputs.version }}.* | |
| make_latest: true |