obsidian/wiki/concepts/monorepo-deploy-script-pitfall.md
2026-04-18 22:04:01 +01:00

3.5 KiB

title aliases tags sources created updated
Monorepo Deploy Script — Subdirectory .git Check Pitfall
monorepo-git-pull
deploy-script-monorepo
git-pull-monorepo
monorepo
git
bash
deploy
devops
daily/2026-04-16.md
2026-04-16 2026-04-16

Monorepo Deploy Script — Subdirectory .git Check Pitfall

A deploy script written for a multi-repo setup (separate git repos for backend and frontend) will silently fail to pull new code when the project is converted to a monorepo. The script checks for .git in subdirectories that don't exist in a monorepo, never finds them, skips the git pull, and exits successfully — leaving the server running old code with no warning.

Key Points

  • Silent failure: the script exits 0 even though git pull never ran — nothing in stdout indicates the problem
  • The symptom: running scripts/deploy.sh reports success, but the server is still running the old version
  • Fix: in a monorepo, git pull runs once at the repo root — remove all subdirectory .git checks
  • The warning message (if the script emitted one) is easy to miss in CI/CD output or when tailing logs
  • Multi-repo scripts often check backend/.git and frontend/.git to determine if each component needs to be pulled separately

Details

The Anti-Pattern

# scripts/deploy.sh — written for multi-repo, broken in monorepo

if [ -d "backend/.git" ]; then
    echo "Pulling backend..."
    cd backend && git pull && cd ..
fi

if [ -d "frontend/.git" ]; then
    echo "Pulling frontend..."
    cd frontend && git pull && cd ..
fi

# In a monorepo: neither condition is true → git pull never runs
# Script exits 0 anyway → deploy "succeeds" with stale code

The Fix

# scripts/deploy.sh — monorepo version

set -e
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT_DIR"

echo "Pulling latest code..."
git pull

echo "Rebuilding backend..."
cd backend && pip install -r requirements.txt && cd ..

echo "Rebuilding frontend..."
cd frontend && npm ci && npm run build && cd ..

echo "Restarting services..."
systemctl restart myapp-backend
systemctl reload nginx

One git pull at the root covers all subdirectories in a monorepo.

Detecting the Problem

If a deploy claims success but the running version doesn't match the expected commit:

# On the server — check what commit is actually running
git log -1 --oneline

# Compare with what should be deployed
git fetch origin main
git log -1 --oneline origin/main

If they differ after a "successful" deploy, the deploy script didn't actually pull.

Coexisting Deploy Scripts

Repositories that transitioned from multi-repo to monorepo sometimes have two deploy scripts:

  • full-deploy.sh — the original multi-repo script (potentially still working for other components)
  • scripts/deploy.sh — the active script that was incorrectly carried over

Always identify which script is actually invoked by the CI/CD system or cron job before modifying.

Sources

  • daily/2026-04-16.mdscripts/deploy.sh in Ford QC web app discovered checking backend/.git and frontend/.git; monorepo never matched; fixed to git pull at root