Skip to content

fix(workflow): streamline installation of build dependencies for linu… #369

fix(workflow): streamline installation of build dependencies for linu…

fix(workflow): streamline installation of build dependencies for linu… #369

Workflow file for this run

name: build, test and release sqlite-sync
on:
push:
workflow_dispatch:
permissions:
contents: write
pages: write
id-token: write
jobs:
build:
runs-on: ${{ matrix.os }}
container: ${{ matrix.container && matrix.container || '' }}
name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }} build${{ matrix.arch != 'arm64-v8a' && matrix.name != 'ios-sim' && matrix.name != 'ios' && matrix.name != 'wasm' && matrix.name != 'apple-xcframework' && ' + test' || ''}}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
arch: x86_64
name: linux
- os: LinuxARM64
arch: arm64
name: linux
- os: macos-latest
name: macos
- os: windows-latest
arch: x86_64
name: windows
- os: ubuntu-latest
arch: arm64-v8a
name: android
make: PLATFORM=android ARCH=arm64-v8a
- os: ubuntu-latest
arch: x86_64
name: android
make: PLATFORM=android ARCH=x86_64
sqlite-amalgamation-zip: https://sqlite.org/2025/sqlite-amalgamation-3490100.zip
- os: macos-latest
name: ios
make: PLATFORM=ios
- os: macos-latest
name: ios-sim
make: PLATFORM=ios-sim
- os: ubuntu-latest
name: wasm
make: PLATFORM=wasm
- os: macos-latest
name: apple-xcframework
make: xcframework
- os: ubuntu-latest
arch: x86_64
name: linux-musl
container: alpine:latest
- os: ubuntu-24.04-arm
arch: arm64
name: linux-musl
container: alpine:latest
defaults:
run:
shell: ${{ matrix.name == 'linux-musl' && 'sh' || 'bash' }}
env:
CONNECTION_STRING: ${{ secrets.CONNECTION_STRING }}
APIKEY: ${{ secrets.APIKEY }}
WEBLITE: ${{ secrets.WEBLITE }}
steps:
- uses: actions/[email protected]
if: matrix.name != 'linux-musl' || matrix.arch != 'arm64'
- uses: msys2/[email protected]
if: matrix.os == 'windows-latest'
with:
msystem: mingw64
install: mingw-w64-x86_64-cc make
- name: linux-musl install dependencies
if: matrix.name == 'linux-musl'
run: apk update && apk add --no-cache git gcc make curl sqlite openssl-dev musl-dev linux-headers
- name: linux-musl arm64 checkout
if: matrix.name == 'linux-musl' && matrix.arch == 'arm64'
run: |
git config --global --add safe.directory '*'
git clone https://github.com/${{ github.repository }}.git .
git checkout ${{ github.sha }}
- name: windows build curl
if: matrix.os == 'windows-latest'
run: make curl/windows/libcurl.a
shell: msys2 {0}
- name: wasm install wabt
if: matrix.name == 'wasm'
run: sudo apt install wabt
- name: build sqlite-sync
run: make extension ${{ matrix.make && matrix.make || ''}}
- name: windows install sqlite3
if: matrix.os == 'windows-latest'
run: choco install sqlite -y
- name: macos install sqlite3 without SQLITE_OMIT_LOAD_EXTENSION
if: matrix.name == 'macos'
run: brew link sqlite --force
- name: android setup test environment
if: matrix.name == 'android' && matrix.arch != 'arm64-v8a'
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 and build sqlite3 without SQLITE_OMIT_LOAD_EXTENSION"
curl -O ${{ matrix.sqlite-amalgamation-zip }}
unzip sqlite-amalgamation-*.zip
export ${{ matrix.make }}
$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.arch }}-linux-android26-clang sqlite-amalgamation-*/shell.c sqlite-amalgamation-*/sqlite3.c -o sqlite3 -ldl
# remove unused folders to save up space
rm -rf sqlite-amalgamation-*.zip sqlite-amalgamation-* openssl
echo "::endgroup::"
echo "::group::prepare the test script"
make test PLATFORM=$PLATFORM ARCH=$ARCH || echo "It should fail. Running remaining commands in the emulator"
cat > commands.sh << EOF
mv -f /data/local/tmp/sqlite3 /system/xbin
cd /data/local/tmp
export CONNECTION_STRING="$CONNECTION_STRING"
export APIKEY="$APIKEY"
export WEBLITE="$WEBLITE"
$(make test PLATFORM=$PLATFORM ARCH=$ARCH -n)
EOF
echo "::endgroup::"
- name: android test sqlite-sync
if: matrix.name == 'android' && matrix.arch != 'arm64-v8a'
uses: reactivecircus/[email protected]
with:
api-level: 26
arch: ${{ matrix.arch }}
script: |
adb root
adb remount
adb push ${{ github.workspace }}/. /data/local/tmp/
adb shell "sh /data/local/tmp/commands.sh"
- name: test sqlite-sync
if: contains(matrix.name, 'linux') || matrix.name == 'windows'
run: make test
- name: test sqlite-sync + coverage
if: matrix.name == 'macos'
run: brew install lcov && make test COVERAGE=true
- uses: actions/[email protected]
if: matrix.name == 'macos'
with:
path: coverage
- uses: actions/[email protected]
if: always()
with:
name: cloudsync-${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }}
path: dist/${{ matrix.name == 'wasm' && 'sqlite-wasm.zip' || 'cloudsync.*'}}
if-no-files-found: error
release:
runs-on: ubuntu-latest
name: release
needs: build
if: github.ref == 'refs/heads/main'
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/[email protected]
- uses: actions/[email protected]
with:
path: artifacts
- name: setup GitHub Pages
uses: actions/configure-pages@v5
- name: deploy coverage to GitHub Pages
uses: actions/[email protected]
- name: release tag version from cloudsync.h
id: tag
run: |
VERSION=$(make version)
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
LATEST=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r '.name')
if [[ "$VERSION" != "$LATEST" || "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
echo "version=$VERSION" >> $GITHUB_OUTPUT
else
echo "::warning file=src/cloudsync.h::To release a new version, please update the CLOUDSYNC_VERSION in src/cloudsync.h to be different than the latest $LATEST"
fi
exit 0
fi
echo "❌ CLOUDSYNC_VERSION not found in cloudsync.h"
exit 1
- uses: actions/setup-node@v4
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
- name: zip artifacts
run: |
for folder in "artifacts"/*; do
if [ -d "$folder" ]; then
name=$(basename "$folder")
if [[ "$name" != "github-pages" && "$name" != "cloudsync-wasm" ]]; then
(cd "$folder" && zip -rq "../../${name}-${{ steps.tag.outputs.version }}.zip" .)
tar -czf "${name}-${{ steps.tag.outputs.version }}.tar.gz" -C "$folder" .
fi
fi
done
cp artifacts/cloudsync-wasm/sqlite-wasm.zip "sqlite-$(make sqlite_version)-sync-${{ steps.tag.outputs.version }}-wasm.zip"
- name: wasm publish to npmjs
if: steps.tag.outputs.version != ''
run: |
TAG=$(git ls-remote --tags https://github.com/sqlite/sqlite-wasm.git | \
awk -v ver=$(make sqlite_version) -F'/' '$NF ~ ver"-build[0-9]+$" {print $NF}' | \
sort -V | \
tail -n1)
git clone --branch "$TAG" --depth 1 https://github.com/sqlite/sqlite-wasm.git sqlite-wasm
rm -rf sqlite-wasm/sqlite-wasm/*
unzip artifacts/cloudsync-wasm/sqlite-wasm.zip -d sqlite-wasm/tmp
mv sqlite-wasm/tmp/sqlite-wasm-*/jswasm sqlite-wasm/sqlite-wasm
cd sqlite-wasm && npm i && npm run fix && npm run publint && npm run check-types && cd ..
PKG=sqlite-wasm/package.json
TMP=sqlite-wasm/package.tmp.json
DESC="SQLite Wasm compiled with the automatically initialized sqlite-sync extension. Conveniently packaged as an ES Module for effortless integration."
jq \
--arg name "@sqliteai/sqlite-sync-wasm" \
--arg version "$(make sqlite_version)-sync-$(make version)" \
--arg desc "$DESC" \
--argjson keywords '["sync","offsync","cloudsync","sqliteai"]' \
--arg repo_url "git+https://github.com/sqliteai/sqlite-sync.git" \
--arg author "Gioele Cantoni ([email protected])" \
--arg bugs_url "https://github.com/sqliteai/sqlite-sync/issues" \
--arg homepage "https://github.com/sqliteai/sqlite-sync#readme" \
'
.name = $name
| .version = $version
| .description = $desc
| .keywords += $keywords
| del(.bin)
| .scripts |= with_entries(select(
.key != "build"
and .key != "start"
and .key != "start:node"
and .key != "prepublishOnly"
and .key != "deploy"
))
| .repository.url = $repo_url
| .author = $author
| .bugs.url = $bugs_url
| .homepage = $homepage
| del(.devDependencies.decompress)
| del(.devDependencies["http-server"])
| del(.devDependencies.shx)
' "$PKG" > "$TMP" && mv "$TMP" "$PKG"
sed 's/@sqlite\.org\/sqlite-wasm/@sqliteai\/sqlite-sync-wasm/g' sqlite-wasm/README.md > sqlite-wasm/README.tmp
echo -e "# sqlite-sync WASM $(make version)\nThis README and the TypeScript types are from the [official SQLite wasm repository](https://github.com/sqlite/sqlite-wasm)\n\n$(cat sqlite-wasm/README.tmp)" > sqlite-wasm/README.md
rm -rf sqlite-wasm/tmp sqlite-wasm/bin sqlite-wasm/demo sqlite-wasm/README.tmp sqlite-wasm/package-lock.json
cd sqlite-wasm && npm publish --access public
#add --provenance to npm publish when the repo will be public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: softprops/[email protected]
if: steps.tag.outputs.version != ''
with:
generate_release_notes: true
tag_name: ${{ steps.tag.outputs.version }}
files: |
cloudsync-*-${{ steps.tag.outputs.version }}.zip
cloudsync-*-${{ steps.tag.outputs.version }}.tar.gz
sqlite-*-sync-${{ steps.tag.outputs.version }}-wasm.zip
make_latest: true