Watch every path the workspace image is built from - #177
Conversation
CS-003, reopened. Deploy 4e33d620 built green off 01143ad and /opt/commonplace/studio-server was absent from the running container. Two independent defects, either one fatal alone. No COPY --from=studio-server existed anywhere. The stage wrote /out and the final image never took it, and BuildKit prunes a stage nothing copies from, so the fork was not merely uncopied, it was never compiled. That is why a build carrying the mangler patch finished without ever reaching the mangler. The gate shared a name with the runtime switch. Railway injects every service variable into whatever ARG a stage declares, so IDE_HOST set on the service to keep the runtime host on code-server during cutover would have switched the build off too. The safe-cutover shape this plan rests on, ship both binaries and flip a variable, was unreachable: pinning the variable deleted the binary from the next image. The stage is now gated on BUILD_STUDIO_SERVER, IDE_HOST is runtime only and the dead ARG in the base stage is gone, and the COPY exists. At BUILD_STUDIO_SERVER=0 the stage still writes /out so the COPY stays valid; what it omits is the launcher, which is the file entrypoint.sh probes with -x, so a skipped build falls back to code-server by itself. Proof is the container, not the Dockerfile. The previous done was read off the source, which is how this survived a green build.
The artifact is linux and a mac cannot build it, so the only machine that ever holds one is the container. The way in is railway ssh 'STUDIO_SERVER_DIR=... bash -s' < scripts/smoke-server.sh and piped that way there is no BASH_SOURCE, so under set -u the root derivation aborted at line 12 before a single check ran. A harness that only works when it lives on disk cannot smoke the one place that matters. Fall back to the cwd when BASH_SOURCE is empty. Spelled as an explicit if rather than A && B || C, which is the same SC2015 shape the expect helpers in this file already exist to avoid; shellcheck stays clean. Verified against the live container both ways: it now runs to a real assertion and reports the artifact missing, which is true of the image running today and is the thing the next deploy is meant to change.
Deploy d301c820 was the first time the studio-server stage ever ran, and build.sh server refused in 0.3s on a builder with hundreds of GiB free. `df -g` and `du -sg` are BSD flags. GNU coreutils rejects both, so on Debian df wrote nothing, the empty string read as 0 in the arithmetic, and every floor refused. Written on the mac, never run on linux, which is the same shape as the stage that was never copied. `df -Pk` and `du -sk` are POSIX and identical on both platforms; -P also keeps a long device name from wrapping and shifting the column. The free probe now fails loudly when it cannot read a volume instead of reporting 0, because a probe that cannot answer is not an answer of "full", and conflating the two is what produced a refusal nobody believed. The node_modules credit still degrades quietly, since failing to credit an existing tree only makes the floor stricter. Swept the other studio scripts for the same authoring bias: clean. Both forms verified on macOS so the local path is unchanged.
Deploy 6ddb18cd was SKIPPED for bdd2767, the commit that fixed the Studio build's disk guards. Nothing was wrong with it. The commit touched packaging/commonplace-studio, which was not in watchPatterns, so Railway decided the image could not have changed. It very much could. Dockerfile line 155 copies that entire directory into the studio-server stage: the patch queue, the product overlay and build.sh itself are the IDE door. A SKIPPED deploy reads like a successful no-op, which is how a real fix looked shipped while the running image still had the bug. Audited every COPY from the build context against the list rather than adding back only the one that bit. Three more were missing: LICENSE, which the studio stage copies beside the fork tree; apps/console/src/ styles, which the chat door's web stage copies; and the root package.json, which all three pnpm stages copy while only the lockfile and workspace file were watched. Also corrects the header. `railway up --config` is written in older notes and no longer parses, and uploading without it silently deploys the legacy web service from the root railway.toml. This service builds from its GitHub source on push, so the trigger is a merge.
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
|
Warning Review limit reached
Next review available in: 49 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Ensures the Railway “workspace” service rebuilds whenever any Docker build-context input changes, preventing misleading SKIPPED deploys for image-affecting commits, and aligns the Studio build/roll-back controls with Railway’s build-arg injection behavior.
Changes:
- Expand
watchPatternsto cover all Dockerfile build-contextCOPYsources (including Studio fork pipeline inputs and root manifests). - Make the Studio server stage reliably participate in the final image via
COPY --from=studio-server, and decouple build gating (BUILD_STUDIO_SERVER) from runtime selection (IDE_HOST). - Harden/clarify Studio build + smoke workflow (Linux-compatible disk probes; updated runbook / follow-up docs).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packaging/workspace/railway.toml | Add missing watch patterns so Railway rebuild triggers match Docker build-context inputs. |
| packaging/workspace/Dockerfile | Gate Studio build with BUILD_STUDIO_SERVER and copy Studio stage output into the runtime image. |
| packaging/commonplace-studio/scripts/smoke-server.sh | Make smoke script robust when executed via bash -s in a container/remote session. |
| packaging/commonplace-studio/scripts/build.sh | Fix disk-space guards for Linux builders (df -Pk, du -sk) and fail clearly on unreadable probes. |
| packaging/commonplace-studio/RUNBOOK.md | Document container-first smoke invocation via railway ssh ... bash -s. |
| docs/plans/ide-substrate-wire/FOLLOW-UP-CODE-SERVE-WEB.md | Update follow-up status/lessons learned for Studio stage inclusion + gating. |
| docs/plans/console/SPEC-COMMONPLACE-OPENWORK-FORK-1.0.md | Update spec language to match BUILD_STUDIO_SERVER gating and required stage copy. |
| .commonplace-canonical | Update canonical notes to reflect new rollback arg and the prior failure mode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| development tree that runs only under `scripts/code-server.sh`, and it is a | ||
| local smoke rather than anything shippable. | ||
|
|
||
| Since a mac cannot build the linux artifact, the real target is the image, and |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0579fd7a2d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # which still writes /out, so the COPY into the runtime image stays valid. What | ||
| # it omits is the launcher, which is exactly what entrypoint.sh probes with -x | ||
| # before choosing a host, so a skipped build falls back to code-server on its | ||
| # own rather than starting a door that is not there. |
There was a problem hiding this comment.
Set IDE_HOST when disabling the Studio build
When this rollback is used after Railway has IDE_HOST=studio, the image contains only the SKIP marker, but entrypoint.sh lines 210-232 auto-selects a host only when IDE_HOST is empty and otherwise exits 65 because the Studio launcher is absent. Thus the advertised one-argument rollback can leave the service unable to start; it must also set IDE_HOST=code-server, or the entrypoint must fall back when the selected Studio binary is unavailable.
Useful? React with 👍 / 👎.
Deploy
6ddb18cdwas SKIPPED forbdd2767b, the commit that fixed the Studio build's disk guards. Nothing was wrong with the commit. It touchedpackaging/commonplace-studio, which was not inwatchPatterns, so Railway concluded the image could not have changed.It very much could.
Dockerfile:155copies that entire directory into thestudio-serverstage: the patch queue, the product overlay, andbuild.shitself are the IDE door.A SKIPPED deploy is the dangerous failure here because it reads like a successful no-op. That is how a real fix looked shipped while the running image still had the bug.
Changes
Audited every
COPYfrom the build context against the watch list rather than adding back only the path that bit. Four were missing:packaging/commonplace-studio/**(Dockerfile:155) — the Studio fork pipeline.LICENSE(Dockerfile:156) — copied beside the fork tree.apps/console/src/styles/**(Dockerfile:38) — the chat door's web stage.package.json(Dockerfile:26, 102, 242) — all three pnpm stages copy it; only the lockfile and workspace file were watched.Also corrects the file's own header:
railway up --configno longer parses (CLI 5.30.4 answersunexpected argument '--config' found), and runningrailway upwithout it silently deploys the legacy web service from the rootrailway.toml. This service builds from GitHub source on push, so the trigger is a merge.Validation
railway.tomlparses (tomllib), 15 watch patterns.grep '^COPY ' Dockerfile | grep -v -- --from; every context path is now covered.packaging/workspace/**, which was already watched, so merging it will trigger the build that6ddb18cdskipped and carry the disk-guard fix with it.