Skip to content

Commit aa4af55

Browse files
committed
Fix shell-dashboard shell links by plumbing NEXT_PUBLIC_SHELL_URL through build
The shell-dashboard app baked http://localhost:3000 into every demo and code link because NEXT_PUBLIC_SHELL_URL was never provided at build time and the source defaulted to localhost. Next.js inlines NEXT_PUBLIC_* at next build, so setting the value on Railway at runtime does nothing. Fix: remove the silent localhost fallback, pass NEXT_PUBLIC_SHELL_URL as a Docker build arg from showcase_deploy.yml, and fail loudly if it's unset at build so this can't regress silently.
1 parent 2023340 commit aa4af55

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

.github/workflows/showcase_deploy.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ jobs:
175175
{"dispatch_name":"starter-strands","filter_key":"starter_strands","context":"showcase/starters/strands","image":"showcase-starter-strands","railway_id":"06db2bb8-e15d-4c6a-97ad-e14777c92d9f","timeout":15,"lfs":false,"build_args":"","dockerfile":"","health_path":"/api/health"},
176176
{"dispatch_name":"aimock","filter_key":"aimock","context":"showcase/aimock","image":"showcase-aimock","railway_id":"0fa0435d-8a66-46f0-84fd-e4250b580013","timeout":5,"lfs":false,"build_args":"","dockerfile":"","health_path":"/health"},
177177
{"dispatch_name":"shell-dojo","filter_key":"shell_dojo","context":"showcase/shell-dojo","image":"showcase-shell-dojo","railway_id":"7ad1ece7-2228-49cd-8a78-bddf30322907","timeout":10,"lfs":false,"build_args":"","dockerfile":"","health_path":"/"},
178-
{"dispatch_name":"shell-dashboard","filter_key":"shell_dashboard","context":".","image":"showcase-shell-dashboard","railway_id":"4d5dfd74-be61-40b2-8564-b53b7dd4c15b","timeout":10,"lfs":true,"build_args_sha":"${{ github.sha }}","build_args_branch":"${{ github.ref_name }}","dockerfile":"showcase/shell-dashboard/Dockerfile","health_path":"/"},
178+
{"dispatch_name":"shell-dashboard","filter_key":"shell_dashboard","context":".","image":"showcase-shell-dashboard","railway_id":"4d5dfd74-be61-40b2-8564-b53b7dd4c15b","timeout":10,"lfs":true,"build_args_sha":"${{ github.sha }}","build_args_branch":"${{ github.ref_name }}","build_args_shell_url":"https://showcase.copilotkit.ai","dockerfile":"showcase/shell-dashboard/Dockerfile","health_path":"/"},
179179
{"dispatch_name":"shell-docs","filter_key":"shell_docs","context":".","image":"showcase-shell-docs","railway_id":"7badfb8d-4228-414c-9145-b4026803714f","timeout":10,"lfs":true,"build_args_sha":"${{ github.sha }}","build_args_branch":"${{ github.ref_name }}","dockerfile":"showcase/shell-docs/Dockerfile","health_path":"/"}
180180
]'
181181
@@ -278,6 +278,16 @@ jobs:
278278
ARGS="COMMIT_SHA=${{ matrix.service.build_args_sha }}"
279279
ARGS="${ARGS}"$'\n'"BRANCH=${{ matrix.service.build_args_branch }}"
280280
fi
281+
# shell-dashboard needs NEXT_PUBLIC_SHELL_URL at build time —
282+
# Next.js inlines NEXT_PUBLIC_* during `next build`, so the
283+
# Railway runtime env var alone can't rescue a bad build.
284+
if [ -n "${{ matrix.service.build_args_shell_url }}" ]; then
285+
if [ -n "$ARGS" ]; then
286+
ARGS="${ARGS}"$'\n'"NEXT_PUBLIC_SHELL_URL=${{ matrix.service.build_args_shell_url }}"
287+
else
288+
ARGS="NEXT_PUBLIC_SHELL_URL=${{ matrix.service.build_args_shell_url }}"
289+
fi
290+
fi
281291
# Use delimiter to safely pass multiline value
282292
echo "args<<BUILDARGS_EOF" >> $GITHUB_OUTPUT
283293
echo "$ARGS" >> $GITHUB_OUTPUT

showcase/shell-dashboard/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ COPY showcase/shell-dashboard/ ./shell-dashboard/
2424
ENV NEXT_PUBLIC_COMMIT_SHA=${COMMIT_SHA}
2525
ENV NEXT_PUBLIC_BRANCH=${BRANCH}
2626

27+
# Shell URL is inlined by Next.js at build time (NEXT_PUBLIC_*). Must be
28+
# provided as a build arg — a runtime env var on Railway is too late.
29+
ARG NEXT_PUBLIC_SHELL_URL
30+
ENV NEXT_PUBLIC_SHELL_URL=${NEXT_PUBLIC_SHELL_URL}
31+
2732
# Generate registry + docs status + demo content, then build Next.js
2833
RUN cd scripts && node node_modules/tsx/dist/cli.mjs generate-registry.ts \
2934
&& node node_modules/tsx/dist/cli.mjs probe-docs.ts \

showcase/shell-dashboard/src/components/feature-grid.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ import {
1616
} from "@/lib/status";
1717
import { getDocsStatus } from "@/lib/docs-status";
1818

19+
// Read NEXT_PUBLIC_SHELL_URL at module scope so a missing value fails the
20+
// build (`next build` evaluates top-level module code for this server
21+
// component). Previously this fell back silently to http://localhost:3000
22+
// when the env var wasn't set, which baked localhost into every demo/code
23+
// link in the deployed dashboard because Next.js inlines NEXT_PUBLIC_* at
24+
// build time and a runtime env var can't rescue a bad build.
25+
function requireShellUrl(): string {
26+
const url = process.env.NEXT_PUBLIC_SHELL_URL;
27+
if (!url) {
28+
throw new Error(
29+
"NEXT_PUBLIC_SHELL_URL must be set at build time for shell-dashboard",
30+
);
31+
}
32+
return url;
33+
}
34+
const SHELL_URL: string = requireShellUrl();
35+
1936
export interface CellContext {
2037
integration: Integration;
2138
feature: Feature;
@@ -112,7 +129,7 @@ export function FeatureGrid({
112129
renderCell: CellRenderer;
113130
minColWidth?: number;
114131
}) {
115-
const shellUrl = process.env.NEXT_PUBLIC_SHELL_URL || "http://localhost:3000";
132+
const shellUrl = SHELL_URL;
116133
const integrations = getIntegrations();
117134
const features = getFeatures();
118135
const categories = getFeatureCategories();

0 commit comments

Comments
 (0)