`gh secret set` strips the trailing newline when storing APPLE_API_KEY_CONTENT, and Apple's PEM parser expects the key file to end with one. Write it back explicitly so notarization can load the key.
492 lines
24 KiB
YAML
492 lines
24 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: this is the ACTIVE release path. macOS is Developer-ID
|
|
# signed + notarized in CI when the Apple secrets below are configured (see
|
|
# README "macOS signing & notarization"). When the secrets are absent the mac
|
|
# jobs still build, but ad-hoc signed / unnotarized. Linux/Windows installers
|
|
# remain unsigned.
|
|
#
|
|
# Required secrets for signed + notarized macOS builds:
|
|
# APPLE_CERTIFICATE base64 of the Developer ID Application .p12
|
|
# APPLE_CERTIFICATE_PASSWORD password for that .p12
|
|
# APPLE_SIGNING_IDENTITY "Developer ID Application: Name (TEAMID)"
|
|
# KEYCHAIN_PASSWORD any throwaway password for the temp keychain
|
|
# APPLE_API_KEY App Store Connect Key ID
|
|
# APPLE_API_ISSUER App Store Connect Issuer ID
|
|
# APPLE_API_KEY_CONTENT contents of the AuthKey_<KeyID>.p8
|
|
#
|
|
# The cask bump runs only after the draft release is PUBLISHED (the GitHub
|
|
# releases/tags API does not serve drafts), so it is wired to the `release:
|
|
# published` event rather than the tag push. It also needs HOMEBREW_TAP_TOKEN.
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
release:
|
|
types: [published]
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
publish:
|
|
# Build + draft release happen on the tag push; the `release: published`
|
|
# event exists only to trigger the cask bump below.
|
|
if: github.event_name == 'push'
|
|
env:
|
|
# Empty when the secret is unset — the tool steps below test for a
|
|
# non-empty value before re-signing.
|
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
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
|
|
|
|
# ---- Apple signing setup (macOS only, skipped when secrets absent) ---
|
|
- name: Detect Apple signing secrets
|
|
id: apple
|
|
shell: bash
|
|
run: |
|
|
if [ -n "${{ secrets.APPLE_CERTIFICATE }}" ]; then
|
|
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
|
echo "::notice::APPLE_CERTIFICATE not set — macOS build will be ad-hoc signed and NOT notarized."
|
|
fi
|
|
|
|
# The bundled pg/mariadb tools are re-signed in their own steps below, so
|
|
# the identity must be in a keychain BEFORE those steps run. tauri-action
|
|
# is deliberately NOT given APPLE_CERTIFICATE (only the identity), so it
|
|
# does not create a second keychain.
|
|
- name: Import Apple Developer ID certificate
|
|
if: startsWith(matrix.platform, 'macos') && steps.apple.outputs.enabled == 'true'
|
|
shell: bash
|
|
env:
|
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
run: |
|
|
set -euo pipefail
|
|
KEYCHAIN="gridline-signing.keychain-db"
|
|
echo "$APPLE_CERTIFICATE" | base64 --decode > "$RUNNER_TEMP/cert.p12"
|
|
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
|
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
|
security import "$RUNNER_TEMP/cert.p12" -k "$KEYCHAIN" \
|
|
-P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
|
|
security set-key-partition-list -S apple-tool:,apple:,codesign: \
|
|
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN" >/dev/null
|
|
EXISTING="$(security list-keychain -d user | tr -d ' \"')"
|
|
security list-keychain -d user -s "$KEYCHAIN" $EXISTING
|
|
rm -f "$RUNNER_TEMP/cert.p12"
|
|
security find-identity -v -p codesigning
|
|
|
|
- name: Prepare notarization credentials
|
|
if: startsWith(matrix.platform, 'macos') && steps.apple.outputs.enabled == 'true'
|
|
shell: bash
|
|
env:
|
|
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
|
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
|
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }}
|
|
run: |
|
|
set -euo pipefail
|
|
KEY_PATH="$RUNNER_TEMP/private_keys/AuthKey_${APPLE_API_KEY}.p8"
|
|
mkdir -p "$(dirname "$KEY_PATH")"
|
|
# Apple's PEM parser expects a terminating newline, which
|
|
# `gh secret set` strips from the stored value — so write one
|
|
# explicitly. A doubled trailing newline is harmless to PEM parsers,
|
|
# but a missing one can make notarization fail to load the key.
|
|
printf '%s\n' "$APPLE_API_KEY_CONTENT" > "$KEY_PATH"
|
|
{
|
|
echo "APPLE_API_KEY=${APPLE_API_KEY}"
|
|
echo "APPLE_API_ISSUER=${APPLE_API_ISSUER}"
|
|
echo "APPLE_API_KEY_PATH=${KEY_PATH}"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- 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: './desktop/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}/desktop/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
|
|
# install_name_tool invalidates the linker signature. Re-sign with
|
|
# the Developer ID identity + hardened runtime + secure timestamp:
|
|
# Apple rejects ad-hoc-signed nested executables at notarization.
|
|
# No-op until the Apple secrets are configured.
|
|
if [ -n "${APPLE_SIGNING_IDENTITY:-}" ]; then
|
|
for f in "$OUT"/pg_dump "$OUT"/pg_restore "$OUT"/psql "$OUT"/libpq.5.dylib; do
|
|
codesign --force --options runtime --timestamp \
|
|
--sign "$APPLE_SIGNING_IDENTITY" "$f"
|
|
done
|
|
fi
|
|
;;
|
|
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}/desktop/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 libgnutls28-dev patchelf
|
|
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. The in-tree
|
|
# Connector C still probes GnuTLS on Unix regardless of WITH_SSL,
|
|
# so libgnutls28-dev is required at build time.
|
|
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
|
|
# Bundle every non-core shared dependency (GnuTLS + its chain,
|
|
# libzstd) next to the clients and point the loader at $ORIGIN —
|
|
# the same pattern the pg_tools step uses for libpq.
|
|
for b in mariadb-dump mariadb; do
|
|
ldd "$OUT/$b" | awk '/=> \// {print $3}' | sort -u | while read -r lib; do
|
|
case "$(basename "$lib")" in
|
|
ld-linux*|libc.so*|libm.so*|libpthread*|libdl.so*|librt.so*|libgcc_s*|libstdc++*|libcrypt.so*|libresolv*|libutil*)
|
|
;; # core runtime — present on every glibc system
|
|
*)
|
|
cp -n "$lib" "$OUT/$(basename "$lib")" 2>/dev/null || true
|
|
;;
|
|
esac
|
|
done
|
|
patchelf --set-rpath '$ORIGIN' "$OUT/$b"
|
|
done
|
|
;;
|
|
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
|
|
# macOS connects the in-tree Connector C against brew OpenSSL
|
|
# (proven to build+run on the runners); the Linux-only GnuTLS
|
|
# probe does not fire here. Absolute brew paths are rewritten to
|
|
# @loader_path below so user machines resolve them from the
|
|
# resource dir.
|
|
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
|
|
# Rewrite absolute Homebrew dylib deps to @loader_path so the
|
|
# bundled clients (and OpenSSL + their own deps) resolve from the
|
|
# resource dir on user machines. Fixed-point loop: each pass
|
|
# copies newly-seen dylibs and rewrites their parents' refs.
|
|
# Ad-hoc re-sign after each edit — arm64 dyld refuses to load a
|
|
# dylib whose (Homebrew) code signature was invalidated.
|
|
for pass in 1 2 3 4 5 6; do
|
|
for dylib in "$OUT"/*.dylib "$OUT"/mariadb-dump "$OUT"/mariadb; do
|
|
[ -f "$dylib" ] || continue
|
|
# `|| true` — with pipefail, grep exits 1 on zero matches.
|
|
otool -L "$dylib" | awk 'NR>1 {print $1}' | grep -E '^/(usr/local|opt/homebrew)' | while read -r lib; do
|
|
base=$(basename "$lib")
|
|
if [ ! -f "$OUT/$base" ]; then cp "$lib" "$OUT/$base" 2>/dev/null || true; fi
|
|
install_name_tool -change "$lib" "@loader_path/$base" "$dylib" 2>/dev/null || true
|
|
done || true
|
|
if [ -n "${APPLE_SIGNING_IDENTITY:-}" ]; then
|
|
codesign --force --options runtime --timestamp \
|
|
--sign "$APPLE_SIGNING_IDENTITY" "$dylib"
|
|
else
|
|
codesign --force --sign - "$dylib" 2>/dev/null || true
|
|
fi
|
|
done
|
|
done
|
|
;;
|
|
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:
|
|
projectPath: desktop
|
|
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.
|
|
|
|
# After the installers are uploaded, refresh the Homebrew cask in the
|
|
# AdrianBonpin/homebrew-gridline tap: hash the freshly-published DMGs,
|
|
# render Casks/gridline.rb from the template, and push it. Users then get
|
|
# the new version via `brew upgrade --cask gridline`.
|
|
#
|
|
# Requires the HOMEBREW_TAP_TOKEN secret (a PAT with `repo` scope on the tap
|
|
# repo — the default GITHUB_TOKEN cannot push to a different repo). The job
|
|
# no-ops until that secret is set, so releases stay green before this is
|
|
# configured.
|
|
bump-cask:
|
|
# Triggered by `release: published`, NOT the tag push: the GitHub
|
|
# releases/tags API returns 404 for drafts, so the DMGs are undownloadable
|
|
# until the draft is published.
|
|
if: github.event_name == 'release'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Check for tap token
|
|
id: tap
|
|
shell: bash
|
|
run: |
|
|
if [ -n "${{ secrets.HOMEBREW_TAP_TOKEN }}" ]; then
|
|
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
|
echo "::notice::HOMEBREW_TAP_TOKEN not set - skipping Homebrew cask bump."
|
|
fi
|
|
|
|
- name: Checkout
|
|
if: steps.tap.outputs.enabled == 'true'
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Resolve version and DMG checksums
|
|
id: meta
|
|
if: steps.tap.outputs.enabled == 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
VERSION="${GITHUB_REF_NAME#v}"
|
|
gh release download "$GITHUB_REF_NAME" -p "Gridline_${VERSION}_aarch64.dmg" -O /tmp/arm.dmg
|
|
gh release download "$GITHUB_REF_NAME" -p "Gridline_${VERSION}_x64.dmg" -O /tmp/intel.dmg
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "sha_arm=$(shasum -a 256 /tmp/arm.dmg | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
|
|
echo "sha_intel=$(shasum -a 256 /tmp/intel.dmg | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Checkout tap repo
|
|
if: steps.tap.outputs.enabled == 'true'
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: AdrianBonpin/homebrew-gridline
|
|
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
path: tap
|
|
|
|
- name: Render and push cask
|
|
if: steps.tap.outputs.enabled == 'true'
|
|
env:
|
|
VERSION: ${{ steps.meta.outputs.version }}
|
|
SHA_ARM: ${{ steps.meta.outputs.sha_arm }}
|
|
SHA_INTEL: ${{ steps.meta.outputs.sha_intel }}
|
|
run: |
|
|
mkdir -p tap/Casks
|
|
./scripts/render-cask.sh "$VERSION" "$SHA_ARM" "$SHA_INTEL" > tap/Casks/gridline.rb
|
|
cat tap/Casks/gridline.rb
|
|
cd tap
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add Casks/gridline.rb
|
|
if git diff --cached --quiet; then
|
|
echo "cask already up to date"
|
|
else
|
|
git commit -m "gridline $VERSION"
|
|
git push
|
|
fi |