Skip to content

Release v6.3

Release v6.3 #175

Workflow file for this run

name: Build Electron App
run-name: ${{ startsWith(github.ref, 'refs/tags/') && format('Release {0}', github.ref_name) || format('Cache warm ({0})', github.ref_name) }}
on:
push:
tags:
- v* # full build + release
branches:
- main # cache warming only — no packaging
workflow_dispatch:
jobs:
build:
strategy:
matrix:
include:
# - os: windows
# platform: win
# artifact: .exe
- os: macos
platform: mac
artifact: .dmg
# - os: ubuntu
# platform: linux
# artifact: .AppImage
runs-on: ${{ matrix.os }}-latest
env:
ELECTRON_CACHE: ${{ github.workspace }}/.cache/electron
ELECTRON_BUILDER_CACHE: ${{ github.workspace }}/.cache/electron-builder
steps:
- uses: actions/checkout@v6
# Caches ~/.npm tarballs (per-OS, ~300 MB) so npm ci downloads are instant.
# NOT caching node_modules (1.6 GB — upload times out and never saves).
- uses: actions/setup-node@v6
with:
node-version: '22'
# Cache node_modules keyed on the lockfile — skips npm install entirely on hit
- uses: actions/cache/restore@v4
id: cache-deps
with:
path: |
~/.npm
node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: node-modules-${{ runner.os }}-
- name: Install Python setuptools (node-gyp needs distutils, removed in Python 3.12)
if: steps.cache-deps.outputs.cache-hit != 'true'
run: pip3 install setuptools --break-system-packages
- name: Install dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
run: npm ci
- uses: actions/cache/save@v4
if: "!startsWith(github.ref, 'refs/tags/') && steps.cache-deps.outputs.cache-hit != 'true'"
with:
path: |
~/.npm
node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
# .output is only 17 MB and platform-independent.
# Saved to main on every push → tag builds find it via the main fallback.
- uses: actions/cache/restore@v4
id: cache-nuxt
with:
path: .output
key: nuxt-${{ hashFiles('app/**', 'server/**', 'nuxt.config.ts', 'package-lock.json') }}
- name: Build Nuxt
if: steps.cache-nuxt.outputs.cache-hit != 'true'
run: npx nuxt build
- uses: actions/cache/save@v4
if: "!startsWith(github.ref, 'refs/tags/') && steps.cache-nuxt.outputs.cache-hit != 'true'"
with:
path: .output
key: nuxt-${{ hashFiles('app/**', 'server/**', 'nuxt.config.ts', 'package-lock.json') }}
# Remove native modules from Nuxt output so Nitro uses the root copies
# (which electron-builder rebuilds for the correct Electron ABI)
- name: Fix native modules for Electron
shell: bash
run: rm -rf .output/server/node_modules/node-pty .output/server/node_modules/ssh2
# Remove all node-pty prebuilds so electron-builder rebuilds from source
# for the correct Electron ABI (prebuilds are for Node.js, not Electron)
- name: Remove node-pty prebuilds
shell: bash
run: rm -rf node_modules/node-pty/prebuilds
# Electron binary + prebuilt native module binaries (~200 MB per platform).
# Always restored/saved so main-push warming populates the cache for tag builds.
- uses: actions/cache/restore@v4
with:
path: |
${{ env.ELECTRON_CACHE }}
${{ env.ELECTRON_BUILDER_CACHE }}
key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: electron-${{ runner.os }}-
# On main: --dir downloads the electron binary + prebuilts, skips installer creation (~1 min).
# On tag: full build produces the installable artifact (~3:45).
- name: Package with electron-builder
run: npx electron-builder --${{ matrix.platform }} ${{ startsWith(github.ref, 'refs/tags/') && '--publish never' || '--dir' }}
env:
CSC_IDENTITY_AUTO_DISCOVERY: false
# APPLE_ID: ${{ secrets.APPLE_ID }}
# APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- uses: actions/cache/save@v4
if: "!startsWith(github.ref, 'refs/tags/')"
with:
path: |
${{ env.ELECTRON_CACHE }}
${{ env.ELECTRON_BUILDER_CACHE }}
key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- name: Upload artifact
if: startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v4
with:
name: LoCode-${{ matrix.os }}
path: dist/*${{ matrix.artifact }}
if-no-files-found: error
check_tag_branch:
if: startsWith(github.ref, 'refs/tags/')
needs: build
runs-on: ubuntu-latest
outputs:
on_main: ${{ steps.check.outputs.output }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch main
run: git fetch origin main --tags
- name: Check if tag is on main
id: check
run: echo "output=$(git merge-base --is-ancestor ${{ github.sha }} origin/main; echo $?)" >> $GITHUB_OUTPUT
create_release:
if: needs.check_tag_branch.outputs.on_main == 0
needs: check_tag_branch
runs-on: ubuntu-latest
steps:
- name: Download files
uses: actions/download-artifact@v4
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: LoCode-*/*
name: Release ${{ github.ref_name }}
generate_release_notes: true