Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ad107d2
Seed public-read parity for environment-mode realms at boot
backspace May 27, 2026
31f8685
Add environment-mode host CI proof-of-concept job
backspace May 28, 2026
8a6eefe
Run card-catalog suite in the env-mode host PoC job
backspace May 28, 2026
4212b94
Invoke ember via pnpm exec in env-mode card-catalog step
backspace May 28, 2026
77f63ce
Make env-mode card-catalog slice non-blocking while it is matured
backspace May 28, 2026
729030c
Add cross-origin module CORS diagnostic to env-mode PoC
backspace May 28, 2026
7f12ce4
Add environment-mode realm-server CI proof-of-concept job
backspace May 28, 2026
80e62db
Scale env-mode realm-server CI to a 6-shard matrix
backspace May 28, 2026
5e674d1
Strengthen env-mode host PoC readiness gate and settle prerender
backspace May 28, 2026
9fc3788
Fix env-mode host PoC sleep step that absorbed prior step's tail
backspace May 28, 2026
3aaff3d
Scale env-mode host CI to a 20-shard matrix
backspace May 29, 2026
4d9c587
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace May 29, 2026
746e9bd
Rewrite hardcoded test-realm URL in env mode and add chunk-fetch retry
backspace May 29, 2026
0467110
Reformat env-mode-lock.js to satisfy prettier
backspace May 29, 2026
21db4f3
Declare resolvedTestRealmURL type; reformat software-factory doc
backspace May 29, 2026
cde8381
Diagnostic: disable test-realm URL mapping to isolate shard 9 regression
backspace Jun 1, 2026
8520764
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 5, 2026
b6af3d1
Restore test-realm URL mapping now that global prefix mappings are gone
backspace Jun 5, 2026
0a169a6
Wait for skills realm to finish indexing in env-mode host PoC
backspace Jun 8, 2026
52d05ed
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 8, 2026
0a6527c
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 9, 2026
91f1140
Populate skills-realm content before env-mode workspace builds
backspace Jun 9, 2026
582c355
Explicit HTTPS clone of boxel-skills in env-mode jobs
backspace Jun 9, 2026
fb513d7
Diagnostic: verify skills content on disk just before realm-server st…
backspace Jun 9, 2026
898cba0
Mirror full realm permissions for env-mode bootstrap realms
backspace Jun 9, 2026
5175537
Use migration-free path for env-mode parity deepEqual tests
backspace Jun 9, 2026
dea60ec
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 10, 2026
31d9200
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 11, 2026
644ac13
Run host + realm-server tests in environment mode
backspace Jun 11, 2026
5f29a39
Fix env-mode host + realm-server test failures
backspace Jun 11, 2026
fffac3c
Set TLS cert env vars explicitly at job level
backspace Jun 11, 2026
bf03ab4
Skip TLS env-var strip in tests/helpers when in env mode
backspace Jun 11, 2026
8cb6397
Revert realm-server-test to standard mode
backspace Jun 11, 2026
578baa2
Make testModuleRealm env-mode-aware
backspace Jun 12, 2026
f5ca867
Source the test matrix URL from ENV.matrixURL
backspace Jun 12, 2026
0c41e17
Parameterize hardcoded standard-mode URLs in host tests
backspace Jun 12, 2026
311f014
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 12, 2026
3a90ae6
Sort the expected card-references list at assertion time
backspace Jun 12, 2026
41c5435
Parameterize hardcoded localhost:4201 hosts in host-submode tests
backspace Jun 12, 2026
9799354
Cut journey/private-tracker rot from comments on this branch
backspace Jun 12, 2026
01af7eb
Prebuild env-mode host dist once, download per shard
backspace Jun 12, 2026
da16144
Migrate live-test to env mode; drop separate env-mode prebuild job
backspace Jun 12, 2026
0f1dbc8
[TEMP] Disable host/realm-server/matrix-client tests for live-test it…
backspace Jun 12, 2026
14d03c6
Re-enable host/realm-server/matrix-client tests
backspace Jun 12, 2026
6cc528d
Drop sleep-60 settle step from live-test and host-test
backspace Jun 12, 2026
c7707e9
Delete unused host `test-with-percy` npm script
backspace Jun 12, 2026
4bd0aff
Gate the test-realm URL rewrite on isTesting()
backspace Jun 12, 2026
4cb089f
Derive testRealmURL from BOXEL_ENVIRONMENT in host config defaults
backspace Jun 12, 2026
4a197d4
Restore \`test-with-percy\` so the workflow can resolve \`percy\`
backspace Jun 12, 2026
5fe0911
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 12, 2026
86daf24
Add empty commit
backspace Jun 12, 2026
66b49ff
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 15, 2026
7dfbfd4
Probe the icons service in the env-mode parity gate
backspace Jun 15, 2026
43d1ecb
Register matrix users in env-mode CI; point card-delete stack 1 at a …
backspace Jun 15, 2026
50fa6bb
Retry host-test shard on transient `Failed to fetch` from icons
backspace Jun 15, 2026
3562962
Retry host-test shard on cross-realm-fetch 404 to the live test realm
backspace Jun 16, 2026
ea01f18
Catch the host-store 404 form of the realm-test boot-race in shard retry
backspace Jun 16, 2026
14a2707
Retry env-mode `*.localhost` fetches in the worker's transient-error …
backspace Jun 16, 2026
39cb846
Scope env-mode `*.localhost` retry to processes with BOXEL_ENVIRONMEN…
backspace Jun 16, 2026
5b2a408
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 16, 2026
07193b2
Wait for the live `/test/` realm to be indexed in the host-test parit…
backspace Jun 16, 2026
9dd860a
Fix icons retry regex and diagnose empty-realm indexing in env-mode CI
backspace Jun 16, 2026
177721d
Retry indexer mtimes on intermediary 404 from a not-yet-routed realm
backspace Jun 16, 2026
c7d586d
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 17, 2026
71b2e24
Cancel intermediary response body before backing off in mtimes retry
backspace Jun 17, 2026
abb4a94
Normalize REALM_TEST_URL override to accept either base host or /test…
backspace Jun 17, 2026
fb2b91b
Merge remote-tracking branch 'origin/main' into environment-mode-host…
backspace Jun 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 342 additions & 17 deletions .github/workflows/ci-host.yaml

Large diffs are not rendered by default.

27 changes: 25 additions & 2 deletions .github/workflows/test-web-assets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ on:
required: false
type: boolean
default: false
boxel_environment:
description: |
BOXEL_ENVIRONMENT slug to bake into the host dist. Empty for
a standard-mode build (URLs like https://localhost:4201);
a value like "ci" produces an env-mode build whose realm URLs
target the per-environment Traefik hostnames
(https://realm-server.ci.localhost, etc.). The slug is folded
into the cache key and artifact name so standard-mode and
env-mode builds don't collide.
required: false
type: string
default: ""
outputs:
artifact_name:
description: Artifact name containing built test web assets
Expand Down Expand Up @@ -46,8 +58,13 @@ jobs:
run: |
ref_slug="$(echo "${GITHUB_REF}" | tr '/' '_')"
skip_catalog="${{ inputs.skip_catalog }}"
cache_key="test-web-assets-v2-${RUNNER_OS}-${ref_slug}-${GITHUB_SHA}-skip-catalog-${skip_catalog}"
artifact_name="test-web-assets-${GITHUB_SHA}-skip-catalog-${skip_catalog}"
boxel_env="${{ inputs.boxel_environment }}"
# An empty boxel_environment encodes the standard-mode build;
# any non-empty slug produces a distinct artifact + cache entry
# so env-mode and standard-mode builds for the same SHA coexist.
env_suffix="${boxel_env:-std}"
cache_key="test-web-assets-v2-${RUNNER_OS}-${ref_slug}-${GITHUB_SHA}-skip-catalog-${skip_catalog}-env-${env_suffix}"
artifact_name="test-web-assets-${GITHUB_SHA}-skip-catalog-${skip_catalog}-env-${env_suffix}"
echo "cache_key=$cache_key" >> "$GITHUB_OUTPUT"
echo "artifact_name=$artifact_name" >> "$GITHUB_OUTPUT"

Expand Down Expand Up @@ -78,6 +95,10 @@ jobs:
working-directory: packages/host
env:
SKIP_CATALOG: ${{ inputs.skip_catalog }}
# When set, environment.js bakes the env-mode realm/matrix/icons
# URLs (https://realm-server.<slug>.localhost, etc.) into the
# vite chunks. Empty preserves the standard-mode defaults.
BOXEL_ENVIRONMENT: ${{ inputs.boxel_environment }}

- name: Write assets manifest
shell: bash
Expand All @@ -94,6 +115,7 @@ jobs:
cacheKey: process.env.CACHE_KEY,
cacheHit: process.env.CACHE_HIT === "true",
skipCatalog: process.env.SKIP_CATALOG === "true",
boxelEnvironment: process.env.BOXEL_ENVIRONMENT || null,
builtAt: new Date().toISOString(),
};
fs.writeFileSync(".ci/test-web-assets/manifest.json", JSON.stringify(manifest, null, 2));
Expand All @@ -102,6 +124,7 @@ jobs:
CACHE_KEY: ${{ steps.keys.outputs.cache_key }}
CACHE_HIT: ${{ steps.restore.outputs.cache-hit }}
SKIP_CATALOG: ${{ inputs.skip_catalog }}
BOXEL_ENVIRONMENT: ${{ inputs.boxel_environment }}

- name: Save cached assets
if: steps.restore.outputs.cache-hit != 'true'
Expand Down
11 changes: 11 additions & 0 deletions mise-tasks/services/test-realms
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ SCRIPTS_DIR="./scripts"
# server never writes into the repo's source tree.
TEST_REALM_DIR=$(mktemp -d)
cp -R ../test-realm-cards/contents/. "$TEST_REALM_DIR"/
# Diagnostics: env-mode CI has been seeing the test realm-server's
# from-scratch index finish with `files_completed=0` for both
# `/test/` (this temp dir) and `/node-test/` (./tests/fixtures/realistic),
# which means the realm-server's `_mtimes` endpoint is walking what
# looks like an empty directory. Log file counts at this point so the
# CI log makes it obvious whether the cp succeeded, whether the
# checked-in fixtures directory is populated, and whether anything
# wipes them between here and the realm-server boot.
echo "[test-realms diag] TEST_REALM_DIR=$TEST_REALM_DIR file_count=$(ls -1A "$TEST_REALM_DIR" 2>/dev/null | wc -l | tr -d ' ')"
echo "[test-realms diag] ../test-realm-cards/contents file_count=$(ls -1A ../test-realm-cards/contents 2>/dev/null | wc -l | tr -d ' ')"
echo "[test-realms diag] ./tests/fixtures/realistic file_count=$(ls -1A ./tests/fixtures/realistic 2>/dev/null | wc -l | tr -d ' ')"

# In environment mode, share the dev icons server; otherwise start our own
if [ -z "$BOXEL_ENVIRONMENT" ]; then
Expand Down
1 change: 1 addition & 0 deletions packages/host/app/config/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default config as {
resolvedCatalogRealmURL: string | undefined;
resolvedSkillsRealmURL: string;
resolvedOpenRouterRealmURL: string | undefined;
resolvedTestRealmURL: string;
hostsOwnAssets: boolean;
realmsServed?: string[];
logLevels: string;
Expand Down
21 changes: 21 additions & 0 deletions packages/host/app/services/network.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type Owner from '@ember/owner';
import Service, { service } from '@ember/service';

import { isTesting } from '@embroider/macros';

import {
VirtualNetwork,
authorizationMiddleware,
Expand Down Expand Up @@ -83,6 +85,25 @@ export default class NetworkService extends Service {
config.resolvedOpenRouterRealmURL,
);
}
// Some test fixture content (JSON card files under tests/cards/, embedded
// card ids in test data) refers to the live test realm by its standard-
// mode URL `https://localhost:4202/test/`. In environment mode the live
// test realm is served at a per-environment Traefik hostname. Mapping
// the standard-mode URL onto whatever the running test realm-server
// serves lets the same fixture content resolve under either mode.
// Gated on isTesting() so the mapping never reaches prod fetches.
if (isTesting()) {
let hardcodedTestRealmURL = new URL('https://localhost:4202/test/');
let resolvedTestRealmURL = new URL(
withTrailingSlash(config.resolvedTestRealmURL),
);
if (resolvedTestRealmURL.href !== hardcodedTestRealmURL.href) {
virtualNetwork.addURLMapping(
hardcodedTestRealmURL,
resolvedTestRealmURL,
);
}
}
return virtualNetwork;
}

