Skip to content

build(workspaces): promote repo root to npm workspace root#53

Merged
CoderCoco merged 4 commits into
mainfrom
claude/issue-49-VR4KW
May 1, 2026
Merged

build(workspaces): promote repo root to npm workspace root#53
CoderCoco merged 4 commits into
mainfrom
claude/issue-49-VR4KW

Conversation

@CoderCoco
Copy link
Copy Markdown
Owner

Summary

Restructure the npm workspace tree to be rooted at the repository root instead of under app/, simplifying dependency management and build workflows across the entire project.

Key Changes

  • Workspace root relocation: Moved workspace configuration from app/package.json to a new root package.json, with workspaces now defined as ["app", "app/packages/*", "scripts"]
  • Root-level npm commands: Added convenience scripts at the root level (e.g., npm run app:dev, npm run app:build) that delegate to workspace-specific commands, eliminating the need to cd app before running tasks
  • Dockerfile updates:
    • Changed WORKDIR from /app to /workspace to match the new structure
    • Updated all COPY commands to reference the root package.json and adjust paths accordingly
    • Added stub scripts/package.json to prevent npm from installing maintainer-only dev tools in production
    • Added final WORKDIR /workspace/app to preserve existing behavior for ConfigService path probing
  • CI/CD workflow updates: Removed working-directory: app defaults and updated cache paths to use root-level package-lock.json; updated lint and test commands to use new root-level scripts
  • Documentation updates:
    • Updated CLAUDE.md with new command patterns (e.g., npm run app:dev instead of cd app && npm run dev)
    • Updated submodule setup guide to use the new workspace structure
    • Updated docker-compose.yml volume mounts to reflect /workspace paths
  • Setup script: Updated setup.sh to run npm ci from repo root instead of app/ directory

Implementation Details

The restructuring maintains backward compatibility by:

  • Keeping the app/ directory structure intact with its own package.json (now without workspace declarations)
  • Using root-level convenience scripts that target specific workspaces with -w flag
  • Preserving the final working directory in Docker as /workspace/app to ensure existing path-based logic continues to work
  • Creating a stub scripts/package.json to prevent unnecessary dependencies in the production image while still allowing the workspace to be referenced

This change simplifies the mental model of the project structure and reduces friction when running commands from the repository root.

https://claude.ai/code/session_01BfCUaJBR6wTmdH2ET8oov4

claude added 2 commits May 1, 2026 02:37
Closes #49

- Add root `package.json` with `workspaces: ["app", "app/packages/*",
  "scripts"]` so a single `npm install` at the repo root installs
  everything for both the management app and the `@gsd/scripts`
  maintainer package.
- Remove the `workspaces` field from `app/package.json` (now declared
  at the root).
- Delete `scripts/package-lock.json`; the new root `package-lock.json`
  covers all workspace members.
- Update `setup.sh` to run `npm ci` from the repo root (was `cd app &&
  npm ci`).
- Update CI workflows (`lint.yml`, `test.yml`): point
  `cache-dependency-path` at the root lockfile, drop the
  `working-directory: app` default, and use `-w game-server-manager`
  workspace flag for lint/test.
- Update `Dockerfile`: workspace root is now `/workspace`; stub out the
  `scripts/` workspace with an empty `package.json` so `tsx` and other
  maintainer-only dev tools are not pulled into the production image.
  Runtime `WORKDIR` stays at `/workspace/app` so ConfigService path
  probing and `docker-compose.yml` volume targets remain consistent.
- Update `docker-compose.yml` volume targets: `/app/terraform` →
  `/workspace/terraform`, `/app/server_config.json` →
  `/workspace/app/server_config.json`.
- Update `CLAUDE.md`, `README.md`, and `docs/docs/guides/submodule.md`
  to reflect the new single-install command and
  `npm run init-parent -w @gsd/scripts` invocation.

https://claude.ai/code/session_01BfCUaJBR6wTmdH2ET8oov4
All common commands now runnable from the repo root without `cd app`:
  npm run app:dev
  npm run app:build / app:start / app:build:lambdas
  npm run app:test / app:test:watch
  npm run app:lint / app:lint:fix
  npm run scripts:init-parent

