learning_ai_notes/scripts/docker-prep.sh
saravanakumardb1 b2d824c8c6 fix(workspace): canonicalize common-plat path to ../learning_ai_common_plat
Restores green build after the May 12 Docker/UI regression.

Root cause: pnpm-workspace.yaml referenced a sibling path
(../learning_ai/learning_ai_common_plat/...) that did not exist on
dev/CI hosts. .pnpmfile.cjs fell back to ../learning_ai_common_plat for
some packages but missed others, so @bytelyst/ui was pulled from a
stale Gitea 0.1.0 tarball with zero exports (breaking web typecheck +
26 tests) and @bytelyst/monitoring was never linked into node_modules
(breaking backend typecheck + 2 test suites).

Changes:
- pnpm-workspace.yaml now references ../learning_ai_common_plat/packages/* directly
- .pnpmfile.cjs swaps DEFAULT/LEGACY common-plat roots so the canonical
  path is the default and the older nested path is the fallback
- scripts/docker-prep.sh, scripts/local-smoke.sh, scripts/release-guard-audit.sh
  follow the same canonical-first / legacy-fallback pattern
- .github/workflows/ci.yml symlinks directly to ../learning_ai_common_plat
- pnpm-lock.yaml regenerated with @bytelyst/ui@0.1.9 and
  @bytelyst/monitoring@0.1.5 linked to the local common-plat checkout

Verified:
- pnpm run verify: backend 373/373, web 96/96, mobile 97/97
- pnpm run audit:release-guards: passes
- backend, web, mobile lint all exit 0 (advisory warnings retained)
2026-05-22 15:08:30 -07:00

147 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Pack @bytelyst/* tarballs from the sibling common-plat repo for
# self-contained Docker builds that don't need the Gitea npm registry.
#
# Usage:
# ./scripts/docker-prep.sh # pack tarballs + rewrite package.json
# ./scripts/docker-prep.sh --restore # undo rewrite
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
COMMON_PLAT="${COMMON_PLAT:-${REPO_DIR}/../learning_ai_common_plat}"
if [[ ! -d "$COMMON_PLAT" && -d "${REPO_DIR}/../learning_ai/learning_ai_common_plat" ]]; then
COMMON_PLAT="${REPO_DIR}/../learning_ai/learning_ai_common_plat"
fi
TARBALL_DIR="${REPO_DIR}/.docker-deps"
# ── Restore mode ───────────────────────────────────────────────────
if [[ "${1:-}" == "--restore" ]]; then
echo "Restoring original package.json files..."
for bak in $(find "$REPO_DIR" -name "package.json.bak" -not -path "*/node_modules/*"); do
mv "$bak" "${bak%.bak}"
echo " Restored ${bak%.bak}"
done
rm -rf "$TARBALL_DIR"
echo "Done."
exit 0
fi
# ── Pack mode ──────────────────────────────────────────────────────
if [[ ! -d "$COMMON_PLAT" ]]; then
echo "Common platform checkout not found: $COMMON_PLAT" >&2
echo "Set COMMON_PLAT=/path/to/learning_ai_common_plat or place it at ../learning_ai/learning_ai_common_plat." >&2
exit 1
fi
echo "=== docker-prep: packing @bytelyst/* tarballs ==="
rm -rf "$TARBALL_DIR"
mkdir -p "$TARBALL_DIR"
# Build all packages first (--filter limits to packages/, skips services/)
echo "Building @bytelyst/* packages..."
(cd "$COMMON_PLAT" && pnpm -r --filter './packages/*' build)
# Pack each package and build a mapping of name → tarball filename
# (uses a temp file instead of associative array for bash 3.2 compat)
TARBALL_MAP_FILE=$(mktemp)
trap 'rm -f "$TARBALL_MAP_FILE"' EXIT
for pkg_dir in "$COMMON_PLAT"/packages/*/; do
pkg_name=$(node -p "require('${pkg_dir}package.json').name" 2>/dev/null || true)
if [[ -z "$pkg_name" ]]; then continue; fi
echo " Packing $pkg_name..."
tarball=$(cd "$pkg_dir" && pnpm pack --pack-destination "$TARBALL_DIR" 2>/dev/null | tail -1)
filename=$(basename "$tarball")
echo "${pkg_name}=${filename}" >> "$TARBALL_MAP_FILE"
echo " -> $filename"
done
# ── Rewrite package.json files ─────────────────────────────────────
echo ""
echo "Rewriting package.json @bytelyst/* refs to .docker-deps/ tarballs..."
rewrite_package_json() {
local pkg_file="$1"
local rel_prefix="$2" # relative path from package.json dir to repo root
if [[ ! -f "$pkg_file" ]]; then return; fi
# Backup
cp "$pkg_file" "${pkg_file}.bak"
local tmp="${pkg_file}.tmp"
cp "$pkg_file" "$tmp"
while IFS='=' read -r pkg_name tarball; do
[[ -z "$pkg_name" ]] && continue
node -e "
const fs = require('fs');
const file = process.argv[1];
const pkgName = process.argv[2];
const replacement = process.argv[3];
const p = JSON.parse(fs.readFileSync(file, 'utf8'));
for (const section of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
if (p[section] && Object.prototype.hasOwnProperty.call(p[section], pkgName)) {
p[section][pkgName] = replacement;
}
}
fs.writeFileSync(file, JSON.stringify(p, null, 2) + '\n');
" "$tmp" "$pkg_name" "file:${rel_prefix}.docker-deps/${tarball}"
done < "$TARBALL_MAP_FILE"
mv "$tmp" "$pkg_file"
echo " Rewrote $pkg_file"
}
# Backend package.json
rewrite_package_json "${REPO_DIR}/backend/package.json" "../"
# Web package.json
rewrite_package_json "${REPO_DIR}/web/package.json" "../"
# ── Inject pnpm.overrides for transitive @bytelyst/* deps ─────────
# Tarball packages may depend on other @bytelyst/* packages (e.g.
# @bytelyst/fastify-core → @bytelyst/errors). Without overrides, pnpm
# tries to fetch them from the npm registry which fails.
inject_overrides() {
local pkg_file="$1"
local rel_prefix="$2"
if [[ ! -f "$pkg_file" ]]; then return; fi
local overrides=""
while IFS='=' read -r pkg_name tarball; do
[[ -z "$pkg_name" ]] && continue
if [[ -n "$overrides" ]]; then overrides="$overrides, "; fi
overrides="$overrides\"${pkg_name}\": \"file:${rel_prefix}.docker-deps/${tarball}\""
done < "$TARBALL_MAP_FILE"
if [[ -n "$overrides" ]]; then
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('${pkg_file}', 'utf8'));
p.pnpm = p.pnpm || {};
p.pnpm.overrides = { ...(p.pnpm.overrides || {}), ...JSON.parse('{${overrides}}') };
fs.writeFileSync('${pkg_file}', JSON.stringify(p, null, 2) + '\n');
"
echo " Injected pnpm.overrides into $pkg_file"
fi
}
inject_overrides "${REPO_DIR}/backend/package.json" "../"
inject_overrides "${REPO_DIR}/web/package.json" "../"
echo ""
echo "Done. Tarballs in $TARBALL_DIR"
echo ""
echo "To build Docker images:"
echo " docker compose build"
echo ""
echo "To restore after build:"
echo " ./scripts/docker-prep.sh --restore"