Add @object-ui/app-shell and @object-ui/providers for third-party integration #1533
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Bundle Analysis | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - 'packages/**' | |
| - 'apps/console/**' | |
| - 'pnpm-lock.yaml' | |
| pull_request: | |
| branches: [main, develop] | |
| paths: | |
| - 'packages/**' | |
| - 'apps/console/**' | |
| - 'pnpm-lock.yaml' | |
| concurrency: | |
| group: bundle-analysis-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| bundle-analysis: | |
| name: Bundle Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Verify pnpm version | |
| run: pnpm --version | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20.x' | |
| cache: 'pnpm' | |
| - name: Turbo Cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: node_modules/.cache/turbo | |
| key: turbo-${{ runner.os }}-${{ github.sha }} | |
| restore-keys: | | |
| turbo-${{ runner.os }}- | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build packages | |
| run: pnpm turbo run build --filter='./packages/*' | |
| - name: Build Console | |
| run: pnpm --filter @object-ui/console build | |
| - name: Check console performance budget | |
| id: budget | |
| run: | | |
| # Performance budget: main entry must be < 350 KB gzip | |
| # This is a realistic threshold for a full-featured enterprise app | |
| # with React, routing, UI components, and core business logic. | |
| MAX_ENTRY_GZIP_KB=350 | |
| DIST_DIR="apps/console/dist/assets" | |
| if [ ! -d "$DIST_DIR" ]; then | |
| echo "❌ Build output not found at $DIST_DIR" | |
| exit 1 | |
| fi | |
| # Find the main entry chunk (index-*.js) | |
| ENTRY_FILE=$(find "$DIST_DIR" -name 'index-*.js' -not -name '*.gz' -not -name '*.br' | head -1) | |
| if [ -z "$ENTRY_FILE" ]; then | |
| echo "⚠️ Could not find main entry chunk, checking all JS files..." | |
| ENTRY_FILE=$(find "$DIST_DIR" -name '*.js' -not -name '*.gz' -not -name '*.br' | sort | head -1) | |
| fi | |
| if [ -z "$ENTRY_FILE" ]; then | |
| echo "❌ No JS files found in $DIST_DIR" | |
| exit 1 | |
| fi | |
| echo "📦 Main entry file: $(basename $ENTRY_FILE)" | |
| # Calculate gzip size | |
| GZIP_BYTES=$(gzip -c "$ENTRY_FILE" | wc -c) | |
| GZIP_KB=$(awk "BEGIN {printf \"%.1f\", $GZIP_BYTES / 1024}") | |
| echo " Raw size: $(awk "BEGIN {printf \"%.1f\", $(wc -c < "$ENTRY_FILE") / 1024}") KB" | |
| echo " Gzip size: ${GZIP_KB} KB" | |
| echo " Budget: ${MAX_ENTRY_GZIP_KB} KB" | |
| echo "gzip_kb=$GZIP_KB" >> "$GITHUB_OUTPUT" | |
| echo "budget_kb=$MAX_ENTRY_GZIP_KB" >> "$GITHUB_OUTPUT" | |
| echo "entry_file=$(basename $ENTRY_FILE)" >> "$GITHUB_OUTPUT" | |
| # Check budget | |
| OVER=$(awk "BEGIN {print ($GZIP_KB > $MAX_ENTRY_GZIP_KB) ? 1 : 0}") | |
| if [ "$OVER" -eq 1 ]; then | |
| echo "" | |
| echo "❌ BUDGET EXCEEDED: Main entry is ${GZIP_KB} KB gzip (limit: ${MAX_ENTRY_GZIP_KB} KB)" | |
| echo "budget_status=fail" >> "$GITHUB_OUTPUT" | |
| exit 1 | |
| else | |
| echo "" | |
| echo "✅ Budget OK: Main entry is ${GZIP_KB} KB gzip (limit: ${MAX_ENTRY_GZIP_KB} KB)" | |
| echo "budget_status=pass" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate package size report | |
| id: size-report | |
| if: always() | |
| run: | | |
| echo "## 📦 Bundle Size Report" > size-report.md | |
| echo "" >> size-report.md | |
| echo "| Package | Size | Gzipped |" >> size-report.md | |
| echo "|---------|------|---------|" >> size-report.md | |
| for pkg in packages/*/dist; do | |
| if [ -d "$pkg" ]; then | |
| pkg_name=$(basename $(dirname $pkg)) | |
| # Calculate sizes for main bundle files | |
| for file in "$pkg"/*.js; do | |
| if [ -f "$file" ] && [ ! -f "${file}.map" ]; then | |
| # Use portable method to get file size | |
| size=$(wc -c < "$file") | |
| size_kb=$(awk "BEGIN {printf \"%.2f\", $size/1024}") | |
| # Estimate gzipped size | |
| gzip_size=$(gzip -c "$file" | wc -c) | |
| gzip_kb=$(awk "BEGIN {printf \"%.2f\", $gzip_size/1024}") | |
| echo "| $pkg_name ($(basename $file)) | ${size_kb}KB | ${gzip_kb}KB |" >> size-report.md | |
| fi | |
| done | |
| fi | |
| done | |
| echo "" >> size-report.md | |
| echo "### Size Limits" >> size-report.md | |
| echo "- ✅ Core packages should be < 50KB gzipped" >> size-report.md | |
| echo "- ✅ Component packages should be < 100KB gzipped" >> size-report.md | |
| echo "- ⚠️ Plugin packages should be < 150KB gzipped" >> size-report.md | |
| - name: Comment PR with results | |
| if: github.event_name == 'pull_request' && always() | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const status = '${{ steps.budget.outputs.budget_status }}'; | |
| const gzipKb = '${{ steps.budget.outputs.gzip_kb }}'; | |
| const budgetKb = '${{ steps.budget.outputs.budget_kb }}'; | |
| const entryFile = '${{ steps.budget.outputs.entry_file }}'; | |
| const icon = status === 'pass' ? '✅' : '❌'; | |
| let body = `## ${icon} Console Performance Budget | |
| | Metric | Value | Budget | | |
| |--------|-------|--------| | |
| | Main entry (gzip) | **${gzipKb} KB** | ${budgetKb} KB | | |
| | Entry file | \`${entryFile}\` | — | | |
| | Status | **${status === 'pass' ? 'PASS' : 'FAIL'}** | — | | |
| `; | |
| // Append package size report if available | |
| try { | |
| const sizeReport = fs.readFileSync('size-report.md', 'utf8'); | |
| body += '\n---\n\n' + sizeReport; | |
| } catch (e) { | |
| // Size report not generated | |
| } | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body | |
| }); |