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
135 changes: 135 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,141 @@ jobs:
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}

vfs-build-linux:
name: Build VFS (Linux ${{ matrix.arch }})
runs-on: ubuntu-20.04 # Use older Ubuntu for broader glibc compatibility (2.31)
needs: goreleaser
strategy:
matrix:
arch: [amd64, arm64]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Install cross-compiler (arm64)
if: matrix.arch == 'arm64'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu

- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "version=${{ inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi

- name: Build VFS extension
run: make vfs-linux-${{ matrix.arch }}

- name: Verify artifact
run: |
file dist/litestream-vfs-linux-${{ matrix.arch }}.so
# For native arch, verify it can be loaded by SQLite
if [ "${{ matrix.arch }}" == "amd64" ]; then
sqlite3 ':memory:' ".load dist/litestream-vfs-linux-amd64.so" ".exit" && echo "Extension loads successfully"
fi
# For cross-compiled arch, verify ELF header and architecture
if [ "${{ matrix.arch }}" == "arm64" ]; then
readelf -h dist/litestream-vfs-linux-arm64.so | grep -E "(Class|Machine)"
echo "ARM64 ELF header verified"
fi

- name: Create archive
run: |
cd dist
cp litestream-vfs-linux-${{ matrix.arch }}.so litestream.so
tar -czvf litestream-vfs-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz \
litestream.so

- name: Generate checksum
run: |
cd dist
sha256sum litestream-vfs-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz \
> litestream-vfs-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz.sha256

- name: Upload to release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ steps.version.outputs.version }} \
dist/litestream-vfs-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz \
dist/litestream-vfs-${{ steps.version.outputs.version }}-linux-${{ matrix.arch }}.tar.gz.sha256 \
--clobber

vfs-build-darwin:
name: Build VFS (macOS ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
needs: goreleaser
strategy:
matrix:
include:
- arch: amd64
runner: macos-13
- arch: arm64
runner: macos-14
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "version=${{ inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi

- name: Build VFS extension
run: make vfs-darwin-${{ matrix.arch }}

- name: Verify artifact
run: |
file dist/litestream-vfs-darwin-${{ matrix.arch }}.dylib
# Verify the extension can be loaded by SQLite
sqlite3 ':memory:' ".load dist/litestream-vfs-darwin-${{ matrix.arch }}.dylib" ".exit" && echo "Extension loads successfully"

- name: Create archive
run: |
cd dist
cp litestream-vfs-darwin-${{ matrix.arch }}.dylib litestream.dylib
tar -czvf litestream-vfs-${{ steps.version.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz \
litestream.dylib

- name: Generate checksum
run: |
cd dist
shasum -a 256 litestream-vfs-${{ steps.version.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz \
> litestream-vfs-${{ steps.version.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz.sha256

- name: Upload to release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ steps.version.outputs.version }} \
dist/litestream-vfs-${{ steps.version.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz \
dist/litestream-vfs-${{ steps.version.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz.sha256 \
--clobber

# macos-sign:
# runs-on: macos-latest
# needs: goreleaser
Expand Down
11 changes: 11 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ release:
### Binary installation
Download the appropriate archive for your platform, extract, and move to your PATH.

## VFS Extension (Experimental)

SQLite loadable extensions for read-only access to Litestream replicas are available for supported platforms:

| Platform | File |
|----------|------|
| Linux x86_64 | `litestream-vfs-v{{.Version}}-linux-amd64.tar.gz` |
| Linux ARM64 | `litestream-vfs-v{{.Version}}-linux-arm64.tar.gz` |
| macOS Intel | `litestream-vfs-v{{.Version}}-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `litestream-vfs-v{{.Version}}-darwin-arm64.tar.gz` |

# Signing configuration
# signs:
# - id: macos
Expand Down
44 changes: 44 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,57 @@ default:
docker:
docker build -t litestream .

# VFS build configuration
VFS_BUILD_TAGS := vfs,SQLITE3VFS_LOADABLE_EXT
VFS_SRC := ./cmd/litestream-vfs
VFS_C_SRC := src/litestream-vfs.c
MACOSX_MIN_VERSION := 11.0
DARWIN_LDFLAGS := -framework CoreFoundation -framework Security -lresolv -mmacosx-version-min=$(MACOSX_MIN_VERSION)
LINUX_LDFLAGS := -lpthread -ldl -lm

.PHONY: vfs
vfs:
mkdir -p dist
go build -tags vfs,SQLITE3VFS_LOADABLE_EXT -o dist/litestream-vfs.a -buildmode=c-archive ./cmd/litestream-vfs
mv dist/litestream-vfs.h src/litestream-vfs.h
gcc -framework CoreFoundation -framework Security -lresolv -g -fPIC -shared -o dist/litestream-vfs.so src/litestream-vfs.c dist/litestream-vfs.a

.PHONY: vfs-linux-amd64
vfs-linux-amd64:
mkdir -p dist
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -tags $(VFS_BUILD_TAGS) -o dist/litestream-vfs-linux-amd64.a -buildmode=c-archive $(VFS_SRC)
cp dist/litestream-vfs-linux-amd64.h src/litestream-vfs.h
gcc -g -fPIC -shared -o dist/litestream-vfs-linux-amd64.so \
$(VFS_C_SRC) dist/litestream-vfs-linux-amd64.a $(LINUX_LDFLAGS)

.PHONY: vfs-linux-arm64
vfs-linux-arm64:
mkdir -p dist
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=aarch64-linux-gnu-gcc \
go build -tags $(VFS_BUILD_TAGS) -o dist/litestream-vfs-linux-arm64.a -buildmode=c-archive $(VFS_SRC)
cp dist/litestream-vfs-linux-arm64.h src/litestream-vfs.h
aarch64-linux-gnu-gcc -g -fPIC -shared -o dist/litestream-vfs-linux-arm64.so \
$(VFS_C_SRC) dist/litestream-vfs-linux-arm64.a $(LINUX_LDFLAGS)

.PHONY: vfs-darwin-amd64
vfs-darwin-amd64:
mkdir -p dist
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 \
go build -tags $(VFS_BUILD_TAGS) -o dist/litestream-vfs-darwin-amd64.a -buildmode=c-archive $(VFS_SRC)
cp dist/litestream-vfs-darwin-amd64.h src/litestream-vfs.h
clang -arch x86_64 -g -fPIC -shared -o dist/litestream-vfs-darwin-amd64.dylib \
$(VFS_C_SRC) dist/litestream-vfs-darwin-amd64.a $(DARWIN_LDFLAGS)

.PHONY: vfs-darwin-arm64
vfs-darwin-arm64:
mkdir -p dist
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 \
go build -tags $(VFS_BUILD_TAGS) -o dist/litestream-vfs-darwin-arm64.a -buildmode=c-archive $(VFS_SRC)
cp dist/litestream-vfs-darwin-arm64.h src/litestream-vfs.h
clang -arch arm64 -g -fPIC -shared -o dist/litestream-vfs-darwin-arm64.dylib \
$(VFS_C_SRC) dist/litestream-vfs-darwin-arm64.a $(DARWIN_LDFLAGS)

vfs-test:
go test -v -tags=vfs ./cmd/litestream-vfs

Expand Down