Skip to content

Merge pull request #36 from sqlrsync/v0.0.10 #113

Merge pull request #36 from sqlrsync/v0.0.10

Merge pull request #36 from sqlrsync/v0.0.10 #113

Workflow file for this run

name: Multi-Platform Build
on:
push:
branches:
- main
- beta
pull_request:
branches:
- main
- beta
- "v*"
release:
types: [published]
jobs:
securityIntention:
name: Security Intention
runs-on: ubuntu-latest
steps:
- name: Security Intention
run: |
echo "This workflow is intended to build the project in a secure manner:"
echo " - Only installs absolutely essential and trusted dependencies. (steps \"Install *\")"
echo " - Uses HTTPS for direct package downloads"
echo " - Only uses official Github Actions \"actions/*\""
build:
name: Build for ${{ matrix.os }}-${{matrix.arch}}
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
include:
- os: darwin
runs-on: macos-latest
arch: arm64
- os: darwin
runs-on: macos-latest
arch: x86_64
- os: linux
runs-on: ubuntu-latest
arch: x86_64
- os: linux-musl
runs-on: ubuntu-latest
arch: x86_64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.21"
cache: false
- name: Install dependencies (Ubuntu)
if: matrix.os == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y sqlite3 libsqlite3-dev build-essential
- name: Install dependencies (Alpine/musl)
if: matrix.os == 'linux-musl'
run: |
# Use Alpine container for musl builds
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace alpine:latest sh -c "
apk add --no-cache build-base sqlite-dev go curl git &&
echo 'Alpine dependencies installed'
"
- name: Install dependencies (macOS)
if: matrix.os == 'darwin'
run: |
brew install sqlite3
- name: Install dependencies (Windows)
if: matrix.os == 'windows'
run: |
choco install sqlite
- name: Build SQLite (Unix)
if: matrix.os != 'windows' && matrix.os != 'linux-musl'
run: |
cd sqlite
if [ ! -d "sqlite-latest" ]; then
# Download and extract SQLite source if not present
curl -O https://www.sqlite.org/2024/sqlite-autoconf-3450100.tar.gz
tar xzf sqlite-autoconf-3450100.tar.gz
mv sqlite-autoconf-3450100 sqlite-latest
fi
cd sqlite-latest
./configure --prefix=$(pwd)/../install --enable-static --disable-shared "CFLAGS=-DSQLITE_ENABLE_DBPAGE_VTAB=1 -O2"
make
make install
- name: Build SQLite (Alpine/musl)
if: matrix.os == 'linux-musl'
run: |
# Build SQLite in Alpine container for musl compatibility
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace alpine:latest sh -c "
apk add --no-cache build-base curl &&
cd sqlite &&
if [ ! -d 'sqlite-latest' ]; then
curl -O https://www.sqlite.org/2024/sqlite-autoconf-3450100.tar.gz
tar xzf sqlite-autoconf-3450100.tar.gz
mv sqlite-autoconf-3450100 sqlite-latest
fi &&
cd sqlite-latest &&
./configure --prefix=\$(pwd)/../install --enable-static --disable-shared 'CFLAGS=-DSQLITE_ENABLE_DBPAGE_VTAB=1 -O2' &&
make &&
make install
"
- name: Build SQLite (Windows)
if: matrix.os == 'windows'
run: |
cd sqlite
if (!(Test-Path "sqlite-latest")) {
Invoke-WebRequest -Uri "https://www.sqlite.org/2024/sqlite-autoconf-3450100.tar.gz" -OutFile "sqlite-autoconf-3450100.tar.gz"
tar -xzf sqlite-autoconf-3450100.tar.gz
Rename-Item sqlite-autoconf-3450100 sqlite-latest
}
cd sqlite-latest
# Use MSYS2/MinGW for Windows build
bash -c "./configure --prefix=$(pwd)/../install --enable-static --disable-shared 'CFLAGS=-DSQLITE_ENABLE_DBPAGE_VTAB=1 -O2'"
bash -c "make"
bash -c "make install"
- name: Build Bridge
if: matrix.os != 'linux-musl'
run: |
cd bridge
make
- name: Build Bridge (Alpine/musl)
if: matrix.os == 'linux-musl'
run: |
# Build bridge in Alpine container
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace alpine:latest sh -c "
apk add --no-cache build-base go &&
cd bridge &&
make
"
- name: Set build environment (Darwin ARM64)
if: matrix.os == 'darwin' && matrix.arch == 'arm64'
run: |
echo "GOOS=darwin" >> $GITHUB_ENV
echo "GOARCH=arm64" >> $GITHUB_ENV
echo "CGO_ENABLED=1" >> $GITHUB_ENV
- name: Set build environment (Darwin AMD64)
if: matrix.os == 'darwin' && matrix.arch == 'amd64'
run: |
echo "GOOS=darwin" >> $GITHUB_ENV
echo "GOARCH=amd64" >> $GITHUB_ENV
echo "CGO_ENABLED=1" >> $GITHUB_ENV
- name: Set build environment (Linux x86_64)
if: matrix.os == 'linux' && matrix.arch == 'x86_64'
run: |
echo "GOOS=linux" >> $GITHUB_ENV
echo "GOARCH=amd64" >> $GITHUB_ENV
echo "CGO_ENABLED=1" >> $GITHUB_ENV
- name: Set build environment (Linux musl x86_64)
if: matrix.os == 'linux-musl' && matrix.arch == 'x86_64'
run: |
echo "GOOS=linux" >> $GITHUB_ENV
echo "GOARCH=amd64" >> $GITHUB_ENV
echo "CGO_ENABLED=1" >> $GITHUB_ENV
- name: Set build environment (Windows)
if: matrix.os == 'windows'
run: |
echo "GOOS=windows" >> $env:GITHUB_ENV
echo "GOARCH=amd64" >> $env:GITHUB_ENV
echo "CGO_ENABLED=1" >> $env:GITHUB_ENV
- name: Build Client (Unix)
if: matrix.os != 'windows' && matrix.os != 'linux-musl'
run: |
cd client
make build
- name: Build Client (Alpine/musl)
if: matrix.os == 'linux-musl'
run: |
# Build client in Alpine container
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace alpine:latest sh -c "
apk add --no-cache zlib-dev build-base go git &&
git config --global --add safe.directory /workspace &&
cd client &&
make build
"
# Verify binary was created
if [ ! -f ./client/bin/sqlrsync ]; then
echo "ERROR: Binary not found at ./client/bin/sqlrsync"
exit 1
fi
echo "✓ Binary built successfully at ./client/bin/sqlrsync"
file ./client/bin/sqlrsync
- name: Docker based test (Alpine/musl)
if: matrix.os == 'linux-musl'
run: |
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace alpine:latest sh -c "
ldd ./client/bin/sqlrsync &&
./client/bin/sqlrsync --version &&
./client/bin/sqlrsync usgs.gov/earthquakes.db
"
- name: Build Client (Windows)
if: matrix.os == 'windows'
run: |
cd client
# Use make with MSYS2/MinGW
bash -c "make build"
- name: Test sqlrsync --version
if: matrix.os != 'linux-musl'
run: |
echo "Testing sqlrsync --version..."
./client/bin/sqlrsync --version
- name: Test sqlrsync help
if: matrix.os != 'linux-musl'
run: |
echo "Testing sqlrsync help..."
./client/bin/sqlrsync || true
- name: Test sqlrsync with usgs.gov/earthquakes.db
if: matrix.os != 'linux-musl'
run: |
echo "Testing sqlrsync usgs.gov/earthquakes.db..."
./client/bin/sqlrsync usgs.gov/earthquakes.db
- name: Test sqlrsync with subscribe for 10 seconds (Linux)
if: matrix.os == 'linux'
run: |
echo "Testing sqlrsync usgs.gov/earthquakes.db --subscribe for 10 seconds..."
timeout 10s ./client/bin/sqlrsync usgs.gov/earthquakes.db --subscribe > subscribe_output.log 2>&1 || true
- name: Test sqlrsync with subscribe for 10 seconds (macOS)
if: matrix.os == 'darwin'
run: |
echo "Testing sqlrsync usgs.gov/earthquakes.db --subscribe for 10 seconds..."
# macOS doesn't have timeout, use gtimeout or alternative
if command -v gtimeout &> /dev/null; then
gtimeout 10s ./client/bin/sqlrsync usgs.gov/earthquakes.db --subscribe > subscribe_output.log 2>&1 || true
else
# Fallback: run in background and kill after 10 seconds
./client/bin/sqlrsync usgs.gov/earthquakes.db --subscribe > subscribe_output.log 2>&1 &
PID=$!
sleep 10
kill $PID 2>/dev/null || true
wait $PID 2>/dev/null || true
fi
- name: Test sqlrsync with subscribe for 10 seconds (Windows)
if: matrix.os == 'windows'
run: |
echo "Testing sqlrsync usgs.gov/earthquakes.db --subscribe for 10 seconds..."
# Windows doesn't have timeout, use PowerShell equivalent
$job = Start-Job { ./client/bin/sqlrsync.exe usgs.gov/earthquakes.db --subscribe }
Wait-Job $job -Timeout 10
Stop-Job $job
Receive-Job $job > subscribe_output.log 2>&1 || $true
- name: Verify subscribe output (Unix)
if: matrix.os != 'windows' && matrix.os != 'linux-musl'
run: |
echo "Checking for 'Sync complete' in output..."
cat subscribe_output.log
if grep -q "Sync complete" subscribe_output.log; then
echo "✅ SUCCESS: Found 'Sync complete' in output"
else
echo "❌ FAILURE: 'Sync complete' not found in output"
echo "Full output:"
cat subscribe_output.log
exit 1
fi
- name: Create release directory
run: |
mkdir -p release
- name: Package binary (Unix)
if: matrix.os != 'windows'
run: |
if [ "${{ matrix.os }}" = "darwin" ] && [ "${{ matrix.arch }}" = "arm64" ]; then
BINARY_NAME="sqlrsync-${{ matrix.os }}-${{ matrix.arch }}"
else
BINARY_NAME="sqlrsync-${{ matrix.os }}-${{ matrix.arch }}"
fi
cp client/bin/sqlrsync release/${BINARY_NAME}
- name: Package binary (Windows)
if: matrix.os == 'windows'
run: |
$BINARY_NAME = "sqlrsync-${{ matrix.os }}-${{ matrix.arch }}.exe"
Copy-Item "client/bin/sqlrsync.exe" "release/$BINARY_NAME"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: sqlrsync-${{ matrix.os }}-${{ matrix.arch }}
path: release/*
release:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
needs: build
permissions:
contents: write
packages: write
issues: write
pull-requests: write
actions: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Extract version from main.go
id: extract-version
run: |
VERSION=$(grep 'var VERSION = ' client/main.go | sed 's/var VERSION = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
- name: Check if tag exists
id: tag-check
run: |
VERSION=${{ steps.extract-version.outputs.version }}
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists"
echo "tag-created=false" >> $GITHUB_OUTPUT
else
echo "Tag v$VERSION does not exist, will create"
echo "tag-created=true" >> $GITHUB_OUTPUT
fi
- name: Download all release artifacts
if: steps.tag-check.outputs.tag-created == 'true'
uses: actions/download-artifact@v5
- name: Create tag and GitHub Release, attach artifact
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG=v${{ steps.extract-version.outputs.version }}
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git tag -a $TAG -m "Release $TAG"
git push origin $TAG
# create the release and attach the artifact (gh CLI)
gh release create $TAG --generate-notes sqlrsync-*/sqlrsync-*