Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e66d7ac102 | ||
|
|
84a6f8d41c | ||
|
|
08b0f79f07 |
@@ -7,16 +7,11 @@ name: Release
|
||||
# git checkout prod && git pull
|
||||
# git tag v0.5.0 && git push origin v0.5.0
|
||||
#
|
||||
# SIGNING STATUS: macOS bundles are AD-HOC signed via tauri.conf.json
|
||||
# (bundle.macOS.signingIdentity: "-", hardenedRuntime: false). That replaces
|
||||
# the linker-only signature that made macOS report the app as "damaged" and
|
||||
# refuse Finder launches — users now get the standard "Open Anyway" prompt
|
||||
# (or run `sudo xattr -dr com.apple.quarantine` for the damaged-error case, see
|
||||
# README). Still NOT Developer-ID signed / notarized (no certs yet).
|
||||
# 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 properly signed — no changes to this file required.
|
||||
# SIGNING STATUS: macOS is Developer-ID signed + notarized via
|
||||
# scripts/release-mac.sh (built manually on Adrian's machine). NOTE: this
|
||||
# GitHub workflow is NOT the active release path — Gitea Actions uses
|
||||
# .gitea/workflows/release.yml (Linux/Windows only). Linux/Windows installers
|
||||
# remain unsigned.
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -184,7 +184,7 @@ Cut a release by tagging the **`prod`** branch once the PR is merged — `git ta
|
||||
- `desktop/src/lib/version.test.ts` and `desktop/src/lib/docs-coverage.test.ts` if they assert the version
|
||||
- **README download links are static (versioned)** — both download tables (top **Download** section + **Which file should I download?**) link directly to the release-tag assets (`releases/download/v0.7.9/<file>`). tauri-action uses default versioned asset names (`Gridline_<ver>_aarch64.dmg`, `Gridline-<ver>-1.x86_64.rpm`, etc.) — update BOTH tables to the new names on every release (see the MAINTENANCE comment in README.md).
|
||||
- **Bundled pg tools:** `tauri.conf.json` `bundle.resources` lists `resources/pg_tools/*`; the `release.yml` matrix builds/downloads + checksum-verifies the static binaries before the Tauri build step.
|
||||
- **Release notes must include the macOS first-launch instructions** — until a Developer ID signing certificate is secured, releases are ad-hoc signed only (not notarized), so every macOS user hits a Gatekeeper prompt. The draft release body must include: right-click → **Open** → **Open** (or System Settings → Privacy & Security → **Open Anyway**) for "developer cannot be verified", and `sudo xattr -dr com.apple.quarantine /Applications/Gridline.app` (with the re-run-after-every-upgrade note) for "damaged and can't be opened".
|
||||
- **macOS is Developer-ID signed + notarized** via `scripts/release-mac.sh` (built manually on Adrian's machine; not in CI). The script auto-detects the Developer ID identity from the login keychain, reads notarization credentials from `~/.config/gridline/notarize.env` (App Store Connect API key), and verifies codesign + stapled notarization before uploading. If the cert or credentials are missing it fails with setup instructions (see the README's "macOS signing & notarization" section).
|
||||
|
||||
### Adding a Tauri Command
|
||||
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
|
||||
## Download
|
||||
|
||||
Grab the installer for your OS from the [latest release](https://git.ranio.xyz/adrianbonpin/gridline/releases/latest) — the links below point at the current release (**v0.7.12**):
|
||||
Grab the installer for your OS from the [latest release](https://git.ranio.xyz/adrianbonpin/gridline/releases/latest) — the links below point at the current release (**v0.7.13**):
|
||||
|
||||
| OS | Architecture | Download |
|
||||
| :--------------------------- | :--------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **macOS** | Apple Silicon (M1/M2/M3/M4…) | [Gridline_0.7.12_aarch64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_aarch64.dmg) |
|
||||
| **macOS** | Intel | [Gridline_0.7.12_x64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_x64.dmg) |
|
||||
| **Windows** | x64 | [Gridline_0.7.12_x64-setup.exe](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_x64-setup.exe) |
|
||||
| **Debian / Ubuntu** | amd64 | [Gridline_0.7.12_amd64.deb](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_amd64.deb) |
|
||||
| **Fedora / RHEL / openSUSE** | x86_64 | [Gridline-0.7.12-1.x86_64.rpm](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline-0.7.12-1.x86_64.rpm) |
|
||||
| **Other Linux** | amd64 | [Gridline_0.7.12_amd64.AppImage](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_amd64.AppImage) |
|
||||
| **macOS** | Apple Silicon (M1/M2/M3/M4…) | [Gridline_0.7.13_aarch64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_aarch64.dmg) |
|
||||
| **macOS** | Intel | [Gridline_0.7.13_x64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_x64.dmg) |
|
||||
| **Windows** | x64 | [Gridline_0.7.13_x64-setup.exe](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_x64-setup.exe) |
|
||||
| **Debian / Ubuntu** | amd64 | [Gridline_0.7.13_amd64.deb](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_amd64.deb) |
|
||||
| **Fedora / RHEL / openSUSE** | x86_64 | [Gridline-0.7.13-1.x86_64.rpm](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline-0.7.13-1.x86_64.rpm) |
|
||||
| **Other Linux** | amd64 | [Gridline_0.7.13_amd64.AppImage](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_amd64.AppImage) |
|
||||
|
||||
**macOS via Homebrew** (recommended for Mac users):
|
||||
|
||||
@@ -49,12 +49,12 @@ brew install --cask AdrianBonpin/gridline/gridline
|
||||
brew install --cask gridline
|
||||
```
|
||||
|
||||
The cask strips the macOS quarantine flag automatically during install, so **no manual `xattr` step is needed** on the Homebrew path — the app just launches. (Direct-DMG downloads still need the [first-launch instructions](#installers-are-unsigned-for-now) below.)
|
||||
The cask installs the app directly. The DMGs are Developer-ID signed and notarized, so macOS trusts them on first launch — no `xattr` or "Open Anyway" step needed.
|
||||
|
||||
> **macOS first launch:** macOS may say *"Gridline is damaged and can't be opened"* or *"the developer cannot be verified"* — this is expected; the app isn't Developer-ID signed/notarized yet. See the [macOS first-launch instructions](#installers-are-unsigned-for-now) (right-click → Open, or the one-time `xattr` fix). Not sure if your Mac is Intel or Apple Silicon? See [Which file should I download?](#which-file-should-i-download) below.
|
||||
> **macOS first launch:** Gridline is Developer-ID signed and notarized, so macOS opens it without a Gatekeeper prompt. Not sure if your Mac is Intel or Apple Silicon? See [Which file should I download?](#which-file-should-i-download) below.
|
||||
|
||||
<!--
|
||||
MAINTENANCE: These links are STATIC (versioned) — they point at the v0.7.12
|
||||
MAINTENANCE: These links are STATIC (versioned) — they point at the v0.7.13
|
||||
release assets, not at a moving "latest" target. On every new release,
|
||||
update BOTH tables here (Download + Which file should I download?) to the
|
||||
new version's asset names, which are tauri-action's default naming:
|
||||
@@ -99,6 +99,8 @@ Gridline is built for developers and small teams who manage multiple database en
|
||||
<details>
|
||||
<summary>View the full changelog</summary>
|
||||
|
||||
- **v0.7.13** — **macOS is now Developer-ID signed and notarized**: the app is properly code-signed with a Developer ID Application certificate and notarized by Apple, so macOS opens it without the Gatekeeper "Open Anyway" prompt or the `xattr` quarantine workaround. The release script (`scripts/release-mac.sh`) auto-detects the signing identity from the keychain, notarizes + staples both architectures, and verifies the result before uploading; version bump.
|
||||
|
||||
- **v0.7.12** — **Reliable cell editing for non-text columns**: editing a PostgreSQL cell whose type isn't `text` (integers, booleans, UUIDs, `json`/`jsonb`, timestamps, enums, numerics, …) previously failed with a Rust serialization error; edited values are now sent to PostgreSQL in text wire format so the server parses them into the column's own type. **Recent connections fix**: the Recent strip no longer renders empty on first launch when the connections list hadn't loaded yet. **Full CI release pipeline for Windows**: self-hosted Windows runner builds the `.exe`/`.msi` installers (bundled `pg_dump`/`pg_restore`/`psql` + MariaDB clients) and uploads them to the release alongside Linux; version bump.
|
||||
|
||||
- **v0.7.10** — **Copy connection URL**: from a connection card's ⋮ menu, copy the connection string for use in env vars / other tools — **Copy connection URL** (includes the password, fetched from the OS keychain on demand) and **Copy connection URL (no password)** (safe to share). Builds `postgresql://` / `mysql://` / `sqlite://` / `redis://` strings with percent-encoded credentials and the PG `sslmode` appended; version bump.
|
||||
@@ -307,37 +309,40 @@ Pre-built installers for macOS, Windows, and Linux are published on the [Release
|
||||
|
||||
> ⚠️ Gridline is under active development. Expect rough edges and please [open issues](https://git.ranio.xyz/adrianbonpin/gridline/issues/new) when you hit them.
|
||||
|
||||
#### Installers are unsigned (for now)
|
||||
#### macOS signing & notarization
|
||||
|
||||
Gridline is currently distributed **unsigned** — it doesn't pay for code-signing certificates yet (macOS builds are *ad-hoc signed*, so they pass Apple Silicon's launch checks but aren't Developer-ID signed or notarized). Your OS will warn you the first time you open it. This is expected — the app is safe, it just hasn't paid the signing fee:
|
||||
Gridline's macOS builds are **Developer-ID signed and notarized**, so macOS opens them without a Gatekeeper prompt. This is configured on the machine that runs `scripts/release-mac.sh` (macOS is built manually, not in CI).
|
||||
|
||||
> **Homebrew users:** the [Homebrew cask](#download) strips the quarantine flag automatically during install, so you skip all of the steps below — the app just launches.
|
||||
**One-time setup** (only the repo owner needs to do this):
|
||||
|
||||
- **macOS:** if you see *"Gridline can't be opened because the developer cannot be verified"* (or the app simply won't open from Finder), right-click the app → **Open** → **Open** (or System Settings → Privacy & Security → **Open Anyway**). Do this once per version.
|
||||
- **macOS — "Gridline is damaged and can't be opened":** remove the quarantine flag macOS attaches to downloaded apps, then launch normally:
|
||||
1. **Create a Developer ID Application certificate** — [developer.apple.com](https://developer.apple.com) → Certificates, Identifiers & Profiles → **+** → **Developer ID Application**. Generate a Certificate Signing Request from Keychain Access (Certificate Assistant → *Request a Certificate From a Certificate Authority*), upload it, download the `.cer`, and double-click to install into your login keychain. Verify with `security find-identity -v -p codesigning`.
|
||||
2. **Create an App Store Connect API key** for notarization — [appstoreconnect.apple.com](https://appstoreconnect.apple.com) → Users and Access → **Integrations** → **App Store Connect API** → **+** (name it, *Developer* access). Download the `.p8` (shown once) and note the **Key ID** and **Issuer ID**.
|
||||
3. **Save the notarization credentials** to `~/.config/gridline/notarize.env` (never committed):
|
||||
|
||||
```bash
|
||||
sudo xattr -dr com.apple.quarantine /Applications/Gridline.app
|
||||
APPLE_API_KEY=<Key ID>
|
||||
APPLE_API_ISSUER=<Issuer ID>
|
||||
APPLE_API_KEY_PATH=/absolute/path/to/AuthKey_<KeyID>.p8
|
||||
```
|
||||
|
||||
(`sudo` is required — some files inside the bundle are read-only, so removing the flag needs admin rights.) Re-run after **every upgrade** — each freshly-downloaded copy gets re-quarantined.
|
||||
- **Windows:** on the SmartScreen prompt, click **More info** → **Run anyway**.
|
||||
- **Linux:** no warning — install and run normally.
|
||||
(Alternatively, drop the `.p8` at `~/.appstoreconnect/private_keys/AuthKey_<KeyID>.p8` and omit `APPLE_API_KEY_PATH`.)
|
||||
|
||||
Code signing **will be added in the future** (Apple Developer Program + a Windows signing cert, e.g. Azure Trusted Signing) — the CI workflow is already wired to pick up the signing secrets automatically the moment they exist, no workflow changes needed.
|
||||
`scripts/release-mac.sh` auto-detects the Developer ID identity from your keychain, signs both architectures, notarizes + staples them, and verifies the result before uploading. If the certificate or credentials are missing it fails with instructions (set `GRIDLINE_SKIP_NOTARIZE=1` to build signed-but-unnotarized for testing only).
|
||||
|
||||
**Windows** still shows a SmartScreen prompt (no Windows signing cert yet); **Linux** installs without a warning.
|
||||
|
||||
#### Which file should I download?
|
||||
|
||||
Each release contains **one file per platform** — you only need the one that matches your computer. The links below point at the current release (**v0.7.12**):
|
||||
Each release contains **one file per platform** — you only need the one that matches your computer. The links below point at the current release (**v0.7.13**):
|
||||
|
||||
| Your system | Download this | Notes |
|
||||
| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------- |
|
||||
| macOS **Apple Silicon** (M1/M2/M3/M4…) | [Gridline_0.7.12_aarch64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_aarch64.dmg) | `aarch64` = Apple's own chip |
|
||||
| macOS **Intel** | [Gridline_0.7.12_x64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_x64.dmg) | `x64` = Intel/AMD |
|
||||
| **Windows** (most PCs) | [Gridline_0.7.12_x64-setup.exe](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_x64-setup.exe) | The `.msi` is an alternate installer (for enterprises/IT admins) |
|
||||
| **Debian / Ubuntu** | [Gridline_0.7.12_amd64.deb](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_amd64.deb) | Install: `sudo apt install ./Gridline_0.7.12_amd64.deb` |
|
||||
| **Fedora / RHEL / openSUSE** | [Gridline-0.7.12-1.x86_64.rpm](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline-0.7.12-1.x86_64.rpm) | Install: `sudo dnf install Gridline-0.7.12-1.x86_64.rpm` |
|
||||
| **Any other Linux** | [Gridline_0.7.12_amd64.AppImage](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.12/Gridline_0.7.12_amd64.AppImage) | Works on every distro: `chmod +x` the file, then double-click it |
|
||||
| macOS **Apple Silicon** (M1/M2/M3/M4…) | [Gridline_0.7.13_aarch64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_aarch64.dmg) | `aarch64` = Apple's own chip |
|
||||
| macOS **Intel** | [Gridline_0.7.13_x64.dmg](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_x64.dmg) | `x64` = Intel/AMD |
|
||||
| **Windows** (most PCs) | [Gridline_0.7.13_x64-setup.exe](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_x64-setup.exe) | The `.msi` is an alternate installer (for enterprises/IT admins) |
|
||||
| **Debian / Ubuntu** | [Gridline_0.7.13_amd64.deb](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_amd64.deb) | Install: `sudo apt install ./Gridline_0.7.13_amd64.deb` |
|
||||
| **Fedora / RHEL / openSUSE** | [Gridline-0.7.13-1.x86_64.rpm](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline-0.7.13-1.x86_64.rpm) | Install: `sudo dnf install Gridline-0.7.13-1.x86_64.rpm` |
|
||||
| **Any other Linux** | [Gridline_0.7.13_amd64.AppImage](https://git.ranio.xyz/adrianbonpin/gridline/releases/download/v0.7.13/Gridline_0.7.13_amd64.AppImage) | Works on every distro: `chmod +x` the file, then double-click it |
|
||||
|
||||
**Not sure if your Mac is Intel or Apple Silicon?** Click the **Apple menu** → **About This Mac**. If it shows "Apple M1/M2/M3/M4…" download the `aarch64` file; if it shows an Intel chip, download `x64`. Downloading the wrong one won't run.
|
||||
|
||||
@@ -347,8 +352,8 @@ Cutting a release is one command — CI builds everything. **Releases are cut fr
|
||||
|
||||
```bash
|
||||
git checkout prod && git pull
|
||||
git tag v0.7.12
|
||||
git push origin v0.7.12
|
||||
git tag v0.7.13
|
||||
git push origin v0.7.13
|
||||
```
|
||||
|
||||
Gitea Actions (`.gitea/workflows/release.yml`) builds the **Linux and Windows** installers on the self-hosted runners, then opens a **draft release** on the [Releases](https://git.ranio.xyz/adrianbonpin/gridline/releases) page. **macOS is built manually** on the dev Mac and its DMGs uploaded to the same release via `scripts/release-mac.sh`. Review the draft and hit **Publish release**.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "gridline-desktop",
|
||||
"private": true,
|
||||
"version": "0.7.12",
|
||||
"version": "0.7.13",
|
||||
"description": "An open-source, high-performance database GUI client for PostgreSQL and beyond",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gridline"
|
||||
version = "0.7.12"
|
||||
version = "0.7.13"
|
||||
description = "An open-source, high-performance database GUI client for PostgreSQL and beyond"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- Required for the WKWebView (JIT-compiled JavaScript). Without this the
|
||||
app crashes under the hardened runtime. -->
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<!-- The WebView allocates executable memory for JIT; allow it. -->
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<!-- Tauri's dev server / debug builds rely on DYLD_* environment variables. -->
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Gridline",
|
||||
"version": "0.7.12",
|
||||
"version": "0.7.13",
|
||||
"identifier": "com.adrianbonpin.gridline",
|
||||
"build": {
|
||||
"beforeDevCommand": "bun run dev",
|
||||
@@ -29,7 +29,8 @@
|
||||
"resources": ["resources/pg_tools/*", "resources/mysql_tools/*"],
|
||||
"macOS": {
|
||||
"signingIdentity": "-",
|
||||
"hardenedRuntime": false
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "entitlements.plist"
|
||||
},
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import tauriConf from "../../src-tauri/tauri.conf.json";
|
||||
|
||||
describe("tauri bundle config (v0.7.12)", () => {
|
||||
describe("tauri bundle config (v0.7.13)", () => {
|
||||
it("declares bundled pg_tools resources", () => {
|
||||
expect(tauriConf.bundle.resources).toContain("resources/pg_tools/*");
|
||||
});
|
||||
it("version is 0.7.12", () => {
|
||||
expect(tauriConf.version).toBe("0.7.12");
|
||||
it("version is 0.7.13", () => {
|
||||
expect(tauriConf.version).toBe("0.7.13");
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,7 @@ import { describe, it, expect } from "vitest";
|
||||
import agents from "../../../AGENTS.md?raw";
|
||||
import readme from "../../../README.md?raw";
|
||||
|
||||
describe("v0.7.12 docs coverage", () => {
|
||||
describe("v0.7.13 docs coverage", () => {
|
||||
it("AGENTS.md marks inline cell editing complete", () => {
|
||||
expect(agents).toContain("Inline cell editing");
|
||||
expect(agents).toMatch(/Inline cell editing \| ✅/);
|
||||
@@ -24,8 +24,8 @@ describe("v0.7.12 docs coverage", () => {
|
||||
expect(agents).toMatch(/Connection status indicator on cards \| ✅/);
|
||||
expect(agents).toMatch(/Move-to-folder bulk action \| ✅/);
|
||||
});
|
||||
it("README declares v0.7.12", () => {
|
||||
expect(readme).toContain("0.7.12");
|
||||
it("README declares v0.7.13", () => {
|
||||
expect(readme).toContain("0.7.13");
|
||||
});
|
||||
it("AGENTS.md marks schema CRUD complete", () => {
|
||||
expect(agents).toMatch(/Schema CRUD \| ✅/);
|
||||
@@ -64,9 +64,9 @@ describe("v0.7.12 docs coverage", () => {
|
||||
expect(agents).toMatch(/Cancel long-running queries \| ✅/);
|
||||
expect(agents).toMatch(/Settings export\/import \| ✅/);
|
||||
});
|
||||
it("README links to v0.7.12 assets in both download tables", () => {
|
||||
expect(readme).toContain("releases/download/v0.7.12/");
|
||||
expect(readme).toContain("Gridline_0.7.12_aarch64.dmg");
|
||||
expect(readme).toContain("Gridline-0.7.12-1.x86_64.rpm");
|
||||
it("README links to v0.7.13 assets in both download tables", () => {
|
||||
expect(readme).toContain("releases/download/v0.7.13/");
|
||||
expect(readme).toContain("Gridline_0.7.13_aarch64.dmg");
|
||||
expect(readme).toContain("Gridline-0.7.13-1.x86_64.rpm");
|
||||
});
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
||||
import pkg from "../../package.json";
|
||||
|
||||
describe("version", () => {
|
||||
it("declares v0.7.12 across the app shell", () => {
|
||||
expect(pkg.version).toBe("0.7.12");
|
||||
it("declares v0.7.13 across the app shell", () => {
|
||||
expect(pkg.version).toBe("0.7.13");
|
||||
});
|
||||
});
|
||||
@@ -75,6 +75,11 @@ for b in pg_dump pg_restore psql; do
|
||||
libpq=$(otool -L "$OUT_PG/$b" | awk '/libpq/ {print $1; exit}')
|
||||
install_name_tool -change "$libpq" "@loader_path/libpq.5.dylib" "$OUT_PG/$b"
|
||||
done
|
||||
# install_name_tool invalidates the linker's ad-hoc signature; re-sign so the
|
||||
# bundle passes notarization (every code object inside must be signed).
|
||||
for f in "$OUT_PG"/pg_dump "$OUT_PG"/pg_restore "$OUT_PG"/psql "$OUT_PG"/libpq.5.dylib; do
|
||||
codesign --force --sign - "$f" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo ">> Building MariaDB client tools..."
|
||||
mkdir -p "$OUT_MY"
|
||||
@@ -116,6 +121,58 @@ for pass in 1 2 3 4 5 6; do
|
||||
done
|
||||
done
|
||||
|
||||
# ---- macOS signing + notarization -----------------------------------------
|
||||
# Requires a "Developer ID Application" certificate in the login keychain and
|
||||
# an App Store Connect API key for notarization. See the README's "macOS
|
||||
# signing" section for how to create both.
|
||||
#
|
||||
# Notarization credentials are read from ~/.config/gridline/notarize.env
|
||||
# (never committed). Create it with:
|
||||
# APPLE_API_KEY=<Key ID>
|
||||
# APPLE_API_ISSUER=<Issuer ID>
|
||||
# APPLE_API_KEY_PATH=/absolute/path/to/AuthKey_<KeyID>.p8
|
||||
# (or drop the .p8 at ~/.appstoreconnect/private_keys/AuthKey_<KeyID>.p8 and
|
||||
# omit APPLE_API_KEY_PATH — tauri auto-searches that location.)
|
||||
|
||||
# 1. Resolve the Developer ID Application signing identity from the keychain.
|
||||
SIGNING_IDENTITY="$(security find-identity -v -p codesigning 2>/dev/null \
|
||||
| grep -i 'Developer ID Application' \
|
||||
| sed -E 's/.*"([^"]+)".*/\1/' \
|
||||
| head -1 || true)"
|
||||
if [ -z "$SIGNING_IDENTITY" ]; then
|
||||
echo "ERROR: No 'Developer ID Application' certificate found in the login keychain." >&2
|
||||
echo " Create one at https://developer.apple.com/account/resources/certificates/list" >&2
|
||||
echo " (Certificates, IDs & Profiles -> + -> Developer ID Application), download the" >&2
|
||||
echo " .cer, and double-click it to install into your login keychain." >&2
|
||||
echo " Verify with: security find-identity -v -p codesigning" >&2
|
||||
exit 1
|
||||
fi
|
||||
export APPLE_SIGNING_IDENTITY="$SIGNING_IDENTITY"
|
||||
echo ">> Signing identity: $SIGNING_IDENTITY"
|
||||
|
||||
# 2. Load notarization credentials.
|
||||
NOTARIZE_ENV="${HOME}/.config/gridline/notarize.env"
|
||||
if [ -f "$NOTARIZE_ENV" ]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$NOTARIZE_ENV"
|
||||
set +a
|
||||
fi
|
||||
if [ -z "${APPLE_API_KEY:-}" ] || [ -z "${APPLE_API_ISSUER:-}" ]; then
|
||||
if [ "${GRIDLINE_SKIP_NOTARIZE:-0}" = "1" ]; then
|
||||
echo ">> WARNING: notarization credentials missing; GRIDLINE_SKIP_NOTARIZE=1 set." >&2
|
||||
echo " Building signed but NOT notarized (test-only — users will still see a prompt)." >&2
|
||||
else
|
||||
echo "ERROR: Notarization credentials not configured." >&2
|
||||
echo " Create ${NOTARIZE_ENV} with APPLE_API_KEY and APPLE_API_ISSUER" >&2
|
||||
echo " (and APPLE_API_KEY_PATH, or place the .p8 at ~/.appstoreconnect/private_keys/)." >&2
|
||||
echo " See the README's 'macOS signing' section for the App Store Connect API key setup." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo ">> Notarization: API key ${APPLE_API_KEY} (issuer ${APPLE_API_ISSUER})"
|
||||
fi
|
||||
|
||||
# ---- build the app (both arches) ------------------------------------------
|
||||
cd "${WORKSPACE}/desktop"
|
||||
echo ">> Installing frontend dependencies..."
|
||||
@@ -130,6 +187,24 @@ VERSION="${TAG#v}"
|
||||
BUNDLE_ARM="${WORKSPACE}/desktop/src-tauri/target/aarch64-apple-darwin/release/bundle"
|
||||
BUNDLE_INTEL="${WORKSPACE}/desktop/src-tauri/target/x86_64-apple-darwin/release/bundle"
|
||||
|
||||
# ---- verify signing + notarization -----------------------------------------
|
||||
# Confirm both .app bundles are properly signed and carry a stapled
|
||||
# notarization ticket before we upload them. spctl can lag right after
|
||||
# notarization (assessment cache), so stapler validate is the authoritative
|
||||
# check; a pending spctl is only a warning.
|
||||
for APP in \
|
||||
"${BUNDLE_ARM}/macos/Gridline.app" \
|
||||
"${BUNDLE_INTEL}/macos/Gridline.app"; do
|
||||
[ -d "$APP" ] || { echo "missing $APP" >&2; exit 1; }
|
||||
echo ">> Verifying $APP"
|
||||
codesign --verify --deep --strict --verbose=2 "$APP" \
|
||||
|| { echo "codesign verify FAILED" >&2; exit 1; }
|
||||
xcrun stapler validate "$APP" \
|
||||
|| { echo "notarization ticket not stapled" >&2; exit 1; }
|
||||
spctl --assess --type execute --verbose=4 "$APP" \
|
||||
|| echo " (spctl assessment pending — normal right after notarization; stapler validate passed)"
|
||||
done
|
||||
|
||||
# ---- create/ensure release + upload DMGs -----------------------------------
|
||||
API="${GITEA_SERVER}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}"
|
||||
AUTH="Authorization: token ${GITEA_TOKEN}"
|
||||
|
||||
+3
-20
@@ -60,7 +60,7 @@
|
||||
const keepLabel = downloadBtn.hasAttribute("data-download-label");
|
||||
|
||||
const releasesUrl = "https://git.ranio.xyz/adrianbonpin/gridline/releases";
|
||||
const version = "0.7.12";
|
||||
const version = "0.7.13";
|
||||
|
||||
if (isMobile) {
|
||||
downloadBtn.href = releasesUrl;
|
||||
@@ -68,9 +68,6 @@
|
||||
} else if (isMac) {
|
||||
downloadBtn.href = `${releasesUrl}/download/v${version}/Gridline_${version}_aarch64.dmg`;
|
||||
if (!keepLabel) downloadBtn.textContent = "Download for macOS";
|
||||
if (downloadBtn.id === "download") {
|
||||
document.getElementById("macos-hint")?.classList.remove("hidden");
|
||||
}
|
||||
} else if (isWin) {
|
||||
downloadBtn.href = `${releasesUrl}/download/v${version}/Gridline_${version}_x64-setup.exe`;
|
||||
if (!keepLabel) downloadBtn.textContent = "Download for Windows";
|
||||
@@ -83,18 +80,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("copy-quarantine")?.addEventListener("click", async () => {
|
||||
const command = "sudo xattr -dr com.apple.quarantine /Applications/Gridline.app";
|
||||
try {
|
||||
await navigator.clipboard.writeText(command);
|
||||
const btn = document.getElementById("copy-quarantine");
|
||||
if (!btn) return;
|
||||
const original = btn.textContent;
|
||||
btn.textContent = "Copied";
|
||||
setTimeout(() => (btn.textContent = original), 1500);
|
||||
} catch {}
|
||||
});
|
||||
|
||||
// Nav scroll background
|
||||
const nav = document.getElementById("nav");
|
||||
function onScroll() {
|
||||
@@ -141,24 +126,22 @@
|
||||
const subtitle = hero.querySelector(".hero-animate > p:nth-of-type(2)");
|
||||
const buttons = hero.querySelector(".hero-animate > div");
|
||||
const screenshot = hero.querySelector(".hero-screenshot");
|
||||
const macosHint = hero.querySelector("#macos-hint");
|
||||
|
||||
if (reducedMotion) {
|
||||
// Reduced motion: reveal the hero immediately (CSS hides it at first
|
||||
// paint to avoid flicker, but the timeline below is skipped). Section
|
||||
// reveals below still run through the IntersectionObserver.
|
||||
anime.set([eyebrow, h1, subtitle, buttons, screenshot, macosHint], { opacity: 1, translateY: 0 });
|
||||
anime.set([eyebrow, h1, subtitle, buttons, screenshot], { opacity: 1, translateY: 0 });
|
||||
} else {
|
||||
const heroTl = anime.timeline({ easing: "easeOutExpo" });
|
||||
|
||||
anime.set([eyebrow, h1, subtitle, buttons, screenshot, macosHint], { opacity: 0, translateY: 20 });
|
||||
anime.set([eyebrow, h1, subtitle, buttons, screenshot], { opacity: 0, translateY: 20 });
|
||||
anime.set(screenshot, { opacity: 0, scale: 0.96, translateY: 0 });
|
||||
|
||||
if (eyebrow) heroTl.add({ targets: eyebrow, opacity: [0, 1], translateY: [15, 0] }, 0);
|
||||
if (h1) heroTl.add({ targets: h1, opacity: [0, 1], translateY: [30, 0], duration: 800 }, 100);
|
||||
if (subtitle) heroTl.add({ targets: subtitle, opacity: [0, 1], translateY: [20, 0] }, 250);
|
||||
if (buttons) heroTl.add({ targets: buttons, opacity: [0, 1], translateY: [20, 0] }, 350);
|
||||
if (macosHint) heroTl.add({ targets: macosHint, opacity: [0, 1], translateY: [20, 0] }, 400);
|
||||
if (screenshot) heroTl.add({ targets: screenshot, opacity: [0, 1], scale: [0.96, 1], duration: 900 }, 450);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,13 @@ export interface ChangelogEntry {
|
||||
}
|
||||
|
||||
export const changelogEntries: ChangelogEntry[] = [
|
||||
{
|
||||
version: "0.7.13",
|
||||
date: "2026-09-04",
|
||||
highlights: [
|
||||
"macOS is now Developer-ID signed and notarized — the app is properly code-signed with a Developer ID Application certificate and notarized by Apple, so macOS opens it without the Gatekeeper 'Open Anyway' prompt or the xattr quarantine workaround.",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "0.7.12",
|
||||
date: "2026-09-01",
|
||||
|
||||
@@ -15,7 +15,7 @@ import queryEditor from "../assets/screenshots/query-editor.png";
|
||||
import erDiagram from "../assets/screenshots/er-diagram.png";
|
||||
import home from "../assets/screenshots/home.png";
|
||||
import dataGrid from "../assets/screenshots/data-grid.png";
|
||||
const version = "0.7.12";
|
||||
const version = "0.7.13";
|
||||
const site = "https://getgridline.app";
|
||||
const jsonLd = [
|
||||
buildSoftwareApplicationJsonLd({
|
||||
@@ -80,14 +80,6 @@ const jsonLd = [
|
||||
View on Gitea
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="macos-hint" class="hidden max-w-lg mx-auto w-full rounded-xl border border-[var(--border)] bg-[var(--surface)] p-3 text-left mt-4">
|
||||
<p class="text-xs text-[var(--text-muted)] mb-2">First launch on macOS? Run this in Terminal:</p>
|
||||
<div class="flex items-center justify-between gap-3 rounded-lg bg-[var(--bg)] border border-[var(--border)] px-3 py-2">
|
||||
<code class="font-mono text-xs truncate">sudo xattr -dr com.apple.quarantine /Applications/Gridline.app</code>
|
||||
<button id="copy-quarantine" class="text-xs font-medium text-[var(--primary)] hover:text-[var(--primary-hover)] transition-colors shrink-0" aria-label="Copy command">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-screenshot mt-14 md:mt-20 mx-auto max-w-6xl">
|
||||
|
||||
Reference in New Issue
Block a user