From a460457f234b6bc09b56445d45d5e9eec4f09bd5 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 18 Mar 2026 15:30:49 -0400 Subject: [PATCH 1/4] fix for tests unable to resolve @cardstack/catalog when skipping catalog --- .github/workflows/ci-host.yaml | 5 ----- .../scripts/start-services-for-host-tests.sh | 12 +++++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-host.yaml b/.github/workflows/ci-host.yaml index c05109acd5..487908e24b 100644 --- a/.github/workflows/ci-host.yaml +++ b/.github/workflows/ci-host.yaml @@ -28,8 +28,6 @@ jobs: test-web-assets: name: Build test web assets uses: ./.github/workflows/test-web-assets.yaml - with: - skip_catalog: true concurrency: group: ci-host-test-web-assets-${{ github.head_ref || github.run_id }} cancel-in-progress: true @@ -80,8 +78,6 @@ jobs: - name: Start realm servers run: pnpm start:services-for-host-tests | tee -a /tmp/server.log & working-directory: packages/realm-server - env: - SKIP_CATALOG: true - name: create realm users run: pnpm register-realm-users working-directory: packages/matrix @@ -107,7 +103,6 @@ jobs: fi exit $exit_code env: - SKIP_CATALOG: true PERCY_GZIP: true PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_HOST }} PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }} diff --git a/packages/realm-server/scripts/start-services-for-host-tests.sh b/packages/realm-server/scripts/start-services-for-host-tests.sh index 6b734859b7..2610b19377 100755 --- a/packages/realm-server/scripts/start-services-for-host-tests.sh +++ b/packages/realm-server/scripts/start-services-for-host-tests.sh @@ -34,7 +34,10 @@ for item in $KEEP_FOLDERS; do fi done # Explicitly keep some files needed for the tests -KEEP_FILES="cloudflare-image.gts index.json Spec/f869024a-cdec-4a73-afca-d8d32f258ead.json" +# skill-set.gts, skill-plus.gts, skill-reference.gts are needed because the +# skills realm's skill instances adopt from @cardstack/catalog/skill-set and +# @cardstack/catalog/skill-plus which are defined in these files. +KEEP_FILES="cloudflare-image.gts index.json Spec/f869024a-cdec-4a73-afca-d8d32f258ead.json skill-set.gts skill-plus.gts skill-reference.gts" for item in $KEEP_FILES; do if [ -f "$CATALOG_SRC_PATH/$item" ]; then cp -a "$CATALOG_SRC_PATH/$item" "$CATALOG_TEMP_PATH/$item" @@ -48,14 +51,17 @@ export CATALOG_REALM_PATH="$CATALOG_TEMP_PATH" # Make host-test startup logs focus on indexing progress rather than per-request noise. HOST_TEST_LOG_LEVELS="${HOST_TEST_LOG_LEVELS:-*=info,realm:requests=warn,realm-index-updater=debug,index-runner=debug,index-perf=debug,index-writer=debug,worker=debug,worker-manager=debug}" -SKIP_CATALOG="${SKIP_CATALOG:-}" +# Always start the catalog with the trimmed content above. The skills realm +# depends on @cardstack/catalog/skill-set and @cardstack/catalog/skill-plus +# modules, so the catalog realm must be running for skills to index correctly. +# The trimmed catalog is small enough to index quickly. +# # There is a race condition starting up the servers that setting up the # submission realm triggers which triggers the start-development.sh script to # SIGTERM. currently we don't need the submission realm for host tests to # skipping that. but this issue needs to be fixed. WAIT_ON_TIMEOUT=900000 \ SKIP_EXPERIMENTS=true \ - SKIP_CATALOG="$SKIP_CATALOG" \ SKIP_BOXEL_HOMEPAGE=true \ SKIP_SUBMISSION=true \ CATALOG_REALM_PATH="$CATALOG_TEMP_PATH" \ From 8a022495ca709a03ffbd076e360e806a4efec2d4 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 18 Mar 2026 15:34:12 -0400 Subject: [PATCH 2/4] add theme dir to catalog skeleton --- .../realm-server/scripts/start-services-for-host-tests.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/realm-server/scripts/start-services-for-host-tests.sh b/packages/realm-server/scripts/start-services-for-host-tests.sh index 2610b19377..47750b8ff5 100755 --- a/packages/realm-server/scripts/start-services-for-host-tests.sh +++ b/packages/realm-server/scripts/start-services-for-host-tests.sh @@ -37,7 +37,14 @@ done # skill-set.gts, skill-plus.gts, skill-reference.gts are needed because the # skills realm's skill instances adopt from @cardstack/catalog/skill-set and # @cardstack/catalog/skill-plus which are defined in these files. +# The Theme directory is needed because skills link to @cardstack/catalog/Theme/cardstack. KEEP_FILES="cloudflare-image.gts index.json Spec/f869024a-cdec-4a73-afca-d8d32f258ead.json skill-set.gts skill-plus.gts skill-reference.gts" +KEEP_SKILL_FOLDERS="Theme" +for item in $KEEP_SKILL_FOLDERS; do + if [ -d "$CATALOG_SRC_PATH/$item" ]; then + cp -a "$CATALOG_SRC_PATH/$item" "$CATALOG_TEMP_PATH/" + fi +done for item in $KEEP_FILES; do if [ -f "$CATALOG_SRC_PATH/$item" ]; then cp -a "$CATALOG_SRC_PATH/$item" "$CATALOG_TEMP_PATH/$item" From 544f58e9ec4178f16f746fbdf36253f593b0b401 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 18 Mar 2026 15:41:48 -0400 Subject: [PATCH 3/4] better approach including matrix tests --- .github/workflows/ci-host.yaml | 2 ++ .../matrix/helpers/isolated-realm-server.ts | 36 ++++++++++++++++++- .../realm-server/scripts/start-development.sh | 20 +++++++++-- .../scripts/start-services-for-host-tests.sh | 7 ++-- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-host.yaml b/.github/workflows/ci-host.yaml index 487908e24b..0415acd406 100644 --- a/.github/workflows/ci-host.yaml +++ b/.github/workflows/ci-host.yaml @@ -78,6 +78,8 @@ jobs: - name: Start realm servers run: pnpm start:services-for-host-tests | tee -a /tmp/server.log & working-directory: packages/realm-server + env: + SKIP_CATALOG: true - name: create realm users run: pnpm register-realm-users working-directory: packages/matrix diff --git a/packages/matrix/helpers/isolated-realm-server.ts b/packages/matrix/helpers/isolated-realm-server.ts index e4055dd79b..338abcb74c 100644 --- a/packages/matrix/helpers/isolated-realm-server.ts +++ b/packages/matrix/helpers/isolated-realm-server.ts @@ -2,7 +2,7 @@ import { spawn, type ChildProcess } from 'child_process'; import { resolve, join } from 'path'; // @ts-expect-error no types import { dirSync, setGracefulCleanup } from 'tmp'; -import { ensureDirSync, copySync, readFileSync } from 'fs-extra'; +import { ensureDirSync, copySync, readFileSync, existsSync } from 'fs-extra'; import { Pool } from 'pg'; import { createServer as createNetServer, type AddressInfo } from 'net'; import type { SynapseInstance } from '../docker/synapse'; @@ -17,6 +17,33 @@ const skillsRealmDir = resolve( join(__dirname, '..', '..', 'skills-realm', 'contents'), ); const baseRealmDir = resolve(join(__dirname, '..', '..', 'base')); +const catalogRealmSrc = resolve(join(__dirname, '..', '..', 'catalog-realm')); + +// Build a minimal catalog realm with only the files needed by the skills realm. +// Skills adopt from @cardstack/catalog/skill-set and @cardstack/catalog/skill-plus, +// and link to @cardstack/catalog/Theme/cardstack. +function buildMinimalCatalog(): string { + let tmpDir = dirSync({ unsafeCleanup: true }).name; + let configFiles = ['.realm.json', 'package.json', 'tsconfig.json']; + for (let f of configFiles) { + let src = join(catalogRealmSrc, f); + if (existsSync(src)) { + copySync(src, join(tmpDir, f)); + } + } + let skillFiles = ['skill-set.gts', 'skill-plus.gts', 'skill-reference.gts']; + for (let f of skillFiles) { + let src = join(catalogRealmSrc, f); + if (existsSync(src)) { + copySync(src, join(tmpDir, f)); + } + } + let themeDir = join(catalogRealmSrc, 'Theme'); + if (existsSync(themeDir)) { + copySync(themeDir, join(tmpDir, 'Theme')); + } + return tmpDir; +} const matrixDir = resolve(join(__dirname, '..')); export const appURL = 'http://localhost:4205/test'; @@ -279,6 +306,13 @@ export async function startServer({ `--fromUrl='http://localhost:4205/test/'`, `--toUrl='http://localhost:4205/test/'`, ]; + let minimalCatalogDir = buildMinimalCatalog(); + serverArgs = serverArgs.concat([ + `--username='catalog_realm'`, + `--path='${minimalCatalogDir}'`, + `--fromUrl='@cardstack/catalog/'`, + `--toUrl='http://localhost:4205/catalog/'`, + ]); serverArgs = serverArgs.concat([ `--username='skills_realm'`, `--path='${skillsRealmDir}'`, diff --git a/packages/realm-server/scripts/start-development.sh b/packages/realm-server/scripts/start-development.sh index a1b07ba6e3..699d084460 100755 --- a/packages/realm-server/scripts/start-development.sh +++ b/packages/realm-server/scripts/start-development.sh @@ -33,10 +33,24 @@ if [ -z "$MATRIX_REGISTRATION_SHARED_SECRET" ]; then fi START_EXPERIMENTS=$(if [ -z "$SKIP_EXPERIMENTS" ]; then echo "true"; else echo ""; fi) -START_CATALOG=true -if [ "${SKIP_CATALOG:-}" = "true" ]; then - START_CATALOG="" +# Always start the catalog realm. The skills realm depends on +# @cardstack/catalog/skill-set and @cardstack/catalog/skill-plus modules. +# When SKIP_CATALOG is set, build a minimal catalog with only the files needed +# by the skills realm so it indexes quickly. +if [ "${SKIP_CATALOG:-}" = "true" ] && [ "${CATALOG_REALM_PATH:-}" = "" ]; then + CATALOG_REALM_PATH="$(mktemp -d "${TMPDIR:-/tmp}/catalog-realm.minimal.XXXXXX")" + CATALOG_SRC="../catalog-realm" + for f in .realm.json package.json tsconfig.json; do + [ -e "$CATALOG_SRC/$f" ] && cp -a "$CATALOG_SRC/$f" "$CATALOG_REALM_PATH/" + done + for f in skill-set.gts skill-plus.gts skill-reference.gts; do + [ -f "$CATALOG_SRC/$f" ] && cp -a "$CATALOG_SRC/$f" "$CATALOG_REALM_PATH/" + done + if [ -d "$CATALOG_SRC/Theme" ]; then + cp -a "$CATALOG_SRC/Theme" "$CATALOG_REALM_PATH/" + fi fi +START_CATALOG=true START_BOXEL_HOMEPAGE=$(if [ -z "$SKIP_BOXEL_HOMEPAGE" ]; then echo "true"; else echo ""; fi) START_SUBMISSION=$(if [ -z "$SKIP_SUBMISSION" ]; then echo "true"; else echo ""; fi) diff --git a/packages/realm-server/scripts/start-services-for-host-tests.sh b/packages/realm-server/scripts/start-services-for-host-tests.sh index 47750b8ff5..d3f674cf87 100755 --- a/packages/realm-server/scripts/start-services-for-host-tests.sh +++ b/packages/realm-server/scripts/start-services-for-host-tests.sh @@ -58,17 +58,14 @@ export CATALOG_REALM_PATH="$CATALOG_TEMP_PATH" # Make host-test startup logs focus on indexing progress rather than per-request noise. HOST_TEST_LOG_LEVELS="${HOST_TEST_LOG_LEVELS:-*=info,realm:requests=warn,realm-index-updater=debug,index-runner=debug,index-perf=debug,index-writer=debug,worker=debug,worker-manager=debug}" -# Always start the catalog with the trimmed content above. The skills realm -# depends on @cardstack/catalog/skill-set and @cardstack/catalog/skill-plus -# modules, so the catalog realm must be running for skills to index correctly. -# The trimmed catalog is small enough to index quickly. -# # There is a race condition starting up the servers that setting up the # submission realm triggers which triggers the start-development.sh script to # SIGTERM. currently we don't need the submission realm for host tests to # skipping that. but this issue needs to be fixed. +SKIP_CATALOG="${SKIP_CATALOG:-}" WAIT_ON_TIMEOUT=900000 \ SKIP_EXPERIMENTS=true \ + SKIP_CATALOG="$SKIP_CATALOG" \ SKIP_BOXEL_HOMEPAGE=true \ SKIP_SUBMISSION=true \ CATALOG_REALM_PATH="$CATALOG_TEMP_PATH" \ From 7dbb7b0d719785aad66c0e2f07c9edf0dfe616cf Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 18 Mar 2026 15:54:49 -0400 Subject: [PATCH 4/4] fix: ensure worker processes register @cardstack/catalog/ URL mapping The worker-manager processes build their own VirtualNetwork from --fromUrl/--toUrl pairs. When SKIP_CATALOG=true, the catalog mapping was omitted, so workers couldn't resolve @cardstack/catalog/skill-set during skills realm indexing. - start-worker-development.sh: always register the @cardstack/catalog/ mapping regardless of SKIP_CATALOG (the realm server always serves at least a minimal catalog now) - isolated-realm-server.ts: add catalog and skills URL mappings to the matrix test worker-manager args Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/matrix/helpers/isolated-realm-server.ts | 8 ++++++++ .../realm-server/scripts/start-worker-development.sh | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/matrix/helpers/isolated-realm-server.ts b/packages/matrix/helpers/isolated-realm-server.ts index 338abcb74c..2da517191e 100644 --- a/packages/matrix/helpers/isolated-realm-server.ts +++ b/packages/matrix/helpers/isolated-realm-server.ts @@ -271,6 +271,14 @@ export async function startServer({ `--fromUrl='http://localhost:4205/test/'`, `--toUrl='http://localhost:4205/test/'`, ]; + workerArgs = workerArgs.concat([ + `--fromUrl='@cardstack/catalog/'`, + `--toUrl='http://localhost:4205/catalog/'`, + ]); + workerArgs = workerArgs.concat([ + `--fromUrl='http://localhost:4205/skills/'`, + `--toUrl='http://localhost:4205/skills/'`, + ]); workerArgs = workerArgs.concat([ `--fromUrl='https://cardstack.com/base/'`, `--toUrl='http://localhost:4205/base/'`, diff --git a/packages/realm-server/scripts/start-worker-development.sh b/packages/realm-server/scripts/start-worker-development.sh index 2441b31f56..649634e892 100755 --- a/packages/realm-server/scripts/start-worker-development.sh +++ b/packages/realm-server/scripts/start-worker-development.sh @@ -33,6 +33,11 @@ DEFAULT_SOFTWARE_FACTORY_REALM_URL="${REALM_BASE_URL}/software-factory/" SOFTWARE_FACTORY_REALM_URL="${RESOLVED_SOFTWARE_FACTORY_REALM_URL:-$DEFAULT_SOFTWARE_FACTORY_REALM_URL}" START_EXPERIMENTS=$(if [ -z "${SKIP_EXPERIMENTS:-}" ]; then echo "true"; else echo ""; fi) +# Always register the catalog URL mapping. The skills realm depends on +# @cardstack/catalog/skill-set and @cardstack/catalog/skill-plus modules, +# so the worker needs this mapping to index skills even when SKIP_CATALOG is set +# (start-development.sh always serves at least a minimal catalog). +START_CATALOG_MAPPING=true START_CATALOG=$(if [ -z "${SKIP_CATALOG:-}" ]; then echo "true"; else echo ""; fi) NODE_ENV=development \ @@ -59,8 +64,8 @@ NODE_ENV=development \ ${START_EXPERIMENTS:+--fromUrl="${REALM_BASE_URL}/experiments/"} \ ${START_EXPERIMENTS:+--toUrl="${REALM_BASE_URL}/experiments/"} \ \ - ${START_CATALOG:+--fromUrl='@cardstack/catalog/'} \ - ${START_CATALOG:+--toUrl="${CATALOG_REALM_URL}"} \ + ${START_CATALOG_MAPPING:+--fromUrl='@cardstack/catalog/'} \ + ${START_CATALOG_MAPPING:+--toUrl="${CATALOG_REALM_URL}"} \ \ --fromUrl="${REALM_BASE_URL}/skills/" \ --toUrl="${REALM_BASE_URL}/skills/" \