Expand Down
23 changes: 23 additions & 0 deletions packages/host/config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function environmentDefaults() {
catalogRealmURL: 'https://localhost:4201/catalog/',
skillsRealmURL: 'https://localhost:4201/skills/',
openRouterRealmURL: 'https://localhost:4201/openrouter/',
testRealmURL: 'https://localhost:4202/test/',
};
}
let slug = getEnvSlug();
Expand All @@ -87,6 +88,10 @@ function environmentDefaults() {
catalogRealmURL: `https://${realmHost}/catalog/`,
skillsRealmURL: `https://${realmHost}/skills/`,
openRouterRealmURL: `https://${realmHost}/openrouter/`,
// mise-tasks/services/test-realms registers the live test realm at
// `https://realm-test.${slug}.localhost/test/` in env mode (the
// counterpart to standard mode's `https://localhost:4202/test/`).
testRealmURL: `https://realm-test.${slug}.localhost/test/`,
};
}

Expand Down Expand Up @@ -165,6 +170,24 @@ module.exports = function (environment) {
process.env.RESOLVED_SKILLS_REALM_URL || defaults.skillsRealmURL,
resolvedOpenRouterRealmURL:
process.env.RESOLVED_OPENROUTER_REALM_URL || defaults.openRouterRealmURL,
// The live test realm-server's /test/ realm — used by host tests
// that load source modules from it via
// `tests/helpers#testModuleRealm`. Derived from BOXEL_ENVIRONMENT via
// `defaults.testRealmURL` above (localhost:4202 in standard mode,
// realm-test.<slug>.localhost in env mode). Explicit
// `REALM_TEST_URL` overrides take precedence for non-CI consumers
// that want a custom test realm endpoint. The override accepts
// either a base host URL (which gets `/test/` appended) or a value
// that already names the `/test` realm — without the latter case
// a path like `https://my-host/test/` would become
// `https://my-host/test/test/`.
resolvedTestRealmURL: (() => {
if (!process.env.REALM_TEST_URL) return defaults.testRealmURL;
let normalized = process.env.REALM_TEST_URL.replace(/\/$/, '');
return normalized.endsWith('/test')
? `${normalized}/`
: `${normalized}/test/`;
})(),
featureFlags: {},
};