Update CI workflows and setup.sh to use the new aliases. Update
CLAUDE.md to document the root-level commands.

https://claude.ai/code/session_01BfCUaJBR6wTmdH2ET8oov4
Copilot AI review requested due to automatic review settings May 1, 2026 02:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restructures the repository’s npm workspaces so the workspace root is the repo root (instead of app/), updating local tooling, Docker, CI, and docs to run commands from the top-level consistently.

Changes:

  • Added a root package.json with workspaces and root-level convenience scripts that delegate into the game-server-manager workspace.
  • Updated bootstrap/setup, Docker, docker-compose, and CI workflows to run npm commands from the repo root and use the root lockfile.
  • Updated documentation to reflect the new workspace/command layout (submodule guide, CLAUDE.md, README).

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
package.json New root workspace definition + root convenience scripts (e.g. app:*, scripts:init-parent).
app/package.json Removes workspace declarations from app/ now that root is the workspace root.
setup.sh Runs npm ci from repo root and uses npm run app:build:lambdas.
Dockerfile Switches to /workspace root, installs via root lockfile, builds via workspace command, then sets WORKDIR /workspace/app.
docker-compose.yml Updates bind-mount targets to match new /workspace layout.
.github/workflows/test.yml Removes working-directory: app, caches root lockfile, runs npm run app:test.
.github/workflows/lint.yml Removes working-directory: app, caches root lockfile, runs npm run app:lint.
docs/docs/guides/submodule.md Updates submodule scaffolder instructions for the new workspace install flow.
CLAUDE.md Updates maintainer command examples to root-level scripts.
README.md Updates quick-start commands related to running the app after terraform apply.
scripts/package-lock.json Removes scripts-specific lockfile (now covered by root workspace lockfile).
Files not reviewed (1)
  • scripts/package-lock.json: Language not supported

