mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
The build script fix only applies to future tags. For v0.1.24 (and any tag built before that fix), we need the workflow itself to remove the CUDA .so files after building the managed runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
484 lines
18 KiB
YAML
484 lines
18 KiB
YAML
name: Desktop Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
- "desktop-v*"
|
|
- "desktop-macos-v*"
|
|
- "desktop-linux-v*"
|
|
- "desktop-windows-v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Existing tag to build (e.g. v0.1.0)"
|
|
required: true
|
|
type: string
|
|
platform:
|
|
description: "Optional desktop platform to build."
|
|
required: false
|
|
default: "all"
|
|
type: choice
|
|
options:
|
|
- all
|
|
- macos
|
|
- linux
|
|
- windows
|
|
|
|
concurrency:
|
|
group: desktop-release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
SOURCE_TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref_name }}
|
|
|
|
jobs:
|
|
publish-macos:
|
|
if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'macos')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-macos-v'))) }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- runner: macos-14
|
|
rust_target: aarch64-apple-darwin
|
|
- runner: macos-15-intel
|
|
rust_target: x86_64-apple-darwin
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: ${{ matrix.runner }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
source_tag="${SOURCE_TAG}"
|
|
release_tag="$source_tag"
|
|
for prefix in desktop-windows-v desktop-linux-v desktop-macos-v desktop-v; do
|
|
if [[ "$source_tag" == ${prefix}* ]]; then
|
|
release_tag="v${source_tag#${prefix}}"
|
|
break
|
|
fi
|
|
done
|
|
echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV"
|
|
|
|
version="${release_tag#v}"
|
|
echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV"
|
|
|
|
if [[ "$source_tag" == *gha-smoke* ]]; then
|
|
echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV"
|
|
else
|
|
echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV"
|
|
fi
|
|
|
|
- name: Set desktop version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
console.log(`Setting desktop version to ${version}`);
|
|
|
|
const tauriConfPath = path.join('packages', 'desktop', 'src-tauri', 'tauri.conf.json');
|
|
const tauriConfText = fs.readFileSync(tauriConfPath, 'utf8');
|
|
const tauriRe = /("version"\s*:\s*")([^"]+)(")/;
|
|
if (!tauriRe.test(tauriConfText)) throw new Error('Failed to find version in tauri.conf.json');
|
|
fs.writeFileSync(tauriConfPath, tauriConfText.replace(tauriRe, `$1${version}$3`));
|
|
|
|
const cargoTomlPath = path.join('packages', 'desktop', 'src-tauri', 'Cargo.toml');
|
|
const lines = fs.readFileSync(cargoTomlPath, 'utf8').split(/\r?\n/);
|
|
let inPackage = false, updated = false;
|
|
const result = lines.map((line) => {
|
|
if (/^\[package\]\s*$/.test(line)) inPackage = true;
|
|
else if (inPackage && /^\[/.test(line)) inPackage = false;
|
|
if (inPackage && /^version\s*=\s*".*"\s*$/.test(line)) {
|
|
updated = true;
|
|
return `version = "${version}"`;
|
|
}
|
|
return line;
|
|
});
|
|
if (!updated) throw new Error('Failed to update Cargo.toml version');
|
|
fs.writeFileSync(cargoTomlPath, result.join('\n') + '\n');
|
|
NODE
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install Rust stable
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.rust_target }}
|
|
|
|
- name: Restore Rust cache
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: desktop-release-macos-${{ matrix.rust_target }}
|
|
workspaces: |
|
|
.
|
|
packages/desktop/src-tauri -> target
|
|
|
|
- name: Install JS dependencies
|
|
run: npm ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build web app for Tauri
|
|
run: npm run build:web --workspace=@getpaseo/app
|
|
|
|
- name: Build managed runtime
|
|
run: npm run prepare:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Validate managed runtime bundle
|
|
run: npm run validate:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Import Apple code-signing certificate
|
|
uses: apple-actions/import-codesign-certs@v3
|
|
with:
|
|
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
|
|
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
|
|
- name: Sign bundled managed runtime
|
|
env:
|
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
run: node ./packages/desktop/scripts/sign-managed-runtime-macos.mjs
|
|
|
|
- name: Detect existing GitHub release state
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then
|
|
:
|
|
else
|
|
release_draft="false"
|
|
fi
|
|
echo "RELEASE_DRAFT=$release_draft" >> "$GITHUB_ENV"
|
|
|
|
- name: Build and publish macOS Tauri release
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
with:
|
|
projectPath: packages/desktop
|
|
tagName: ${{ env.RELEASE_TAG }}
|
|
releaseName: Paseo ${{ env.RELEASE_TAG }}
|
|
releaseBody: See the assets to download and install this version.
|
|
releaseDraft: ${{ env.RELEASE_DRAFT }}
|
|
prerelease: false
|
|
args: --target ${{ matrix.rust_target }}
|
|
|
|
- name: Build macOS app (smoke only)
|
|
if: env.IS_SMOKE_TAG == 'true'
|
|
run: npm run tauri --workspace=@getpaseo/desktop build -- --target ${{ matrix.rust_target }} --no-bundle
|
|
|
|
publish-linux:
|
|
if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'linux')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-linux-v'))) }}
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: ubuntu-22.04
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
source_tag="${SOURCE_TAG}"
|
|
release_tag="$source_tag"
|
|
for prefix in desktop-windows-v desktop-linux-v desktop-macos-v desktop-v; do
|
|
if [[ "$source_tag" == ${prefix}* ]]; then
|
|
release_tag="v${source_tag#${prefix}}"
|
|
break
|
|
fi
|
|
done
|
|
echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV"
|
|
|
|
version="${release_tag#v}"
|
|
echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV"
|
|
|
|
if [[ "$source_tag" == *gha-smoke* ]]; then
|
|
echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV"
|
|
else
|
|
echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV"
|
|
fi
|
|
|
|
- name: Set desktop version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
console.log(`Setting desktop version to ${version}`);
|
|
|
|
const tauriConfPath = path.join('packages', 'desktop', 'src-tauri', 'tauri.conf.json');
|
|
const tauriConfText = fs.readFileSync(tauriConfPath, 'utf8');
|
|
const tauriRe = /("version"\s*:\s*")([^"]+)(")/;
|
|
if (!tauriRe.test(tauriConfText)) throw new Error('Failed to find version in tauri.conf.json');
|
|
fs.writeFileSync(tauriConfPath, tauriConfText.replace(tauriRe, `$1${version}$3`));
|
|
|
|
const cargoTomlPath = path.join('packages', 'desktop', 'src-tauri', 'Cargo.toml');
|
|
const lines = fs.readFileSync(cargoTomlPath, 'utf8').split(/\r?\n/);
|
|
let inPackage = false, updated = false;
|
|
const result = lines.map((line) => {
|
|
if (/^\[package\]\s*$/.test(line)) inPackage = true;
|
|
else if (inPackage && /^\[/.test(line)) inPackage = false;
|
|
if (inPackage && /^version\s*=\s*".*"\s*$/.test(line)) {
|
|
updated = true;
|
|
return `version = "${version}"`;
|
|
}
|
|
return line;
|
|
});
|
|
if (!updated) throw new Error('Failed to update Cargo.toml version');
|
|
fs.writeFileSync(cargoTomlPath, result.join('\n') + '\n');
|
|
NODE
|
|
|
|
- name: Install Linux packaging dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libappindicator3-dev librsvg2-dev patchelf libfuse2
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install Rust stable
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Restore Rust cache
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: desktop-release-linux
|
|
workspaces: |
|
|
.
|
|
packages/desktop/src-tauri -> target
|
|
|
|
- name: Install JS dependencies
|
|
run: npm ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build web app for Tauri
|
|
run: npm run build:web --workspace=@getpaseo/app
|
|
|
|
- name: Build managed runtime
|
|
run: npm run prepare:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Validate managed runtime bundle
|
|
run: npm run validate:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Remove CUDA/TensorRT providers from onnxruntime
|
|
shell: bash
|
|
run: |
|
|
find packages/desktop/src-tauri/resources/managed-runtime -path '*/onnxruntime-node/bin/*' \( -name '*cuda*' -o -name '*tensorrt*' \) -delete || true
|
|
|
|
- name: Detect existing GitHub release state
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then
|
|
:
|
|
else
|
|
release_draft="false"
|
|
fi
|
|
echo "RELEASE_DRAFT=$release_draft" >> "$GITHUB_ENV"
|
|
|
|
- name: Build and publish Linux Tauri release
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
NO_STRIP: "true"
|
|
with:
|
|
projectPath: packages/desktop
|
|
tagName: ${{ env.RELEASE_TAG }}
|
|
releaseName: Paseo ${{ env.RELEASE_TAG }}
|
|
releaseBody: See the assets to download and install this version.
|
|
releaseDraft: ${{ env.RELEASE_DRAFT }}
|
|
prerelease: false
|
|
args: --bundles appimage --verbose
|
|
|
|
- name: Build Linux app (smoke only)
|
|
if: env.IS_SMOKE_TAG == 'true'
|
|
run: npm run tauri --workspace=@getpaseo/desktop build -- --no-bundle
|
|
|
|
publish-windows:
|
|
if: ${{ (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'windows')) || (github.event_name == 'push' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'desktop-v') || startsWith(github.ref_name, 'desktop-windows-v'))) }}
|
|
permissions:
|
|
contents: write
|
|
packages: read
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }}
|
|
|
|
- name: Resolve release metadata
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
source_tag="${SOURCE_TAG}"
|
|
release_tag="$source_tag"
|
|
for prefix in desktop-windows-v desktop-linux-v desktop-macos-v desktop-v; do
|
|
if [[ "$source_tag" == ${prefix}* ]]; then
|
|
release_tag="v${source_tag#${prefix}}"
|
|
break
|
|
fi
|
|
done
|
|
echo "RELEASE_TAG=$release_tag" >> "$GITHUB_ENV"
|
|
|
|
version="${release_tag#v}"
|
|
echo "DESKTOP_VERSION=$version" >> "$GITHUB_ENV"
|
|
|
|
if [[ "$source_tag" == *gha-smoke* ]]; then
|
|
echo "IS_SMOKE_TAG=true" >> "$GITHUB_ENV"
|
|
else
|
|
echo "IS_SMOKE_TAG=false" >> "$GITHUB_ENV"
|
|
fi
|
|
|
|
- name: Set desktop version from tag
|
|
shell: bash
|
|
run: |
|
|
node <<'NODE'
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const version = process.env.DESKTOP_VERSION;
|
|
if (!version) throw new Error('DESKTOP_VERSION env var is missing');
|
|
console.log(`Setting desktop version to ${version}`);
|
|
|
|
const tauriConfPath = path.join('packages', 'desktop', 'src-tauri', 'tauri.conf.json');
|
|
const tauriConfText = fs.readFileSync(tauriConfPath, 'utf8');
|
|
const tauriRe = /("version"\s*:\s*")([^"]+)(")/;
|
|
if (!tauriRe.test(tauriConfText)) throw new Error('Failed to find version in tauri.conf.json');
|
|
fs.writeFileSync(tauriConfPath, tauriConfText.replace(tauriRe, `$1${version}$3`));
|
|
|
|
const cargoTomlPath = path.join('packages', 'desktop', 'src-tauri', 'Cargo.toml');
|
|
const lines = fs.readFileSync(cargoTomlPath, 'utf8').split(/\r?\n/);
|
|
let inPackage = false, updated = false;
|
|
const result = lines.map((line) => {
|
|
if (/^\[package\]\s*$/.test(line)) inPackage = true;
|
|
else if (inPackage && /^\[/.test(line)) inPackage = false;
|
|
if (inPackage && /^version\s*=\s*".*"\s*$/.test(line)) {
|
|
updated = true;
|
|
return `version = "${version}"`;
|
|
}
|
|
return line;
|
|
});
|
|
if (!updated) throw new Error('Failed to update Cargo.toml version');
|
|
fs.writeFileSync(cargoTomlPath, result.join('\n') + '\n');
|
|
NODE
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: "npm"
|
|
cache-dependency-path: package-lock.json
|
|
registry-url: "https://npm.pkg.github.com"
|
|
scope: "@boudra"
|
|
|
|
- name: Install Rust stable
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Restore Rust cache
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: desktop-release-windows
|
|
workspaces: |
|
|
.
|
|
packages/desktop/src-tauri -> target
|
|
|
|
- name: Install JS dependencies
|
|
run: npm ci
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build web app for Tauri
|
|
run: npm run build:web --workspace=@getpaseo/app
|
|
|
|
- name: Build managed runtime
|
|
run: npm run prepare:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Validate managed runtime bundle
|
|
run: npm run validate:managed-runtime --workspace=@getpaseo/desktop
|
|
|
|
- name: Detect existing GitHub release state
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if release_draft="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then
|
|
:
|
|
else
|
|
release_draft="false"
|
|
fi
|
|
echo "RELEASE_DRAFT=$release_draft" >> "$GITHUB_ENV"
|
|
|
|
- name: Build and publish Windows Tauri release
|
|
if: env.IS_SMOKE_TAG != 'true'
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
with:
|
|
projectPath: packages/desktop
|
|
tagName: ${{ env.RELEASE_TAG }}
|
|
releaseName: Paseo ${{ env.RELEASE_TAG }}
|
|
releaseBody: See the assets to download and install this version.
|
|
releaseDraft: ${{ env.RELEASE_DRAFT }}
|
|
prerelease: false
|
|
args: --bundles nsis,msi
|
|
|
|
- name: Build Windows app (smoke only)
|
|
if: env.IS_SMOKE_TAG == 'true'
|
|
run: npm run tauri --workspace=@getpaseo/desktop build -- --no-bundle
|
|
env:
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|