Expand Down
2 changes: 1 addition & 1 deletion packages/host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"start": "node scripts/vite-serve.js",
"serve:dist": "node scripts/serve-dist.js",
"test": "concurrently \"pnpm:lint\" \"pnpm:test:*\" --names \"lint,test:\"",
"test-with-percy": "percy exec --parallel -- pnpm test:wait-for-servers",
"test-with-percy": "percy exec --parallel -- pnpm ember-test-pre-built",
"test:wait-for-servers": "./scripts/test-wait-for-servers.sh",
"test:live": "./scripts/live-test-wait-for-servers.sh",
"ember-test-pre-built": "sleep 15 && ember exam --path ./dist --split $HOST_TEST_PARTITION_COUNT --partition $HOST_TEST_PARTITION --preserve-test-name",
Expand Down
20 changes: 17 additions & 3 deletions packages/host/scripts/live-test-wait-for-servers.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
#! /bin/sh

READY_PATH="_readiness-check?acceptHeader=application%2Fvnd.api%2Bjson"
BASE_REALM_READY="https-get://localhost:4201/base/${READY_PATH}"
SYNAPSE_URL="http://localhost:8008"

# Default to the standard-mode ports; env mode (BOXEL_ENVIRONMENT set)
# exports REALM_BASE_URL=https://realm-server.<slug>.localhost and
# MATRIX_URL_VAL=https://matrix.<slug>.localhost via env-vars.sh, so
# fall back to those when present.
REALM_BASE_URL="${REALM_BASE_URL:-https://localhost:4201}"
MATRIX_URL_VAL="${MATRIX_URL_VAL:-http://localhost:8008}"
realm_host="${REALM_BASE_URL#http://}"
realm_host="${realm_host#https://}"
realm_host="${realm_host%/}"
case "$REALM_BASE_URL" in
https://*) realm_scheme="https-get" ;;
*) realm_scheme="http-get" ;;
esac
BASE_REALM_READY="${realm_scheme}://${realm_host}/base/${READY_PATH}"
SYNAPSE_URL="$MATRIX_URL_VAL"
SMTP_4_DEV_URL="http://localhost:5001"