Comment thread package.json Outdated
Comment on lines +1 to +4
{
"name": "game-server-deploy",
"private": true,
"workspaces": ["app", "app/packages/*", "scripts"],
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title doesn’t follow Conventional Commits (required here because PR titles are squash-merged onto main). Please retitle to something like chore(workspaces): move npm workspace root to repo root (or similar type/scope) with the <type>(<scope>): <summary> format.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — PR retitled to build(workspaces): promote repo root to npm workspace root.


Generated by Claude Code

Comment thread Dockerfile
Comment on lines +20 to +24

# Stub out the scripts workspace so npm ci doesn't pull in tsx or other
# maintainer-only dev tools that have no place in the production image.
RUN mkdir -p scripts && printf '{"name":"@gsd/scripts","version":"0.0.0","private":true}' > scripts/package.json

Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUN mkdir -p scripts ... > scripts/package.json creates a stub workspace manifest that does not match the root package-lock.json (which includes scripts/ devDependencies). npm ci will fail with a lockfile/package.json mismatch in the Docker build. Consider copying the real scripts/package.json into the image for the install step, or adjusting the install strategy (e.g., install only the game-server-manager workspace / use a multi-stage build + prune) so the lockfile remains consistent.

Suggested change
# Stub out the scripts workspace so npm ci doesn't pull in tsx or other
# maintainer-only dev tools that have no place in the production image.
RUN mkdir -p scripts && printf '{"name":"@gsd/scripts","version":"0.0.0","private":true}' > scripts/package.json
COPY scripts/package.json scripts/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2841127 — replaced the stub with COPY scripts/package.json scripts/. The stub approach was also the root cause of the CI test failure: app/packages/lambda/* was missing from the root workspaces glob (the old app/package.json had them as "packages/lambda/*" separately), so @aws-sdk/client-lambda and friends were absent from the lockfile. Both issues fixed together; all 258 tests now pass locally.


Generated by Claude Code

Comment thread docs/docs/guides/submodule.md Outdated
game-server-deploy/scripts/init-parent.ts
# 3. Install all deps (one install covers the app and the scripts workspace).
(cd game-server-deploy && npm install)
npm run init-parent -w @gsd/scripts --prefix game-server-deploy
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command won’t run as intended: with npm run, options placed after the script name are forwarded to the script, so --prefix game-server-deploy won’t be interpreted by npm (and the command likely fails if run from the parent repo that has no package.json). Use an npm-level --prefix (e.g. npm --prefix game-server-deploy run ...) or the root convenience script (scripts:init-parent) so the invocation works from the parent repo root.

Suggested change
npm run init-parent -w @gsd/scripts --prefix game-server-deploy
npm --prefix game-server-deploy run init-parent -w @gsd/scripts

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2841127 — replaced with (cd game-server-deploy && npm run scripts:init-parent), which uses the root convenience script and avoids the --prefix ordering ambiguity entirely.


Generated by Claude Code

Comment thread README.md Outdated

# 4a. Run the management app in dev mode
cd ../app && npm run dev
cd app && npm run dev
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After cd terraform && terraform apply, the next step is still inside terraform/, so cd app will try to enter terraform/app (nonexistent). This should either cd .. first or use cd ../app so the quick-start commands work as written.

Suggested change
cd app && npm run dev
cd ../app && npm run dev

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2841127 — changed to cd .. && npm run app:dev (also switched from cd app && npm run dev to the root-level alias, consistent with the rest of the PR).


Generated by Claude Code

…docs

- Add `app/packages/lambda/*` to root `package.json` workspaces.
  The old `app/package.json` had `"packages/lambda/*"` as a separate
  entry because the lambda packages nest one level deeper than the
  other packages. Without this, `@aws-sdk/client-lambda` and
  `@aws-sdk/client-elastic-load-balancing-v2` were absent from the
  lockfile, causing three test suites to fail at module resolution.
- Regenerate `package-lock.json` with the correct workspace set (258
  tests now pass).
- Dockerfile: replace the `scripts/` stub with `COPY scripts/package.json
  scripts/` so `npm ci` doesn't fail with a lockfile/manifest mismatch.
- README: fix `cd app` → `cd .. && npm run app:dev` after `cd terraform
  && terraform apply` (the working directory was still inside `terraform/`).
- submodule guide: replace malformed `npm run ... --prefix` invocation
  with `(cd game-server-deploy && npm run scripts:init-parent)` which
  works correctly from the parent repo root.

https://claude.ai/code/session_01BfCUaJBR6wTmdH2ET8oov4
@CoderCoco CoderCoco changed the title Restructure npm workspaces to root level build(workspaces): promote repo root to npm workspace root May 1, 2026
@CoderCoco CoderCoco merged commit 252c91c into main May 1, 2026
7 checks passed
@CoderCoco CoderCoco deleted the claude/issue-49-VR4KW branch May 1, 2026 03:09
CoderCoco added a commit that referenced this pull request May 10, 2026
…#131)

Closes #130

## Summary

- `bootstrap()` and `deploy()` in `setup.sh` were both `cd`-ing into
`app/` and calling `npm run build:lambdas`, left over from before PR #53
promoted the npm workspace root from `app/` to the repo root
- Changed `cd "$SCRIPT_DIR/app"` → `cd "$SCRIPT_DIR"` in both functions
so `npm ci` runs from the workspace root and correctly hoists all
dependencies
- Changed `npm run build:lambdas` → `npm run app:build:lambdas` to match
the root-level script alias
- Fixed the stale "next steps" dev command in the bootstrap output (`cd
app && npm run dev` → `npm run app:dev`)
- Removed `app/package-lock.json` — orphaned lockfile from before the
workspace root promotion that could confuse npm

## Test plan

- [ ] Run `./setup.sh` on a clean clone — confirm `npm ci` succeeds at
the repo root and Lambda bundles build without TS2307 errors
- [ ] Run `./setup.sh deploy` — confirm `npm run app:build:lambdas` runs
successfully from the repo root
- [ ] Confirm `app/package-lock.json` is gone and `npm ci` at repo root
still resolves all workspace deps correctly

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants