mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
241 lines
11 KiB
YAML
241 lines
11 KiB
YAML
name: "Artcraft MacOS Publish"
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- release
|
|
- artcraft-release
|
|
- artcraft-macos # Additional branch for MacOS testing
|
|
|
|
# This workflow creates Universal macOS builds with signing certificate support.
|
|
# On each push to the release branches it will create or update a GitHub release, build your app, and upload the artifacts to the release.
|
|
|
|
jobs:
|
|
publish-artcraft:
|
|
permissions:
|
|
contents: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# Universal macOS builds (arm64 and x86_64)
|
|
- platform: 'macos-latest-xlarge'
|
|
args: '--target universal-apple-darwin'
|
|
# Uncomment below for additional platforms
|
|
# - platform: 'ubuntu-22.04'
|
|
# args: ''
|
|
# - platform: 'windows-latest'
|
|
# args: ''
|
|
|
|
runs-on: ${{ matrix.platform }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: setup node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: lts/*
|
|
|
|
- name: install Rust stable
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.platform == 'macos-latest-xlarge' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
|
|
|
- name: install dependencies (ubuntu only)
|
|
if: matrix.platform == 'ubuntu-22.04'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
|
|
|
- name: replace tauri config with mac-specific version
|
|
run: |
|
|
pushd ${{ github.workspace }}/crates/desktop/artcraft
|
|
# Use the mac-specific tauri conf for the build
|
|
# TODO(bt): Replace this with the platform-specific naming conventions
|
|
cp tauri-mac.conf.json tauri.conf.json
|
|
popd
|
|
|
|
- name: install frontend dependencies
|
|
run: |
|
|
# Navigate to the frontend directory to install dependencies
|
|
cd ./frontend
|
|
|
|
npm cache clean --force
|
|
|
|
echo "Installing all workspace dependencies..."
|
|
npm ci
|
|
|
|
echo "=== Version Information ==="
|
|
echo "Node version:"
|
|
node --version
|
|
echo "NPM version:"
|
|
npm --version
|
|
|
|
# Remove mismatched @nx packages and reinstall with correct versions
|
|
npm install --save-dev @nx/remix@21.1.1 @nx/js@21.1.1 @nx/react@21.1.1 @nx/vite@21.1.1 @nx/eslint@21.1.1
|
|
|
|
echo "=== Nx versions after adjustment ==="
|
|
npm list --depth=0 | grep nx
|
|
|
|
- name: import Apple Developer Certificate
|
|
if: matrix.platform == 'macos-latest-xlarge'
|
|
env:
|
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
run: |
|
|
echo "Starting certificate import process..."
|
|
|
|
# Create certificate file
|
|
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
|
|
|
|
# Debug: Check if certificate file exists and has content
|
|
echo "Certificate file info:"
|
|
ls -la certificate.p12
|
|
file certificate.p12
|
|
|
|
# Debug: Check certificate contents without password (just structure)
|
|
echo "Certificate structure (may show error if password protected):"
|
|
openssl pkcs12 -info -in certificate.p12 -passin pass:$APPLE_CERTIFICATE_PASSWORD -noout || echo "Could not read certificate structure"
|
|
|
|
# Debug: Try to list what's in the p12 file
|
|
echo "Attempting to list certificate contents:"
|
|
security cms -D -i certificate.p12 || echo "Not a CMS file, trying PKCS12..."
|
|
openssl pkcs12 -in certificate.p12 -passin pass:$APPLE_CERTIFICATE_PASSWORD -info -nodes 2>&1 | head -20 || echo "Failed to read PKCS12 contents"
|
|
|
|
# Debug: Extract certificate details to verify type and expiration
|
|
echo "Extracting certificate details..."
|
|
# Extract just the certificate portion and examine it
|
|
openssl pkcs12 -in certificate.p12 -passin pass:$APPLE_CERTIFICATE_PASSWORD -nokeys 2>/dev/null | openssl x509 -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After)" || echo "Failed to parse certificate details"
|
|
|
|
# Also try to see what type of certificate this is
|
|
echo "Certificate type check:"
|
|
openssl pkcs12 -in certificate.p12 -passin pass:$APPLE_CERTIFICATE_PASSWORD -nokeys 2>/dev/null | openssl x509 -text -noout | grep -E "(CN=|OU=)" || echo "Could not determine certificate type"
|
|
|
|
# Debug: Check if private key exists
|
|
echo "Checking for private key..."
|
|
openssl pkcs12 -in certificate.p12 -passin pass:$APPLE_CERTIFICATE_PASSWORD -nocerts -nodes 2>&1 | grep -E "(PRIVATE KEY|RSA KEY)" | head -5 || echo "No private key found"
|
|
|
|
# Create temporary keychain
|
|
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
|
|
|
|
# Import certificate - ensure both certificate and private key are imported
|
|
echo "Importing certificate into keychain..."
|
|
# Import the p12 directly - this is the most reliable method
|
|
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
|
|
|
# Alternative: Try with additional flags if the first import didn't create an identity
|
|
echo "Verifying import..."
|
|
if ! security find-identity -v build.keychain | grep -q "1 valid identities found"; then
|
|
echo "First import didn't create identity, trying with -A flag..."
|
|
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -A
|
|
fi
|
|
|
|
# Set trust settings for the certificate
|
|
echo "Setting trust settings..."
|
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
|
|
|
|
# Unlock the keychain again to ensure it's accessible
|
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
|
|
|
# Add the keychain to the search list
|
|
security list-keychains -d user -s build.keychain $(security list-keychains -d user | sed 's/^[[:space:]]*"//;s/"$//')
|
|
|
|
# List all certificates to debug
|
|
echo "Listing all keychains:"
|
|
security list-keychains
|
|
|
|
echo "Listing all certificates in build keychain:"
|
|
security find-certificate -a -p build.keychain || echo "No certificates found"
|
|
|
|
echo "Detailed certificate info:"
|
|
security find-certificate -c "Learning Machines" build.keychain || echo "Certificate 'Learning Machines' not found"
|
|
|
|
# Check certificate trust settings
|
|
echo "Checking certificate trust settings:"
|
|
security dump-trust-settings || echo "No custom trust settings"
|
|
|
|
# Try to find codesigning identities
|
|
echo "Finding all identities in keychain:"
|
|
security find-identity -v build.keychain || echo "No identities found"
|
|
|
|
echo "Finding codesigning identities:"
|
|
security find-identity -v -p codesigning build.keychain || echo "No codesigning identities found"
|
|
|
|
# Additional debug: Check if this is a valid Developer ID cert
|
|
echo "Checking for Developer ID certificates:"
|
|
security find-certificate -a build.keychain | grep -A 5 -B 5 "Developer ID" || echo "No Developer ID certificates found"
|
|
|
|
- name: verify certificate
|
|
if: matrix.platform == 'macos-latest-xlarge'
|
|
run: |
|
|
echo "=== Certificate Verification ==="
|
|
|
|
echo "1. Checking codesigning identities:"
|
|
security find-identity -v -p codesigning build.keychain || echo "No codesigning identities found"
|
|
|
|
echo -e "\n2. Checking all identities:"
|
|
security find-identity -v build.keychain || echo "No identities found"
|
|
|
|
echo -e "\n3. Checking certificates in keychain:"
|
|
security find-certificate -c "Learning Machines" build.keychain -p | openssl x509 -text -noout | grep -E "(Subject:|CN=)" || echo "Could not parse certificate"
|
|
|
|
# Set the correct signing identity
|
|
echo "APPLE_SIGNING_IDENTITY=Developer ID Application: Learning Machines LLC (DJ6XS33FX8)" >> $GITHUB_ENV
|
|
echo "Proceeding with identity: Developer ID Application: Learning Machines LLC (DJ6XS33FX8)"
|
|
|
|
# Also set the team ID
|
|
echo "APPLE_DEVELOPMENT_TEAM=DJ6XS33FX8" >> $GITHUB_ENV
|
|
|
|
- name: Pre-build frontend to avoid Tauri build issues
|
|
run: |
|
|
# Build the frontend app from the correct directory
|
|
cd ./frontend
|
|
|
|
# Increase Node.js memory limit for the build
|
|
export NODE_OPTIONS="--max-old-space-size=8192"
|
|
|
|
# Use npx to ensure we use the local nx version
|
|
echo "Building with npx nx..."
|
|
npx nx run editor3d:build
|
|
|
|
echo "Checking build output..."
|
|
ls -la apps/editor3d/dist/ | head -10
|
|
|
|
# Update Tauri config to skip the build (since we already built)
|
|
cd ${{ github.workspace }}/crates/desktop/artcraft
|
|
cp tauri.conf.json tauri.conf.json.bak
|
|
# Set beforeBuildCommand to empty or a no-op command
|
|
if command -v jq &> /dev/null; then
|
|
jq '.build.beforeBuildCommand = ""' tauri.conf.json > tauri.conf.json.tmp
|
|
mv tauri.conf.json.tmp tauri.conf.json
|
|
else
|
|
node -e "const fs = require('fs'); const config = JSON.parse(fs.readFileSync('tauri.conf.json', 'utf8')); config.build.beforeBuildCommand = ''; fs.writeFileSync('tauri.conf.json', JSON.stringify(config, null, 2));"
|
|
fi
|
|
|
|
|
|
- name: build and publish
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
APPLE_SIGNING_IDENTITY: ${{ env.APPLE_SIGNING_IDENTITY }}
|
|
APPLE_DEVELOPMENT_TEAM: ${{ env.APPLE_DEVELOPMENT_TEAM }}
|
|
# Use the SQLx query cache for SQLite
|
|
SQLX_OFFLINE: true
|
|
with:
|
|
projectPath: ./crates/desktop/artcraft
|
|
tagName: artcraft-v__VERSION__ # the action automatically replaces __VERSION__ with the app version.
|
|
releaseName: "Artcraft v__VERSION__"
|
|
releaseBody: "See the assets to download this version and install."
|
|
releaseDraft: true
|
|
prerelease: false
|
|
args: ${{ matrix.args }}
|