Skip to content

feat: add settings schema validation #14

feat: add settings schema validation

feat: add settings schema validation #14

name: Cross-Platform Build
on:
workflow_dispatch:
inputs:
reason:
description: 'Reason for running this build'
required: false
default: 'Manual verification'
issue_comment:
types: [created]
milestone:
types: [closed]
schedule:
- cron: '0 4 * * 1' # Every Monday 4:00 UTC
jobs:
# Post "building..." comment immediately
notify-start:
if: >-
github.event_name != 'issue_comment' ||
(github.event.comment.body == '/build' &&
github.event.issue.state == 'open')
runs-on: ubuntu-latest
permissions:
issues: write
outputs:
comment-id: ${{ steps.comment.outputs.comment-id }}
steps:
- name: React to comment
if: github.event_name == 'issue_comment'
uses: actions/github-script@v7
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'rocket'
});
- name: Post progress comment
id: comment
if: github.event_name == 'issue_comment'
uses: actions/github-script@v7
with:
script: |
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const { data } = await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
body: `⏳ **Cross-Platform Build started...**\n\n| Platform | Status |\n|----------|--------|\n| macOS | 🔄 building... |\n| Windows | 🔄 building... |\n\n[View live logs](${runUrl})`,
});
core.setOutput('comment-id', data.id);
build:
needs: notify-start
strategy:
fail-fast: false
matrix:
include:
- platform: macos-latest
name: macOS
- platform: windows-latest
name: Windows
name: ${{ matrix.name }} Build
runs-on: ${{ matrix.platform }}
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: dtolnay/rust-toolchain@stable
- name: Add macOS universal target
if: matrix.platform == 'macos-latest'
run: rustup target add x86_64-apple-darwin
- uses: Swatinem/rust-cache@v2
with:
workspaces: desktop/src-tauri -> target
- name: Setup Emscripten
uses: mymindstorm/setup-emsdk@v14
with:
version: 5.0.0
- name: Setup ccache (non-Windows)
if: matrix.platform != 'windows-latest'
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ matrix.platform }}-cross
max-size: 1G
- name: Install dependencies
run: pnpm install
- name: Copy esbuild.wasm to desktop public
shell: bash
run: cp $(find node_modules/.pnpm -name 'esbuild.wasm' -path '*/esbuild-wasm/*' | head -1) desktop/public/esbuild.wasm
# Type-check & test SDK first (editor depends on it)
- name: Type-check SDK
run: pnpm --filter ./sdk exec tsc --noEmit
- name: Run SDK tests
run: pnpm --filter ./sdk exec vitest run
- name: Build SDK
run: pnpm --filter ./sdk build
# Now editor (depends on SDK build output)
- name: Type-check Editor
run: pnpm --filter ./editor exec tsc --noEmit
- name: Run Editor tests
run: pnpm --filter ./editor exec vitest run
- name: Build Editor
run: pnpm --filter ./editor build
# Full engine build (WASM + SDK)
- name: Build engine (WASM + SDK)
run: node build-tools/cli.js build -t all
# Toolchain packaging
- name: Package toolchain
run: node build-tools/cli.js toolchain
# Rust compilation check (Tauri app)
- name: Tauri build check
shell: bash
run: cd desktop/src-tauri && cargo check
# Artifact size report
- name: Collect artifact sizes
id: sizes
shell: bash
run: |
report=""
if [ -f sdk/dist/index.bundled.js ]; then
size=$(du -sh sdk/dist/index.bundled.js | cut -f1)
report+="| SDK bundle | $size |"$'\n'
fi
for f in desktop/public/*.wasm; do
if [ -f "$f" ]; then
name=$(basename "$f")
size=$(du -sh "$f" | cut -f1)
report+="| WASM ($name) | $size |"$'\n'
fi
done
if [ -d desktop/src-tauri/toolchain ]; then
total=$(du -sh desktop/src-tauri/toolchain | cut -f1)
report+="| Toolchain (total) | $total |"$'\n'
if [ -d desktop/src-tauri/toolchain/engine-src ]; then
size=$(du -sh desktop/src-tauri/toolchain/engine-src | cut -f1)
report+="| - engine-src | $size |"$'\n'
fi
if [ -d desktop/src-tauri/toolchain/cmake ]; then
size=$(du -sh desktop/src-tauri/toolchain/cmake | cut -f1)
report+="| - cmake | $size |"$'\n'
fi
fi
if [ -f desktop/public/esbuild.wasm ]; then
size=$(du -sh desktop/public/esbuild.wasm | cut -f1)
report+="| esbuild.wasm | $size |"$'\n'
fi
echo "## Artifact Size Report (${{ matrix.name }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Artifact | Size |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "$report" >> $GITHUB_STEP_SUMMARY
# Save for final report
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "report<<$EOF" >> $GITHUB_OUTPUT
echo "$report" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
# Update the progress comment with final results
report:
needs: [notify-start, build]
if: always() && github.event_name == 'issue_comment' && needs.notify-start.outputs.comment-id
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Update progress comment with results
uses: actions/github-script@v7
with:
script: |
const jobs = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId,
});
const buildJobs = jobs.data.jobs.filter(j =>
j.name.includes('Build') && !j.name.includes('notify') && !j.name.includes('report')
);
const allPassed = buildJobs.every(j => j.conclusion === 'success');
const header = allPassed
? '✅ **Cross-Platform Build passed!**'
: '❌ **Cross-Platform Build failed**';
const lines = buildJobs.map(j => {
const icon = j.conclusion === 'success' ? '✅' : '❌';
const dur = j.completed_at && j.started_at
? Math.round((new Date(j.completed_at) - new Date(j.started_at)) / 1000)
: 0;
const mins = Math.floor(dur / 60);
const secs = dur % 60;
const time = mins > 0 ? `${mins}m${secs}s` : `${secs}s`;
return `| ${j.name} | ${icon} ${j.conclusion || 'unknown'} | ${time} |`;
});
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const body = [
header,
'',
'| Platform | Status | Duration |',
'|----------|--------|----------|',
...lines,
'',
`[View full run](${runUrl})`,
].join('\n');
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ needs.notify-start.outputs.comment-id }},
body,
});