Skip to content

Raised version

Raised version #39

Workflow file for this run

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