* [P1-T1] feat(backup): MySQL/SQLite backup models + db_type on SyncOptions (Task 1.1) * [P1-T2] feat: enable tools(mysql,sqlite) + tableManagement(sqlite) + add fflate (Task 1.2) * [P1-T3] feat(cancel): CancelHandle enum + CancelRegistry (Task 1.3) * [P2-T1] feat(export): hand-rolled XLSX writer with inline-string cells (Task 2.1) * [P2-T2] feat(backup): SQLite .dump/restore/sync core, fail-closed virtual tables (Task 2.2) * [P2-T3] feat(backup): MySQL dump/restore/sync arg builders + tool resolution (Task 2.3) * [P2-T4] feat(settings): pure import validator + SettingsExport envelope + Store.apply_settings (Task 2.4) * [P2-T5] feat(table-editor): SQLite create/diff/rebuild SQL generation, fail-closed AUTOINCREMENT (Task 2.5) * [P3-T1] feat(commands): MySQL/SQLite backup + settings export/import commands + wrappers (Task 3.1) * [P3-T2] feat(cancel): capture cancel primitives at connect; cancel_query command; SQLite interrupt test (Task 3.2) * [P3-T3] feat(table-editor): SQLite object-change dispatch + execute_change Ddl/RebuildTable (Task 3.3) * [P4-T1] feat(tools): DB-aware backup/restore/sync pages (Task 4.1) * [P4-T2] feat(export): xlsx export in grid toolbar + overflow menu (Task 4.2) * [P4-T3] feat(query): cancel button wired to cancelQuery (Task 4.3) * [P4-T4] feat(settings): export/import buttons + validation gate (Task 4.4) * [P4-T5] fix(ui): gate macOS overlay drag strip to macOS only (Task 4.5) * [P4-T6] feat(table-editor): SQLite Create/Edit Table mode (Task 4.6) * [P5-T1] chore: bump 0.7.7 -> 0.7.8 + README/AGENTS/ROADMAP status (Task 5.1) * [P5-T2] build(release): bundle mariadb-dump + mariadb client (system-first fallback) (Task 5.2) * fix(cancel): propagate cancellations past wrapped->raw fallback (SQLite/PG/MySQL) + MySQL CONNECTION_ID cast * fix(export): Excel export from overflow menu did nothing + add export success/error toasts * fix(export): tree kebab export fetches table data when rows not loaded * docs(readme): surface v0.7.8 features (MySQL/SQLite backup-sync, Excel export, query cancel, SQLite table editor, settings import/export)
290 lines
14 KiB
YAML
290 lines
14 KiB
YAML
name: Release
|
|
|
|
# Builds Gridline installers for macOS (Apple Silicon + Intel), Windows, and
|
|
# Linux, then uploads them to a draft GitHub Release.
|
|
#
|
|
# Trigger: push a version tag from the `prod` branch (production), e.g.
|
|
# git checkout prod && git pull
|
|
# git tag v0.5.0 && git push origin v0.5.0
|
|
#
|
|
# SIGNING STATUS: builds are UNSIGNED for now (no code-signing certs yet —
|
|
# see README "Download a release"). tauri-action automatically signs +
|
|
# notarizes when the signing secrets are present, so the moment we add
|
|
# APPLE_CERTIFICATE / APPLE_API_KEY / WINDOWS_CERTIFICATE (or Azure Trusted
|
|
# Signing) to repo secrets, future builds are signed — no changes to this
|
|
# file required.
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
publish:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- platform: macos-latest # Apple Silicon (M1/M2/M3+)
|
|
args: --target aarch64-apple-darwin
|
|
- platform: macos-15-intel # Intel Macs (last Intel runner; retired ~Aug 2027)
|
|
args: --target x86_64-apple-darwin
|
|
- platform: ubuntu-22.04 # Linux x86_64 (.deb / .rpm / .AppImage)
|
|
args: ''
|
|
- platform: windows-latest # Windows x86_64 (NSIS .exe + .msi)
|
|
args: ''
|
|
runs-on: ${{ matrix.platform }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install Linux dependencies
|
|
if: matrix.platform == 'ubuntu-22.04'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
|
|
|
- name: Set up Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
|
|
- name: Set up Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: aarch64-apple-darwin, x86_64-apple-darwin
|
|
|
|
- name: Cache Rust build artifacts
|
|
uses: swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: './src-tauri -> target'
|
|
|
|
- name: Install frontend dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
- name: Build PostgreSQL client tools (bundled)
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
PG_VER="16.4"
|
|
OUT="${GITHUB_WORKSPACE}/src-tauri/resources/pg_tools"
|
|
mkdir -p "$OUT"
|
|
case "${{ matrix.platform }}" in
|
|
ubuntu-22.04)
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y build-essential libreadline-dev zlib1g-dev flex bison patchelf
|
|
curl -fsSL "https://ftp.postgresql.org/pub/source/v${PG_VER}/postgresql-${PG_VER}.tar.bz2" -o /tmp/pg.tar.bz2
|
|
tar -xf /tmp/pg.tar.bz2 -C /tmp
|
|
cd /tmp/postgresql-${PG_VER}
|
|
./configure --prefix=/tmp/pgbuild --without-readline --without-icu CFLAGS="-O2"
|
|
# Build the shared prerequisites (catalog headers + libpq/common/
|
|
# port archives) SERIALLY FIRST. Parallel `make -C` runs recurse
|
|
# into src/common concurrently and race `rm -f` / `ar crs` on the
|
|
# same .a — intermittently failing with 'ar: libpgcommon_srv.a:
|
|
# file format not recognized'. Once the archives exist, the tools'
|
|
# -j builds find them up to date and those recursions are no-ops.
|
|
make -C src/backend generated-headers
|
|
make -C src/interfaces/libpq all
|
|
make -j"$(nproc)" -C src/bin/pg_dump all
|
|
make -j"$(nproc)" -C src/bin/psql all
|
|
cp src/bin/pg_dump/pg_dump src/bin/pg_dump/pg_restore "$OUT"/
|
|
cp src/bin/psql/psql "$OUT"/
|
|
# pg_dump links shared libpq (PG16 has no --disable-shared for the
|
|
# client tools); bundle libpq.so alongside and point the loader at
|
|
# the app's resource dir via $ORIGIN rpath.
|
|
cp src/interfaces/libpq/libpq.so.5 "$OUT"/libpq.so.5
|
|
for b in pg_dump pg_restore psql; do
|
|
patchelf --set-rpath '$ORIGIN' "$OUT/$b"
|
|
done
|
|
;;
|
|
macos-latest|macos-15-intel)
|
|
curl -fsSL "https://ftp.postgresql.org/pub/source/v${PG_VER}/postgresql-${PG_VER}.tar.bz2" -o /tmp/pg.tar.bz2
|
|
tar -xf /tmp/pg.tar.bz2 -C /tmp
|
|
cd /tmp/postgresql-${PG_VER}
|
|
# ac_cv_func_strchrnul=no: Xcode 16.4's SDK marks strchrnul as
|
|
# introduced in macOS 15.4, so configure detects it and PG's
|
|
# snprintf.c calls the system symbol — which fails to compile
|
|
# (-Werror=unguarded-availability-new) and would crash at runtime
|
|
# on macOS < 15.4. Forcing the check off makes PG use its own
|
|
# inline fallback instead.
|
|
ac_cv_func_strchrnul=no ./configure --prefix=/tmp/pgbuild --without-readline --without-icu CFLAGS="-O2"
|
|
# macOS SDKs always declare strchrnul in <string.h> (Xcode 16.4
|
|
# marks it 'introduced in macOS 15.4'), so even with HAVE_STRCHRNUL
|
|
# disabled PG16's static-inline fallback would collide with the
|
|
# header declaration on newer SDKs. Rename PG's fallback so the
|
|
# tools compile on any SDK and never touch the (15.4+ only)
|
|
# system symbol.
|
|
sed -i '' 's/strchrnul/pg_strchrnul/g' src/port/snprintf.c
|
|
# Serial shared-prerequisite build first (see the Linux block: the
|
|
# archives must exist before the -j tool builds recurse into
|
|
# src/common).
|
|
make -C src/backend generated-headers
|
|
make -C src/interfaces/libpq all
|
|
make -j"$(sysctl -n hw.ncpu)" -C src/bin/pg_dump all
|
|
make -j"$(sysctl -n hw.ncpu)" -C src/bin/psql all
|
|
cp src/bin/pg_dump/pg_dump src/bin/pg_dump/pg_restore "$OUT"/
|
|
cp src/bin/psql/psql "$OUT"/
|
|
cp src/interfaces/libpq/libpq.5.dylib "$OUT"/libpq.5.dylib
|
|
# Rewrite the absolute /tmp/pgbuild libpq install_name to a
|
|
# relative @loader_path so the tools find libpq next to themselves.
|
|
for b in pg_dump pg_restore psql; do
|
|
libpq=$(otool -L "$OUT/$b" | awk '/libpq/ {print $1; exit}')
|
|
install_name_tool -change "$libpq" "@loader_path/libpq.5.dylib" "$OUT/$b"
|
|
done
|
|
;;
|
|
windows-latest)
|
|
URL="https://get.enterprisedb.com/postgresql/postgresql-${PG_VER}-1-windows-x64-binaries.zip"
|
|
curl -fsSL "$URL" -o /tmp/pg.zip
|
|
EXPECTED="3508d8f085bc3980f38211a82e3f31e5fcae9952105d3dc2f8be67b64a822baa"
|
|
echo "$EXPECTED /tmp/pg.zip" | sha256sum -c -
|
|
sha256sum /tmp/pg.zip
|
|
unzip -o /tmp/pg.zip -d /tmp/pg
|
|
cp /tmp/pg/pgsql/bin/pg_dump.exe /tmp/pg/pgsql/bin/pg_restore.exe /tmp/pg/pgsql/bin/psql.exe "$OUT"/
|
|
# pg_dump.exe needs far more than libpq.dll (libcrypto-3-x64.dll,
|
|
# libssl-3-x64.dll, libiconv-2.dll, libintl-9.dll,
|
|
# libwinpthread-1.dll, liblz4.dll, libzstd.dll, ICU DLLs, ...);
|
|
# copy every DLL next to the tools.
|
|
cp /tmp/pg/pgsql/bin/*.dll "$OUT"/
|
|
;;
|
|
esac
|
|
(cd "$OUT" && sha256sum * | tee checksums.txt)
|
|
# Resolve the per-platform binary suffix WITHOUT a command
|
|
# substitution: `$( [ ... ] && echo .exe )` returns exit 1 when the
|
|
# test is false, and under `set -e` that aborts the whole step.
|
|
if [ "${{ matrix.platform }}" = windows-latest ]; then
|
|
BIN_EXT=".exe"
|
|
else
|
|
BIN_EXT=""
|
|
fi
|
|
for b in pg_dump pg_restore psql; do
|
|
f="$OUT/${b}${BIN_EXT}"
|
|
test -f "$f" || { echo "missing $f"; exit 1; }
|
|
done
|
|
# Sanity: every tool must run (loader path is correct) — this catches
|
|
# a wrong @loader_path / rpath before we ship a broken bundle.
|
|
for b in pg_dump pg_restore psql; do
|
|
"$OUT/${b}${BIN_EXT}" --version >/dev/null 2>&1 || { echo "$b failed to run from resource dir"; exit 1; }
|
|
done
|
|
|
|
- name: Build MariaDB client tools (bundled)
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
MARIADB_VER="11.4.5"
|
|
OUT="${GITHUB_WORKSPACE}/src-tauri/resources/mysql_tools"
|
|
mkdir -p "$OUT"
|
|
case "${{ matrix.platform }}" in
|
|
ubuntu-22.04)
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y cmake build-essential libssl-dev libzstd-dev pkg-config
|
|
git clone --depth 1 --branch "mariadb-${MARIADB_VER}" https://github.com/MariaDB/server.git /tmp/mariadb-server
|
|
cd /tmp/mariadb-server
|
|
# Client-only build: wolfSSL + zlib are vendored, so the bundled
|
|
# clients need no system OpenSSL on the user's machine.
|
|
cmake -DCMAKE_BUILD_TYPE=Release \
|
|
-DWITHOUT_SERVER=ON \
|
|
-DWITHOUT_TOKUDB=1 \
|
|
-DWITHOUT_ROCKSDB=1 \
|
|
-DWITHOUT_MROONGA=1 \
|
|
-DWITHOUT_SPIDER=1 \
|
|
-DWITHOUT_SEQUENCE=1 \
|
|
-DWITH_UNIT_TESTS=OFF \
|
|
-DWITH_SSL=bundled \
|
|
-DWITH_ZLIB=bundled .
|
|
make -j"$(nproc)" mariadb-dump mariadb
|
|
# Clients build into client/ (stable across MariaDB 10.x/11.x);
|
|
# fall back to a broad search if a future version moves them.
|
|
for b in mariadb-dump mariadb; do
|
|
src=$(find client -maxdepth 1 -type f -name "$b" -print -quit 2>/dev/null || true)
|
|
test -n "$src" || src=$(find . -type f -name "$b" -print -quit || true)
|
|
test -n "$src" || { echo "build produced no $b binary"; exit 1; }
|
|
cp "$src" "$OUT"/
|
|
done
|
|
# Print the clients' shared-library deps for the first CI run.
|
|
# TODO(RELEASE): if the --version smoke check below fails with a
|
|
# shared-library error, the clients linked a shared libmariadb/
|
|
# libedit — copy it into "$OUT" and patchelf --set-rpath '$ORIGIN'
|
|
# exactly like the pg_tools step does for libpq.
|
|
ldd "$OUT"/mariadb-dump || true
|
|
;;
|
|
macos-latest|macos-15-intel)
|
|
git clone --depth 1 --branch "mariadb-${MARIADB_VER}" https://github.com/MariaDB/server.git /tmp/mariadb-server
|
|
cd /tmp/mariadb-server
|
|
if [ "$(uname -m)" = arm64 ]; then
|
|
SSL_DIR="/opt/homebrew/opt/openssl"
|
|
else
|
|
SSL_DIR="/usr/local/opt/openssl"
|
|
fi
|
|
[ -d "$SSL_DIR" ] || brew install openssl
|
|
cmake -DCMAKE_BUILD_TYPE=Release \
|
|
-DWITHOUT_SERVER=ON \
|
|
-DWITHOUT_TOKUDB=1 \
|
|
-DWITHOUT_ROCKSDB=1 \
|
|
-DWITHOUT_MROONGA=1 \
|
|
-DWITHOUT_SPIDER=1 \
|
|
-DWITHOUT_SEQUENCE=1 \
|
|
-DWITH_UNIT_TESTS=OFF \
|
|
-DWITH_SSL="$SSL_DIR" \
|
|
-DWITH_ZLIB=bundled .
|
|
make -j"$(sysctl -n hw.ncpu)" mariadb-dump mariadb
|
|
for b in mariadb-dump mariadb; do
|
|
src=$(find client -maxdepth 1 -type f -name "$b" -print -quit 2>/dev/null || true)
|
|
test -n "$src" || src=$(find . -type f -name "$b" -print -quit || true)
|
|
test -n "$src" || { echo "build produced no $b binary"; exit 1; }
|
|
cp "$src" "$OUT"/
|
|
done
|
|
# TODO(RELEASE): if the --version smoke check below fails with a
|
|
# dyld error, rewrite the lib dependency to @loader_path like the
|
|
# pg_tools step does for libpq (see also the Linux shared-lib note).
|
|
otool -L "$OUT"/mariadb-dump || true
|
|
;;
|
|
windows-latest)
|
|
URL="https://archive.mariadb.org/mariadb-${MARIADB_VER}/winx64-packages/mariadb-${MARIADB_VER}-winx64.zip"
|
|
curl -fsSL "$URL" -o /tmp/mariadb.zip
|
|
# TODO(RELEASE): pin the sha256 printed on the first CI run, then
|
|
# uncomment the check so later releases verify the download.
|
|
# EXPECTED="<sha256 of mariadb-${MARIADB_VER}-winx64.zip>"
|
|
# echo "$EXPECTED /tmp/mariadb.zip" | sha256sum -c -
|
|
sha256sum /tmp/mariadb.zip
|
|
unzip -o /tmp/mariadb.zip -d /tmp/mariadb
|
|
WINROOT="/tmp/mariadb/mariadb-${MARIADB_VER}-winx64"
|
|
cp "$WINROOT"/bin/mariadb-dump.exe "$WINROOT"/bin/mariadb.exe "$OUT"/
|
|
# The clients' only runtime dependency is the client library
|
|
# (lib/libmariadb.dll); the winx64 package statically links
|
|
# wolfSSL, so there are no OpenSSL DLLs to bundle. bin/*.dll is
|
|
# just the embedded server.dll, which the client tools don't need.
|
|
cp "$WINROOT"/lib/libmariadb.dll "$OUT"/
|
|
;;
|
|
esac
|
|
(cd "$OUT" && sha256sum * | tee checksums.txt)
|
|
# Resolve the per-platform binary suffix WITHOUT a command
|
|
# substitution (see the pg_tools step for why).
|
|
if [ "${{ matrix.platform }}" = windows-latest ]; then
|
|
BIN_EXT=".exe"
|
|
else
|
|
BIN_EXT=""
|
|
fi
|
|
for b in mariadb-dump mariadb; do
|
|
f="$OUT/${b}${BIN_EXT}"
|
|
test -f "$f" || { echo "missing $f"; exit 1; }
|
|
done
|
|
# Sanity: every tool must run (loader path is correct) — this catches
|
|
# a missing shared library before we ship a broken bundle.
|
|
for b in mariadb-dump mariadb; do
|
|
"$OUT/${b}${BIN_EXT}" --version >/dev/null 2>&1 || { echo "$b failed to run from resource dir"; exit 1; }
|
|
done
|
|
|
|
- name: Build and upload to GitHub Release
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
with:
|
|
tagName: ${{ github.ref_name }}
|
|
releaseName: 'Gridline ${{ github.ref_name }}'
|
|
releaseDraft: true
|
|
args: ${{ matrix.args }}
|
|
# Assets use tauri-action's default versioned naming (e.g.
|
|
# Gridline_0.7.5_aarch64.dmg, Gridline-0.7.5-1.x86_64.rpm) and the
|
|
# README download tables link to them statically per release —
|
|
# remember to update both README tables when cutting a new version. |