feat(compose): use compose project name as workspace name - #1006
Conversation
✅ Deploy Preview for devsydev canceled.
|
✅ Deploy Preview for images-devsy-sh canceled.
|
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 112 |
| Duplication | 4 |
AI Reviewer: run a review on demand. To trigger the first review automatically, go to your organization or repository integration settings. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
|
If you're new to commit signing, there are different ways to set it up: Sign commits with
|
6db5734 to
4962a7a
Compare
3bf116f to
9223448
Compare
When running devsy workspace up . with the docker provider on a compose-based devcontainer, devsy previously ignored the configured compose project name and always used the sanitized random runner id, spawning a separate compose project instead of reusing an existing one. Resolve the project name by trusting compose-go's own resolved project.Name whenever the user named the project explicitly (shell COMPOSE_PROJECT_NAME, a .env file, or a compose file's top-level name), falling back to the sanitized random runner id only when compose-go would otherwise fall back to its directory-basename default. Delegating to compose-go (rather than re-parsing compose files by hand) keeps devsy consistent with Docker Compose's own precedence and correctly interpolates compose name fields that use variable substitution. devcontainer.json's name field is deliberately not consulted: per the Dev Containers spec it is a UI display name, not a compose project name. Add unit tests for the resolution precedence, including compose-go's own present-but-empty-shell-env edge case, and an e2e spec plus testdata (docker-compose-nested-envfile) reproducing the reported issue's exact layout: a .env colocated with the compose file in a subdirectory distinct from the workspace root and .devcontainer/. Document the resolution precedence in the devcontainer.json docs page, clarifying that devcontainer.json's name does not affect the compose project name. Resolves #999.
9223448 to
c771731
Compare
|
Tick the box to add this pull request to the merge queue (same as
|
|
|
Warning Review limit reached
Next review available in: 31 minutes Limit details: You’ve used the included review currently available. 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 within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
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 |
Resolves #999.
Summary
When running
devsy workspace up .with the docker provider on a compose-based devcontainer, devsy ignored the configured compose project name and always used the sanitized random runner id, spawning a separate compose project instead of reusing an existing one. This PR resolves the project name following the@devcontainers/clireference precedence so an existing compose project is reused.Precedence (final, aligned with the reference)
COMPOSE_PROJECT_NAMEfrom the shell session.COMPOSE_PROJECT_NAMEfrom the collected.envfiles (first definition wins). devsy passes these same files todocker compose --env-file, so readingCOMPOSE_PROJECT_NAMEfrom the same set keeps devsy and the runtime compose invocation consistent.name:(last declaration wins, matching multi-file override semantics).devsy passes the resolved name via
--project-name, which is Docker Compose's highest-precedence override — exactly the mechanism devsy was already using, just with the wrong value.Comparison with the official specification
containers.dev): thenamefield is "A name for the dev container displayed in the UI" — a display name, not a compose project name. The spec's Docker Compose section is silent on project-name derivation. Sodevcontainer.jsonnameis not used.@devcontainers/clireference (getProjectNameinsrc/spec-node/dockerCompose.ts): resolvesCOMPOSE_PROJECT_NAME(shell) →COMPOSE_PROJECT_NAME(<cwd>/.env) → top-levelname:(with a guard distinguishing a user-declaredname:from compose-go's injected default) → directory basename. devsy matches this ladder, using the random runner id as its final fallback to preserve existing behavior.docs.docker.com/compose/how-tos/project-name/):-pflag >COMPOSE_PROJECT_NAMEenv > top-levelname:> project-dir basename > current-dir basename. Since devsy passes the resolved name via--project-name, step 1 (the-pflag) is what takes effect.TopLevelComposeNamereads raw compose fragments, so it only returns user-declared names — never compose-go's injectedname: devcontainerdefault, which is the same distinction the reference's fragment re-check makes.Known divergence from the reference
devsy reads
COMPOSE_PROJECT_NAMEfrom.devcontainer/.envand compose-dir.envfiles in addition to<workspace>/.env, whereas the reference reads only<workspace>/.env. This is intentional: devsy already passes all of these as--env-filetodocker compose, so they are part of compose's own resolution at runtime. Reading from the same set keeps the computed name and the runtime name identical, which is what makes "reuse the existing compose project" work.Changes
pkg/devcontainer/compose.go:loadComposeProjectno longer unconditionally overwrites the project name with the random runner id; it calls the newresolveComposeProjectName.resolveComposeProjectNameimplements the precedence above.baseEnvFiles(devcontainer config-dir.env+ workspace-root.env, used to resolve$COMPOSE_FILEandCOMPOSE_PROJECT_NAME) andcomposeDirEnvFiles(.envfiles colocated with the resolved compose files, added after compose-file resolution). Deduplication preserves first-seen order.pkg/compose/projectname.go(new): pure, testable helpersProjectNameFromEnvFilesandTopLevelComposeName, plus theComposeProjectNameEnvconstant.pkg/compose/helper.go: addedSanitizeProjectName(exported wrapper around the existing sanitization logic) so the devcontainer layer can sanitize the random-id fallback without re-implementing version-dependent character rules.Notes
stopDockerCompose/deleteDockerComposeare unaffected: they derive the project name from the running container'scom.docker.compose.projectlabel, which compose sets from--project-nameatuptime, so they stay consistent with the new resolution.Namefrom compose-go is intentionally not trusted directly, because compose-go falls back to the project directory's base name when no explicit name source is present. Each higher-precedence source is read explicitly instead.Testing
ProjectNameFromEnvFiles,TopLevelComposeName, andSanitizeProjectNameinpkg/compose/projectname_test.go.resolveComposeProjectName(all precedence levels, multi-file last-wins),baseEnvFiles(collection + dedup),composeDirEnvFiles, andappendEnvFilesinpkg/devcontainer/compose_projectname_test.go.go vet,gofmt,golines, andgolangci-lint v2.12.2(--new-from-rev=origin/main) all clean;go build ./...passes.Test up-docker-composesuite is green in CI, including four new specs that assert the resolved project name (top-level composename:,COMPOSE_PROJECT_NAMEfrom.env,COMPOSE_PROJECT_NAMEfrom the shell, and reuse of the existing compose project on a secondup). The sharedfindComposeContainerhelper now resolves the actual compose project name from the dev container labels (rather than assuming the sanitized workspace UID) so the existing multi-service, shutdown, v2-features, andupdateRemoteUserUIDspecs stay green alongside the new ones.Test up-workspaces(git exit-128) andTest self-update(update --dry-runnetwork call failing instantly at 0.08s) — both environmental flakes unrelated to this change (this PR only touches compose project-name resolution and theup-docker-composehelper; neither test exercises compose). They passed on the prior commit on this same branch and fail from network/git-runner conditions, not from these code changes.This PR was created by an AI agent (OpenHands) on behalf of the user.