489 lines
22 KiB
YAML
489 lines
22 KiB
YAML
name: Build Tauri Applications
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
platform:
|
||
description: "Platform to build (windows, macos, linux, or all)"
|
||
required: true
|
||
default: "all"
|
||
type: choice
|
||
options:
|
||
- all
|
||
- windows
|
||
- macos
|
||
- linux
|
||
pull_request:
|
||
branches: [main, V2, V2-tauri-windows]
|
||
paths:
|
||
- 'frontend/src-tauri/**'
|
||
- 'frontend/src/**'
|
||
- 'frontend/package.json'
|
||
- 'frontend/package-lock.json'
|
||
- '.github/workflows/tauri-build.yml'
|
||
push:
|
||
branches: [main, V2, V2-tauri-windows]
|
||
paths:
|
||
- 'frontend/src-tauri/**'
|
||
- 'frontend/src/**'
|
||
- 'frontend/package.json'
|
||
- 'frontend/package-lock.json'
|
||
- '.github/workflows/tauri-build.yml'
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
jobs:
|
||
determine-matrix:
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||
steps:
|
||
- name: Determine build matrix
|
||
id: set-matrix
|
||
run: |
|
||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||
case "${{ github.event.inputs.platform }}" in
|
||
"windows")
|
||
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"}]}' >> $GITHUB_OUTPUT
|
||
;;
|
||
# "macos")
|
||
# echo 'matrix={"include":[{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-13","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}]}' >> $GITHUB_OUTPUT
|
||
# ;;
|
||
"linux")
|
||
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
|
||
;;
|
||
*)
|
||
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
|
||
# Disabled Mac builds: {"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-13","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}
|
||
;;
|
||
esac
|
||
else
|
||
# For PR/push events, build all platforms
|
||
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
|
||
# Disabled Mac builds: {"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-13","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}
|
||
fi
|
||
|
||
build:
|
||
needs: determine-matrix
|
||
strategy:
|
||
fail-fast: false
|
||
matrix: ${{ fromJson(needs.determine-matrix.outputs.matrix) }}
|
||
runs-on: ${{ matrix.platform }}
|
||
env:
|
||
SM_API_KEY: ${{ secrets.SM_API_KEY }}
|
||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||
steps:
|
||
- name: Harden Runner
|
||
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
|
||
with:
|
||
egress-policy: audit
|
||
|
||
- name: Checkout repository
|
||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||
|
||
- name: Install dependencies (ubuntu only)
|
||
if: matrix.platform == 'ubuntu-22.04'
|
||
run: |
|
||
sudo apt-get update
|
||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 20
|
||
cache: 'npm'
|
||
cache-dependency-path: frontend/package-lock.json
|
||
|
||
- name: Setup Rust
|
||
uses: dtolnay/rust-toolchain@stable
|
||
with:
|
||
toolchain: stable
|
||
targets: ${{ (matrix.platform == 'macos-latest' || matrix.platform == 'macos-13') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||
|
||
|
||
|
||
- name: Set up JDK 21
|
||
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||
with:
|
||
java-version: "21"
|
||
distribution: "temurin"
|
||
|
||
- name: Build Java backend with JLink
|
||
working-directory: ./
|
||
shell: bash
|
||
run: |
|
||
chmod +x ./gradlew
|
||
echo "🔧 Building Stirling-PDF JAR..."
|
||
# STIRLING_PDF_DESKTOP_UI=false ./gradlew clean bootJar --no-daemon
|
||
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
||
|
||
# Find the built JAR
|
||
STIRLING_JAR=$(ls app/core/build/libs/stirling-pdf-*.jar | head -n 1)
|
||
echo "✅ Built JAR: $STIRLING_JAR"
|
||
|
||
# Create Tauri directories
|
||
mkdir -p ./frontend/src-tauri/libs
|
||
mkdir -p ./frontend/src-tauri/runtime
|
||
|
||
# Copy JAR to Tauri libs
|
||
cp "$STIRLING_JAR" ./frontend/src-tauri/libs/
|
||
echo "✅ JAR copied to Tauri libs"
|
||
|
||
# Analyze JAR dependencies for jlink modules
|
||
echo "🔍 Analyzing JAR dependencies..."
|
||
if command -v jdeps &> /dev/null; then
|
||
DETECTED_MODULES=$(jdeps --print-module-deps --ignore-missing-deps "$STIRLING_JAR" 2>/dev/null || echo "")
|
||
if [ -n "$DETECTED_MODULES" ]; then
|
||
echo "📋 jdeps detected modules: $DETECTED_MODULES"
|
||
MODULES="$DETECTED_MODULES,java.compiler,java.instrument,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
|
||
else
|
||
echo "⚠️ jdeps analysis failed, using predefined modules"
|
||
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
|
||
fi
|
||
else
|
||
echo "⚠️ jdeps not available, using predefined modules"
|
||
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
|
||
fi
|
||
|
||
# Create custom JRE with jlink (always rebuild)
|
||
echo "🔧 Creating custom JRE with jlink..."
|
||
echo "📋 Using modules: $MODULES"
|
||
|
||
# Remove any existing JRE
|
||
rm -rf ./frontend/src-tauri/runtime/jre
|
||
|
||
# Create the custom JRE
|
||
jlink \
|
||
--add-modules "$MODULES" \
|
||
--strip-debug \
|
||
--compress=2 \
|
||
--no-header-files \
|
||
--no-man-pages \
|
||
--output ./frontend/src-tauri/runtime/jre
|
||
|
||
if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then
|
||
echo "❌ Failed to create JLink runtime"
|
||
exit 1
|
||
fi
|
||
|
||
# Test the bundled runtime
|
||
if [ -f "./frontend/src-tauri/runtime/jre/bin/java" ]; then
|
||
RUNTIME_VERSION=$(./frontend/src-tauri/runtime/jre/bin/java --version 2>&1 | head -n 1)
|
||
echo "✅ Custom JRE created successfully: $RUNTIME_VERSION"
|
||
else
|
||
echo "❌ Custom JRE executable not found"
|
||
exit 1
|
||
fi
|
||
|
||
# Calculate runtime size
|
||
RUNTIME_SIZE=$(du -sh ./frontend/src-tauri/runtime/jre | cut -f1)
|
||
echo "📊 Custom JRE size: $RUNTIME_SIZE"
|
||
env:
|
||
DISABLE_ADDITIONAL_FEATURES: true
|
||
|
||
- name: Install frontend dependencies
|
||
working-directory: ./frontend
|
||
run: npm install
|
||
|
||
# DigiCert KeyLocker Setup (Cloud HSM)
|
||
- name: Setup DigiCert KeyLocker
|
||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' }}
|
||
uses: digicert/ssm-code-signing@v1.1.0
|
||
env:
|
||
SM_API_KEY: ${{ secrets.SM_API_KEY }}
|
||
SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
|
||
SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }}
|
||
SM_KEYPAIR_ALIAS: ${{ secrets.SM_KEYPAIR_ALIAS }}
|
||
SM_HOST: ${{ secrets.SM_HOST }}
|
||
|
||
- name: Setup DigiCert KeyLocker Certificate
|
||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' }}
|
||
shell: bash
|
||
run: |
|
||
echo "Setting up DigiCert KeyLocker environment..."
|
||
echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
||
echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
|
||
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
|
||
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
|
||
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
|
||
echo "SM_KEYPAIR_ALIAS=${{ secrets.SM_KEYPAIR_ALIAS }}" >> "$GITHUB_ENV"
|
||
|
||
# Traditional PFX Certificate Import (fallback if KeyLocker not configured)
|
||
- name: Import Windows Code Signing Certificate
|
||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY == '' }}
|
||
env:
|
||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||
shell: powershell
|
||
run: |
|
||
if ($env:WINDOWS_CERTIFICATE) {
|
||
Write-Host "Importing Windows Code Signing Certificate..."
|
||
|
||
# Decode base64 certificate and save to file
|
||
$certBytes = [Convert]::FromBase64String($env:WINDOWS_CERTIFICATE)
|
||
$certPath = Join-Path $env:RUNNER_TEMP "certificate.pfx"
|
||
[IO.File]::WriteAllBytes($certPath, $certBytes)
|
||
|
||
# Import certificate to CurrentUser\My store
|
||
$cert = Import-PfxCertificate -FilePath $certPath -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force)
|
||
|
||
# Extract and set thumbprint as environment variable
|
||
$thumbprint = $cert.Thumbprint
|
||
Write-Host "Certificate imported with thumbprint: $thumbprint"
|
||
echo "WINDOWS_CERTIFICATE_THUMBPRINT=$thumbprint" >> $env:GITHUB_ENV
|
||
|
||
# Clean up certificate file
|
||
Remove-Item $certPath
|
||
|
||
Write-Host "Windows certificate import completed."
|
||
} else {
|
||
Write-Host "⚠️ WINDOWS_CERTIFICATE secret not set - building unsigned binary"
|
||
}
|
||
|
||
# Disabled Mac builds - Import Apple Developer Certificate
|
||
# - name: Import Apple Developer Certificate
|
||
# if: matrix.platform == 'macos-latest' || matrix.platform == 'macos-13'
|
||
# env:
|
||
# APPLE_ID: ${{ secrets.APPLE_ID }}
|
||
# APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||
# APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||
# APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||
# KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||
# run: |
|
||
# echo "Importing Apple Developer Certificate..."
|
||
# echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
|
||
# security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
||
# security default-keychain -s build.keychain
|
||
# security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
||
# security set-keychain-settings -t 3600 -u build.keychain
|
||
# security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
|
||
# security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
|
||
# security find-identity -v -p codesigning build.keychain
|
||
# - name: Verify Certificate
|
||
# if: matrix.platform == 'macos-latest' || matrix.platform == 'macos-13'
|
||
# run: |
|
||
# echo "Verifying Apple Developer Certificate..."
|
||
# CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application")
|
||
# echo "Certificate Info: $CERT_INFO"
|
||
# CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
|
||
# echo "Certificate ID: $CERT_ID"
|
||
# echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV
|
||
# echo "Certificate imported."
|
||
|
||
# - name: Check DMG creation dependencies (macOS only)
|
||
# if: matrix.platform == 'macos-latest' || matrix.platform == 'macos-13'
|
||
# run: |
|
||
# echo "🔍 Checking DMG creation dependencies on ${{ matrix.platform }}..."
|
||
# echo "hdiutil version: $(hdiutil --version || echo 'NOT FOUND')"
|
||
# echo "create-dmg availability: $(which create-dmg || echo 'NOT FOUND')"
|
||
# echo "Available disk space: $(df -h /tmp | tail -1)"
|
||
# echo "macOS version: $(sw_vers -productVersion)"
|
||
# echo "Available tools:"
|
||
# ls -la /usr/bin/hd* || echo "No hd* tools found"
|
||
|
||
- name: Build Tauri app
|
||
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: ${{ env.CERT_ID }}
|
||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||
APPLE_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||
APPIMAGETOOL_SIGN_PASSPHRASE: ${{ secrets.APPIMAGETOOL_SIGN_PASSPHRASE }}
|
||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||
SIGN: ${{ (env.SM_API_KEY == '' && env.WINDOWS_CERTIFICATE != '') && '1' || '0' }}
|
||
CI: true
|
||
with:
|
||
projectPath: ./frontend
|
||
tauriScript: npx tauri
|
||
args: ${{ matrix.args }}
|
||
|
||
# Sign with DigiCert KeyLocker (post-build)
|
||
- name: Sign Windows binaries with DigiCert KeyLocker
|
||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' }}
|
||
shell: pwsh
|
||
run: |
|
||
Write-Host "🔏 Signing Windows binaries with DigiCert KeyLocker..."
|
||
|
||
# Find all EXE and MSI files
|
||
$exeFiles = Get-ChildItem -Path "./frontend/src-tauri/target" -Filter "*.exe" -Recurse -File
|
||
$msiFiles = Get-ChildItem -Path "./frontend/src-tauri/target" -Filter "*.msi" -Recurse -File
|
||
|
||
$filesToSign = $exeFiles + $msiFiles
|
||
|
||
if ($filesToSign.Count -eq 0) {
|
||
Write-Host "⚠️ No files found to sign"
|
||
exit 1
|
||
}
|
||
|
||
foreach ($file in $filesToSign) {
|
||
Write-Host "Signing: $($file.FullName)"
|
||
|
||
# Use smctl to sign with keypair alias
|
||
& smctl sign --keypair-alias "${{ secrets.SM_KEYPAIR_ALIAS }}" --input "$($file.FullName)"
|
||
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "❌ Failed to sign $($file.Name)"
|
||
exit 1
|
||
}
|
||
|
||
Write-Host "✅ Successfully signed: $($file.Name)"
|
||
}
|
||
|
||
Write-Host "✅ All files signed successfully with DigiCert KeyLocker"
|
||
|
||
- name: Rename artifacts
|
||
shell: bash
|
||
run: |
|
||
mkdir -p ./dist
|
||
cd ./frontend/src-tauri/target
|
||
|
||
# Find and rename artifacts based on platform
|
||
if [ "${{ matrix.platform }}" = "windows-latest" ]; then
|
||
find . -name "*.exe" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.exe" \;
|
||
find . -name "*.msi" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.msi" \;
|
||
# Disabled Mac builds
|
||
# elif [ "${{ matrix.platform }}" = "macos-latest" ] || [ "${{ matrix.platform }}" = "macos-13" ]; then
|
||
# find . -name "*.dmg" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.dmg" \;
|
||
# find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \;
|
||
else
|
||
find . -name "*.deb" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.deb" \;
|
||
find . -name "*.AppImage" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.AppImage" \;
|
||
fi
|
||
|
||
- name: Verify Windows Code Signature
|
||
if: matrix.platform == 'windows-latest'
|
||
shell: powershell
|
||
run: |
|
||
Write-Host "🔍 Verifying Windows code signatures..."
|
||
|
||
$exePath = "./dist/Stirling-PDF-${{ matrix.name }}.exe"
|
||
$msiPath = "./dist/Stirling-PDF-${{ matrix.name }}.msi"
|
||
|
||
$allSigned = $true
|
||
$usingKeyLocker = "${{ secrets.SM_API_KEY }}" -ne ""
|
||
$usingPfx = "${{ secrets.WINDOWS_CERTIFICATE }}" -ne ""
|
||
|
||
# Check EXE signature
|
||
if (Test-Path $exePath) {
|
||
$exeSig = Get-AuthenticodeSignature -FilePath $exePath
|
||
Write-Host "EXE Signature Status: $($exeSig.Status)"
|
||
Write-Host "EXE Signer: $($exeSig.SignerCertificate.Subject)"
|
||
Write-Host "EXE Timestamp: $($exeSig.TimeStamperCertificate.NotAfter)"
|
||
|
||
if ($exeSig.Status -ne "Valid") {
|
||
Write-Host "⚠️ EXE is not properly signed (Status: $($exeSig.Status))"
|
||
if ($usingKeyLocker -or $usingPfx) {
|
||
Write-Host "❌ Certificate was provided but signing failed"
|
||
$allSigned = $false
|
||
} else {
|
||
Write-Host "ℹ️ Building unsigned binary (no certificate provided)"
|
||
}
|
||
} else {
|
||
Write-Host "✅ EXE is properly signed"
|
||
}
|
||
}
|
||
|
||
# Check MSI signature
|
||
if (Test-Path $msiPath) {
|
||
$msiSig = Get-AuthenticodeSignature -FilePath $msiPath
|
||
Write-Host "MSI Signature Status: $($msiSig.Status)"
|
||
Write-Host "MSI Signer: $($msiSig.SignerCertificate.Subject)"
|
||
Write-Host "MSI Timestamp: $($msiSig.TimeStamperCertificate.NotAfter)"
|
||
|
||
if ($msiSig.Status -ne "Valid") {
|
||
Write-Host "⚠️ MSI is not properly signed (Status: $($msiSig.Status))"
|
||
if ($usingKeyLocker -or $usingPfx) {
|
||
Write-Host "❌ Certificate was provided but signing failed"
|
||
$allSigned = $false
|
||
} else {
|
||
Write-Host "ℹ️ Building unsigned binary (no certificate provided)"
|
||
}
|
||
} else {
|
||
Write-Host "✅ MSI is properly signed"
|
||
}
|
||
}
|
||
|
||
if (($usingKeyLocker -or $usingPfx) -and -not $allSigned) {
|
||
Write-Host "❌ Code signing verification failed"
|
||
exit 1
|
||
} else {
|
||
Write-Host "✅ Code signature verification completed"
|
||
}
|
||
|
||
- name: Upload artifacts
|
||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||
with:
|
||
name: Stirling-PDF-${{ matrix.name }}
|
||
path: ./dist/*
|
||
retention-days: 7
|
||
|
||
- name: Verify build artifacts
|
||
shell: bash
|
||
run: |
|
||
cd ./frontend/src-tauri/target
|
||
|
||
# Check for expected artifacts based on platform
|
||
if [ "${{ matrix.platform }}" = "windows-latest" ]; then
|
||
echo "Checking for Windows artifacts..."
|
||
find . -name "*.exe" -o -name "*.msi" | head -5
|
||
if [ $(find . -name "*.exe" | wc -l) -eq 0 ]; then
|
||
echo "❌ No Windows executable found"
|
||
exit 1
|
||
fi
|
||
# Disabled Mac builds
|
||
# elif [ "${{ matrix.platform }}" = "macos-latest" ] || [ "${{ matrix.platform }}" = "macos-13" ]; then
|
||
# echo "Checking for macOS artifacts..."
|
||
# find . -name "*.dmg" -o -name "*.app" | head -5
|
||
# if [ $(find . -name "*.dmg" -o -name "*.app" | wc -l) -eq 0 ]; then
|
||
# echo "❌ No macOS artifacts found"
|
||
# exit 1
|
||
# fi
|
||
else
|
||
echo "Checking for Linux artifacts..."
|
||
find . -name "*.deb" -o -name "*.AppImage" | head -5
|
||
if [ $(find . -name "*.deb" -o -name "*.AppImage" | wc -l) -eq 0 ]; then
|
||
echo "❌ No Linux artifacts found"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo "✅ Build artifacts found for ${{ matrix.name }}"
|
||
|
||
- name: Test artifact sizes
|
||
shell: bash
|
||
run: |
|
||
cd ./frontend/src-tauri/target
|
||
echo "Artifact sizes for ${{ matrix.name }}:"
|
||
find . -name "*.exe" -o -name "*.dmg" -o -name "*.deb" -o -name "*.AppImage" -o -name "*.msi" | while read file; do
|
||
if [ -f "$file" ]; then
|
||
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "unknown")
|
||
echo "$file: $size bytes"
|
||
# Check if file is suspiciously small (less than 1MB)
|
||
if [ "$size" != "unknown" ] && [ "$size" -lt 1048576 ]; then
|
||
echo "⚠️ Warning: $file is smaller than 1MB"
|
||
fi
|
||
fi
|
||
done
|
||
|
||
report:
|
||
needs: build
|
||
runs-on: ubuntu-latest
|
||
if: always()
|
||
steps:
|
||
- name: Report build results
|
||
run: |
|
||
if [ "${{ needs.build.result }}" = "success" ]; then
|
||
echo "✅ All Tauri builds completed successfully!"
|
||
echo "Artifacts are ready for distribution."
|
||
else
|
||
echo "❌ Some Tauri builds failed."
|
||
echo "Please check the logs and fix any issues."
|
||
exit 1
|
||
fi
|