Skip to content

Build

Build #97

Workflow file for this run

name: Build
on:
push:
tags:
- "v*"
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version to build (e.g., 1.0.0)"
required: true
type: string
permissions:
contents: write
actions: write
pull-requests: write
jobs:
# Pre-build SvelteKit app once and share across all platforms
prebuild:
name: Build SvelteKit App
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
- name: Install dependencies
run: |
npm ci --prefer-offline || \
npm ci --prefer-offline || \
npm ci
env:
ONNXRUNTIME_NODE_INSTALL_CUDA: skip
- name: Build SvelteKit
run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: sveltekit-build
path: build/
retention-days: 1
build:
name: Build (${{ matrix.platform }})
runs-on: ${{ matrix.os }}
needs: prebuild
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
platform: mac-arm64
arch: arm64
- os: macos-14
platform: mac-x64
arch: x64
- os: windows-latest
platform: win-x64
arch: x64
- os: windows-latest
platform: win-arm64
arch: arm64
- os: ubuntu-latest
platform: linux-x64
arch: x64
linux_targets: deb rpm AppImage
- os: ubuntu-latest
platform: linux-arm64
arch: arm64
linux_targets: AppImage
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Get version from tag, release or input
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
elif [ "${{ github.event_name }}" = "push" ]; then
VERSION="${GITHUB_REF#refs/tags/v}"
else
VERSION="${{ inputs.version }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
- name: Cache Electron binaries
uses: actions/cache@v5
with:
path: |
~/Library/Caches/electron
~/Library/Caches/electron-builder
~/.cache/electron
~/.cache/electron-builder
~/AppData/Local/electron/Cache
~/AppData/Local/electron-builder/Cache
key: ${{ runner.os }}-${{ matrix.arch }}-electron-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-electron-
- name: Install dependencies
run: |
npm ci --prefer-offline || \
npm ci --prefer-offline || \
npm ci
env:
ONNXRUNTIME_NODE_INSTALL_CUDA: skip
- name: Download SvelteKit build
uses: actions/download-artifact@v8
with:
name: sveltekit-build
path: build/
- name: Update package.json version
run: npm version ${{ steps.version.outputs.version }} --no-git-tag-version --allow-same-version
- name: Build Electron (macOS)
if: startsWith(matrix.platform, 'mac-')
run: npm run electron:build:mac -- --${{ matrix.arch }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Electron (Windows)
if: startsWith(matrix.platform, 'win-')
run: npm run electron:build:win -- --${{ matrix.arch }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Electron (Linux)
if: startsWith(matrix.platform, 'linux-')
run: npm run build && npx electron-builder --linux ${{ matrix.linux_targets }} --${{ matrix.arch }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Artifacts
uses: actions/upload-artifact@v7
with:
name: build-${{ matrix.platform }}
path: |
dist-electron/*.dmg
dist-electron/*.zip
dist-electron/*.exe
dist-electron/*.deb
dist-electron/*.rpm
dist-electron/*.AppImage
retention-days: 7
publish-release:
name: Publish Release
runs-on: ubuntu-latest
needs: build
if: success()
steps:
- name: Get version from input
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
elif [ "${{ github.event_name }}" = "push" ]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="v${{ inputs.version }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Publish Draft Release
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: releases } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const draftRelease = releases.find(r => r.tag_name === '${{ steps.version.outputs.version }}' && r.draft);
if (draftRelease) {
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: draftRelease.id,
draft: false
});
console.log(`✅ Published release ${draftRelease.tag_name}`);
} else {
console.log('⚠️ No draft release found for ${{ steps.version.outputs.version }}');
}
- name: Sync main to dev
continue-on-error: true
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: comparison } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: 'dev',
head: 'main'
});
if (comparison.ahead_by > 0) {
// Check for existing PR
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.repo.owner}:main`,
base: 'dev',
state: 'open'
});
let pr;
if (prs.length > 0) {
pr = prs[0];
console.log(`📋 Found existing PR #${pr.number}`);
} else {
const { data: newPr } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
head: 'main',
base: 'dev',
title: 'chore: sync main to dev after ${{ steps.version.outputs.version }}',
body: 'Automated PR to sync release changes from main to dev.'
});
pr = newPr;
console.log(`📋 Created PR #${pr.number}`);
}
// Enable auto-merge
try {
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
merge_method: 'merge'
});
console.log('✅ Merged PR');
} catch (e) {
console.log('⚠️ Could not merge (may need manual approval):', e.message);
}
} else {
console.log('ℹ️ dev is up to date with main');
}
- name: Trigger Deploy Workflow
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'deploy.yml',
ref: 'main'
})
cleanup-failed-release:
name: Cleanup Failed Release
runs-on: ubuntu-latest
needs: build
if: failure() || cancelled()
steps:
- name: Get version from input
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
elif [ "${{ github.event_name }}" = "push" ]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="v${{ inputs.version }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Delete Draft Release
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: releases } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const draftRelease = releases.find(r => r.tag_name === '${{ steps.version.outputs.version }}' && r.draft);
if (draftRelease) {
await github.rest.repos.deleteRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: draftRelease.id
});
console.log(`🗑️ Deleted failed draft release ${draftRelease.tag_name}`);
} else {
console.log('⚠️ No draft release found to delete for ${{ steps.version.outputs.version }}');
}