Skip to main content

Submodule Workflow

Each service in The Shift Platform is an independent git repository mounted as a submodule in the platform monorepo. This gives each service its own commit history, branches, and release cycle while still allowing them to be built and tested together.

Initial Clone

Always clone with --recurse-submodules to pull all service repos:

git clone --recurse-submodules https://github.com/the-shift-dev/platform.git
cd platform

If you already cloned without submodules, initialize them:

git submodule update --init --recursive

Updating All Submodules

Pull the latest changes for all submodules:

git submodule update --remote --merge

Working in a Submodule

When making changes to a service, you work inside the submodule directory:

# Enter the submodule
cd yellowpages

# Create a feature branch
git checkout -b feature/my-change

# Make changes, commit, and push
git add .
git commit -m "feat: add new endpoint"
git push origin feature/my-change

# After the PR merges, update the platform's submodule pointer
cd ..
git add yellowpages
git commit -m "Update yellowpages submodule"
git push

Commit Ordering

The order of operations matters:

  1. Commit inside the submodule first -- The submodule must have a committed state before the platform can reference it.
  2. Push the submodule -- The platform's CI will try to fetch the submodule commit. If you have not pushed it, the build will fail.
  3. Update the platform pointer -- git add <submodule> stages the new commit reference, then commit and push the platform repo.

PR Workflow

Where you open PRs depends on what changed:

Change inPR goes to
A submodule (e.g., yellowpages/)The submodule's own repo
Gateway or core (packages/)Platform repo
Convex, scripts, or root configPlatform repo
Submodule pointer updatePlatform repo (after submodule PR merges)

Common Pitfalls

Detached HEAD

After git submodule update, submodules are in a detached HEAD state pointing to the exact commit the platform references. Before making changes, always check out a branch:

cd yellowpages
git checkout dev # or main, or a feature branch

Stale @shift/platform-core Cache

After running bun install in a submodule, the cached @shift/platform-core in .bun/ may be stale. If you see errors about missing exports from platform-core, re-run install:

bun install

Or manually refresh the symlink:

rm -rf yellowpages/packages/api/node_modules/@shift/platform-core
ln -s $(pwd)/packages/core yellowpages/packages/api/node_modules/@shift/platform-core

Submodule Needs Rebase Before Push

CI sometimes pushes commits to a submodule (e.g., version bumps). If your push is rejected, rebase first:

cd yellowpages
git pull --rebase
git push

Forgetting to Push the Submodule

If you update the platform's submodule pointer but forget to push the submodule itself, CI will fail because it cannot fetch the referenced commit. Always push the submodule before the platform.

Useful Commands

# Show which commit each submodule points to
git submodule status

# Show a diff of submodule pointer changes
git diff --submodule

# Reset a submodule to the commit the platform references
git submodule update --init yellowpages

# Pull latest for a single submodule
cd yellowpages && git pull origin main && cd ..
git add yellowpages
git commit -m "Update yellowpages to latest"