# Pick wait-on's protocol prefix from whichever scheme the caller used.
Expand Down Expand Up @@ -32,7 +46,7 @@ else
# passing assert). Skills is small and is hosted by every host CI job
# already, so waiting on its readiness adds little beyond what base
# already incurs.
SKILLS_REALM_READY="https-get://localhost:4201/skills/${READY_PATH}"
SKILLS_REALM_READY="${realm_scheme}://${realm_host}/skills/${READY_PATH}"
READY_URLS="$BASE_REALM_READY|$SKILLS_REALM_READY|$SYNAPSE_URL|$SMTP_4_DEV_URL"
fi

Expand Down
5 changes: 3 additions & 2 deletions packages/host/tests/acceptance/code-submode-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
SYSTEM_CARD_FIXTURE_CONTENTS,
setMonacoContent,
setupLocalIndexing,
testModuleRealm,
testRealmURL,
visitOperatorMode,
setupAuthEndpoints,
Expand Down Expand Up @@ -1273,12 +1274,12 @@ module('Acceptance | code submode tests', function (_hooks) {
});
module('with connection to test realm', function (hooks) {
hooks.beforeEach(function () {
setActiveRealms([testRealmURL, 'https://localhost:4202/test/']);
setActiveRealms([testRealmURL, `${testModuleRealm}`]);
});
test('code submode handles binary files', async function (assert) {
await visitOperatorMode({
submode: 'code',
codePath: `https://localhost:4202/test/mango.png`,
codePath: `${testModuleRealm}mango.png`,
});

await waitFor('[data-test-binary-info]');
Expand Down
7 changes: 4 additions & 3 deletions packages/host/tests/acceptance/code-submode/file-tree-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
elementIsVisible,
setupLocalIndexing,
setupRealmCacheTeardown,
testModuleRealm,
testRealmURL,
setupAcceptanceTestRealm,
SYSTEM_CARD_FIXTURE_CONTENTS,
Expand Down Expand Up @@ -478,7 +479,7 @@ module('Acceptance | code submode | file-tree tests', function (hooks) {
// go to a file with different realm
await fillIn(
'[data-test-card-url-bar-input]',
`https://localhost:4202/test/mango.png`,
`${testModuleRealm}mango.png`,
);
await triggerKeyEvent(
'[data-test-card-url-bar-input]',
Expand Down Expand Up @@ -522,7 +523,7 @@ module('Acceptance | code submode | file-tree tests', function (hooks) {

await fillIn(
'[data-test-card-url-bar-input]',
`https://localhost:4202/test/mango.png`,
`${testModuleRealm}mango.png`,
);
await triggerKeyEvent(
'[data-test-card-url-bar-input]',
Expand Down Expand Up @@ -824,7 +825,7 @@ module('Acceptance | code submode | file-tree tests', function (hooks) {

await fillIn(
'[data-test-card-url-bar-input]',
`https://localhost:4202/test/mango.png`,
`${testModuleRealm}mango.png`,
);
await triggerKeyEvent(
'[data-test-card-url-bar-input]',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
percySnapshot,
setupLocalIndexing,
setupRealmCacheTeardown,
testModuleRealm,
testRealmURL,
setupAcceptanceTestRealm,
SYSTEM_CARD_FIXTURE_CONTENTS,
Expand Down Expand Up @@ -318,7 +319,7 @@ module('Acceptance | code submode | recent files tests', function (hooks) {
test('recent file links are shown', async function (assert) {
setRecentFiles([
[testRealmURL, 'index.json'],
['https://localhost:4202/test/', 'français.json'],
[`${testModuleRealm}`, 'français.json'],
// @ts-ignore error on purpose
'a-non-url-to-ignore',
]);
Expand Down Expand Up @@ -404,7 +405,7 @@ module('Acceptance | code submode | recent files tests', function (hooks) {
[testRealmURL, 'index.json', null],
[testRealmURL, 'français.json', null],
[testRealmURL, 'Person/1.json', null],
['https://localhost:4202/test/', 'français.json', null],
[`${testModuleRealm}`, 'français.json', null],
]);
});

Expand Down
3 changes: 2 additions & 1 deletion packages/host/tests/acceptance/commands-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
addSkillToAiAssistant,
setupLocalIndexing,
setupOnSave,
testModuleRealm,
testRealmURL,
testRRI,
setupAcceptanceTestRealm,
Expand Down Expand Up @@ -399,7 +400,7 @@ module('Acceptance | Commands tests', function (hooks) {
},
meta: {
adoptsFrom: {
module: 'https://localhost:4202/test/ai-command-example',
module: `${testModuleRealm}ai-command-example`,
name: 'AiCommandExample',
},
},
Expand Down
Loading
Loading