mirror of
https://github.com/simstudioai/sim.git
synced 2026-10-24 23:06:59 +08:00
* fix(integrations): repair corrupt icons, backfill missing block metas, restore scroll on back-nav - Restore 7 brand icons (Google, Outlook, MongoDB, Postgres, OpenRouter, Groq, Cerebras) whose SVG path data was corrupted by a past bulk reformat, flooding the integrations page console with <path> parse errors; add a check:icon-paths CI gate that validates every icon d attribute (operand counts + arc flags). - Backfill BlockMeta (tags/url/templates/skills) for postgresql, mysql, ssh, sftp, smtp — previously catalog integrations with empty detail pages; add an integration meta-coverage CI check so every catalog block must have a meta. - Add scroll-position restoration for the integrations index/detail inner scroll containers so browser Back returns to where you were. - Remove the error digest pill from the shared workspace ErrorShell (kept in logs, dropped from UI). * fix(integrations): make scroll restoration robust — value-based echo detection + Back/Forward-only gate Addresses review: replace the racy programmatic-scroll flag with value comparison (a restore's echo equals lastApplied and is ignored, so a stuck flag can never drop the first user scroll or overwrite the saved target), and gate restoration on popstate history traversals so fresh push navigations open at the top instead of jumping mid-list. TSDoc-only comments. * fix(ci): attribute icon-path errors for export-const icons too Greptile review: iconNameAt only matched 'export function', so a malformed path inside an 'export const XxxIcon = (...)' arrow-function icon would be misattributed to the preceding function-declared icon. Match both forms (mirrors check-bare-icons indexIconBodies).
190 lines
6.8 KiB
YAML
190 lines
6.8 KiB
YAML
name: Test and Build
|
|
|
|
on:
|
|
workflow_call:
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
test-build:
|
|
name: Test and Build
|
|
runs-on: blacksmith-8vcpu-ubuntu-2404
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
|
with:
|
|
bun-version: 1.3.13
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
|
with:
|
|
node-version: latest
|
|
|
|
- name: Mount Bun cache (Sticky Disk)
|
|
uses: useblacksmith/stickydisk@4c034ba57b706cf0e3b4b0ce098c2a3b1071580c # v1
|
|
with:
|
|
key: ${{ github.repository }}-bun-cache
|
|
path: ~/.bun/install/cache
|
|
|
|
- name: Mount node_modules (Sticky Disk)
|
|
uses: useblacksmith/stickydisk@4c034ba57b706cf0e3b4b0ce098c2a3b1071580c # v1
|
|
with:
|
|
key: ${{ github.repository }}-node-modules
|
|
path: ./node_modules
|
|
|
|
- name: Mount Turbo cache (Sticky Disk)
|
|
uses: useblacksmith/stickydisk@4c034ba57b706cf0e3b4b0ce098c2a3b1071580c # v1
|
|
with:
|
|
key: ${{ github.repository }}-turbo-cache
|
|
path: ./.turbo
|
|
|
|
- name: Restore Next.js build cache
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
|
with:
|
|
path: ./apps/sim/.next/cache
|
|
key: ${{ runner.os }}-nextjs-${{ hashFiles('bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-nextjs-
|
|
|
|
- name: Install dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
# Surfaces known CVEs in the dependency tree. Non-blocking until the
|
|
# existing advisory backlog is triaged, then flip to a required gate by
|
|
# removing continue-on-error.
|
|
- name: Security audit
|
|
run: bun audit
|
|
continue-on-error: true
|
|
|
|
- name: Validate env flags
|
|
run: |
|
|
FILE="apps/sim/lib/core/config/env-flags.ts"
|
|
ERRORS=""
|
|
|
|
echo "Checking for hardcoded boolean env flags..."
|
|
|
|
# Use perl for multiline matching to catch both:
|
|
# export const isHosted = true
|
|
# export const isHosted =
|
|
# true
|
|
HARDCODED=$(perl -0777 -ne 'while (/export const (is[A-Za-z]+)\s*=\s*\n?\s*(true|false)\b/g) { print " $1 = $2\n" }' "$FILE")
|
|
|
|
if [ -n "$HARDCODED" ]; then
|
|
ERRORS="${ERRORS}\n❌ Env flags must not be hardcoded to boolean literals!\n\nFound hardcoded flags:\n${HARDCODED}\n\nEnv flags should derive their values from environment variables.\n"
|
|
fi
|
|
|
|
echo "Checking env flag naming conventions..."
|
|
|
|
# Check that all export const (except functions) start with 'is'
|
|
# This finds exports like "export const someFlag" that don't start with "is" or "get"
|
|
BAD_NAMES=$(grep -E "^export const [a-z]" "$FILE" | grep -vE "^export const (is|get)" | sed 's/export const \([a-zA-Z]*\).*/ \1/')
|
|
|
|
if [ -n "$BAD_NAMES" ]; then
|
|
ERRORS="${ERRORS}\n❌ Env flags must use 'is' prefix for boolean flags!\n\nFound incorrectly named flags:\n${BAD_NAMES}\n\nExample: 'hostedMode' should be 'isHostedMode'\n"
|
|
fi
|
|
|
|
if [ -n "$ERRORS" ]; then
|
|
echo ""
|
|
echo -e "$ERRORS"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ All env flags are properly configured"
|
|
|
|
- name: Check block registry invariants
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
BASE_REF="origin/${{ github.base_ref }}"
|
|
git fetch --depth=1 origin "${{ github.base_ref }}" 2>/dev/null || true
|
|
else
|
|
BASE_REF="HEAD~1"
|
|
fi
|
|
bun run apps/sim/scripts/check-block-registry.ts "$BASE_REF"
|
|
|
|
- name: Lint code
|
|
run: bun run lint:check
|
|
|
|
- name: Enforce monorepo boundaries
|
|
run: bun run check:boundaries
|
|
|
|
- name: API contract boundary audit
|
|
run: bun run check:api-validation:strict
|
|
|
|
- name: Zustand v5 selector audit
|
|
run: bun run check:zustand-v5
|
|
|
|
- name: React Query pattern audit
|
|
run: bun run check:react-query
|
|
|
|
- name: Client boundary import audit
|
|
run: bun run check:client-boundary
|
|
|
|
- name: Bare-icon theme-safety audit
|
|
run: bun run check:bare-icons
|
|
|
|
- name: Icon SVG path validity audit
|
|
run: bun run check:icon-paths
|
|
|
|
- name: Verify realtime prune graph
|
|
run: bun run check:realtime-prune
|
|
|
|
- name: Migration safety (zero-downtime) audit
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
BASE_REF="origin/${{ github.base_ref }}"
|
|
git fetch --depth=1 origin "${{ github.base_ref }}" 2>/dev/null || true
|
|
else
|
|
BASE_REF="HEAD~1"
|
|
fi
|
|
bun run check:migrations "$BASE_REF"
|
|
|
|
- name: Type-check realtime server
|
|
run: bunx turbo run type-check --filter=@sim/realtime
|
|
|
|
- name: Run tests with coverage
|
|
env:
|
|
NODE_OPTIONS: '--no-warnings --max-old-space-size=8192'
|
|
NEXT_PUBLIC_APP_URL: 'https://www.sim.ai'
|
|
DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/simstudio'
|
|
ENCRYPTION_KEY: '7cf672e460e430c1fba707575c2b0e2ad5a99dddf9b7b7e3b5646e630861db1c' # dummy key for CI only
|
|
TURBO_CACHE_DIR: .turbo
|
|
run: bun run test
|
|
|
|
- name: Check schema and migrations are in sync
|
|
working-directory: packages/db
|
|
run: |
|
|
bunx drizzle-kit generate --config=./drizzle.config.ts
|
|
if [ -n "$(git status --porcelain ./migrations)" ]; then
|
|
echo "❌ Schema and migrations are out of sync!"
|
|
echo "Run 'cd packages/db && bunx drizzle-kit generate' and commit the new migrations."
|
|
git status --porcelain ./migrations
|
|
git diff ./migrations
|
|
exit 1
|
|
fi
|
|
echo "✅ Schema and migrations are in sync"
|
|
|
|
- name: Build application
|
|
env:
|
|
NODE_OPTIONS: '--no-warnings --max-old-space-size=8192'
|
|
NEXT_PUBLIC_APP_URL: 'https://www.sim.ai'
|
|
DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/simstudio'
|
|
STRIPE_SECRET_KEY: 'dummy_key_for_ci_only'
|
|
STRIPE_WEBHOOK_SECRET: 'dummy_secret_for_ci_only'
|
|
RESEND_API_KEY: 'dummy_key_for_ci_only'
|
|
AWS_REGION: 'us-west-2'
|
|
ENCRYPTION_KEY: '7cf672e460e430c1fba707575c2b0e2ad5a99dddf9b7b7e3b5646e630861db1c' # dummy key for CI only
|
|
TURBO_CACHE_DIR: .turbo
|
|
run: bunx turbo run build --filter=sim
|
|
|
|
- name: Upload coverage to Codecov
|
|
uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5
|
|
with:
|
|
directory: ./apps/sim/coverage
|
|
fail_ci_if_error: false
|
|
verbose: true |