feat(workflows): add docker-smoke-test, audit-repo-health, verify-all-backends
- /docker-smoke-test: prep, build, verify all Dockerfiles in a repo - /audit-repo-health: cross-repo pnpm/Docker/config consistency audit - /verify-all-backends: quick local typecheck+test+build (complement to /gitea-ci)
This commit is contained in:
parent
0ffbdce0ef
commit
1d2003a30f
268
.windsurf/workflows/audit-repo-health.md
Normal file
268
.windsurf/workflows/audit-repo-health.md
Normal file
@ -0,0 +1,268 @@
|
||||
---
|
||||
description: Cross-repo health audit — verify pnpm config, Dockerfiles, next.config.ts, and workspace consistency
|
||||
---
|
||||
|
||||
# Cross-Repo Health Audit
|
||||
|
||||
Systematically verify consistency across all ByteLyst product repos. Catches drift in pnpm config, Dockerfiles, next.config.ts, and workspace setup.
|
||||
|
||||
**Run this after:** pnpm migrations, Dockerfile changes, @bytelyst/\* package additions, or periodic maintenance.
|
||||
|
||||
## 1. Check packageManager field in all root package.json files
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== packageManager in root package.json ==="
|
||||
for repo in \
|
||||
learning_ai_common_plat \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
printf "%-40s " "$repo:"
|
||||
grep '"packageManager"' "$REPOS_DIR/$repo/package.json" 2>/dev/null || echo "MISSING"
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all repos show `"packageManager": "pnpm@10.6.5"`. Fix any MISSING entries.
|
||||
|
||||
## 2. Check node_modules in .gitignore
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== node_modules in .gitignore ==="
|
||||
for repo in \
|
||||
learning_ai_common_plat \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
printf "%-40s " "$repo:"
|
||||
grep -c 'node_modules' "$REPOS_DIR/$repo/.gitignore" 2>/dev/null || echo "MISSING"
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all repos have at least 1 match. Fix any with 0 or MISSING.
|
||||
|
||||
## 3. Check .dockerignore exists and does NOT exclude .docker-deps
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== .dockerignore health ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
di="$REPOS_DIR/$repo/.dockerignore"
|
||||
if [ ! -f "$di" ]; then
|
||||
echo "$repo: MISSING .dockerignore"
|
||||
elif grep -q 'docker-deps' "$di"; then
|
||||
echo "$repo: BUG — .dockerignore excludes .docker-deps"
|
||||
else
|
||||
echo "$repo: OK"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all OK. Any BUG entries will break Docker builds.
|
||||
|
||||
## 4. Check stale package-lock.json files
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== Stale package-lock.json ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
found=$(find "$REPOS_DIR/$repo" -name "package-lock.json" -not -path "*/node_modules/*" 2>/dev/null)
|
||||
if [ -n "$found" ]; then echo "STALE: $found"; fi
|
||||
done
|
||||
echo "(empty = all clean)"
|
||||
```
|
||||
|
||||
Expect: no output. Remove any stale lockfiles found.
|
||||
|
||||
## 5. Check Dockerfiles use node:22-slim and have NODE_TLS
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== Dockerfile base image + NODE_TLS ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
for df in $(git -C "$REPOS_DIR/$repo" ls-files '*/Dockerfile' 2>/dev/null); do
|
||||
full="$REPOS_DIR/$repo/$df"
|
||||
base=$(grep -m1 '^FROM' "$full" | awk '{print $2}')
|
||||
tls=$(grep -c 'NODE_TLS_REJECT_UNAUTHORIZED' "$full" 2>/dev/null)
|
||||
status="OK"
|
||||
[[ "$base" == *alpine* ]] && status="WARN:alpine"
|
||||
[[ "$tls" == "0" && "$df" != *python* ]] && status="$status WARN:no-NODE_TLS"
|
||||
echo "$repo/$df: base=$base tls=$tls $status"
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all use `node:22-slim`, all have `NODE_TLS` refs > 0. Fix any WARN entries.
|
||||
|
||||
## 6. Check next.config.ts has transpilePackages + symlinks
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== next.config.ts: transpilePackages + symlinks ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_notes \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
for cfg in $(find "$REPOS_DIR/$repo" -maxdepth 2 -name "next.config.ts" -not -path "*/node_modules/*" 2>/dev/null); do
|
||||
relpath="${cfg#$REPOS_DIR/}"
|
||||
tp=$(grep -c 'transpilePackages' "$cfg")
|
||||
sl=$(grep -c 'symlinks' "$cfg")
|
||||
status="OK"
|
||||
[[ "$tp" == "0" ]] && status="MISSING:transpilePackages"
|
||||
[[ "$sl" == "0" ]] && status="$status MISSING:symlinks"
|
||||
echo "$relpath: transpile=$tp symlinks=$sl $status"
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all show transpile>0 and symlinks>0. Fix any MISSING entries.
|
||||
|
||||
## 7. Check pnpm-workspace.yaml includes common-plat packages
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== pnpm-workspace.yaml includes common-plat ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
ws="$REPOS_DIR/$repo/pnpm-workspace.yaml"
|
||||
if [ ! -f "$ws" ]; then
|
||||
echo "$repo: MISSING pnpm-workspace.yaml"
|
||||
elif grep -q 'common_plat' "$ws"; then
|
||||
echo "$repo: OK"
|
||||
else
|
||||
echo "$repo: MISSING common-plat in workspace"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all OK. Fix any MISSING entries.
|
||||
|
||||
## 8. Check docker-prep.sh uses shared prep-consumer
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== docker-prep.sh uses shared prep-consumer ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
script="$REPOS_DIR/$repo/scripts/docker-prep.sh"
|
||||
if [ ! -f "$script" ]; then
|
||||
echo "$repo: NO docker-prep.sh"
|
||||
elif grep -q 'prep-consumer' "$script"; then
|
||||
echo "$repo: OK (shared wrapper)"
|
||||
else
|
||||
echo "$repo: WARN — legacy docker-prep.sh"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Expect: all OK. Legacy scripts should be replaced with the shared wrapper.
|
||||
|
||||
## 9. Check verify scripts reference correct package filter names
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
echo "=== Root verify scripts ==="
|
||||
for repo in \
|
||||
learning_voice_ai_agent \
|
||||
learning_ai_clock \
|
||||
learning_ai_fastgap \
|
||||
learning_ai_jarvis_jr \
|
||||
learning_ai_peakpulse \
|
||||
learning_ai_notes \
|
||||
learning_ai_flowmonk \
|
||||
learning_ai_trails \
|
||||
learning_ai_local_memory_gpt; do
|
||||
printf "%-40s " "$repo:"
|
||||
node -e "const p=require('$REPOS_DIR/$repo/package.json'); console.log(p.scripts?.verify || 'NONE')" 2>/dev/null
|
||||
done
|
||||
```
|
||||
|
||||
Review output manually — ensure `--filter` names match actual package names in sub-packages.
|
||||
|
||||
## 10. Summarize findings and fix
|
||||
|
||||
For each issue found:
|
||||
|
||||
1. Fix the file in the affected repo
|
||||
2. Commit with message: `fix(repo): <description of fix>`
|
||||
3. Push to origin
|
||||
|
||||
Run `/gitea-ci` after all fixes to verify full CI passes.
|
||||
69
.windsurf/workflows/docker-smoke-test.md
Normal file
69
.windsurf/workflows/docker-smoke-test.md
Normal file
@ -0,0 +1,69 @@
|
||||
---
|
||||
description: Docker smoke test — prep, build, and verify all Dockerfiles in the current repo
|
||||
---
|
||||
|
||||
# Docker Smoke Test
|
||||
|
||||
Build and verify all Dockerfiles in the current product repo. Runs docker-prep, builds each image, then restores package.json files.
|
||||
|
||||
**Prerequisite:** Docker Desktop must be running. The current repo must have `scripts/docker-prep.sh`.
|
||||
|
||||
## 1. Identify the repo and its Dockerfiles
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
REPO_DIR="$(pwd)"
|
||||
REPO_NAME="$(basename "$REPO_DIR")"
|
||||
echo "Repo: $REPO_NAME"
|
||||
echo "Dockerfiles:"
|
||||
find "$REPO_DIR" -maxdepth 2 -name "Dockerfile" -not -path "*/node_modules/*" | sort
|
||||
```
|
||||
|
||||
## 2. Run docker-prep to pack @bytelyst/\* tarballs
|
||||
|
||||
```bash
|
||||
bash scripts/docker-prep.sh
|
||||
```
|
||||
|
||||
## 3. Build each Dockerfile
|
||||
|
||||
Build each Dockerfile found in the repo. The build context is always the repo root (`.`).
|
||||
Tag images as `<service>:smoke-test` for easy cleanup.
|
||||
|
||||
For each Dockerfile found in step 1, run:
|
||||
|
||||
```bash
|
||||
# Example for backend:
|
||||
docker build -f backend/Dockerfile -t "$(basename $(pwd))-backend:smoke-test" . 2>&1 | tail -20
|
||||
|
||||
# Example for web:
|
||||
docker build -f web/Dockerfile -t "$(basename $(pwd))-web:smoke-test" . 2>&1 | tail -20
|
||||
```
|
||||
|
||||
Adapt the `-f` path based on actual Dockerfile locations from step 1.
|
||||
If a build fails, stop and investigate the error before continuing.
|
||||
|
||||
## 4. Restore package.json files
|
||||
|
||||
```bash
|
||||
bash scripts/docker-prep.sh --restore
|
||||
```
|
||||
|
||||
## 5. Report results
|
||||
|
||||
Summarize which images built successfully and which failed.
|
||||
If all passed, the repo's Docker setup is healthy.
|
||||
|
||||
## 6. (Optional) Cleanup smoke-test images
|
||||
|
||||
```bash
|
||||
docker images --filter "reference=*:smoke-test" --format "{{.Repository}}:{{.Tag}}" | xargs -r docker rmi
|
||||
```
|
||||
|
||||
## Common Failures
|
||||
|
||||
- **`.docker-deps` not found:** Run step 2 first, and ensure `.dockerignore` does NOT exclude `.docker-deps`
|
||||
- **Google Fonts / TLS error:** Ensure `ENV NODE_TLS_REJECT_UNAUTHORIZED=0` is in the builder stage
|
||||
- **Native module build failure:** Add `python3 make g++` to `RUN apt-get install` in the builder stage
|
||||
- **`public/` not found:** Remove the `COPY public` line if the web app has no `public/` directory
|
||||
110
.windsurf/workflows/verify-all-backends.md
Normal file
110
.windsurf/workflows/verify-all-backends.md
Normal file
@ -0,0 +1,110 @@
|
||||
---
|
||||
description: Quick local typecheck + test + build across all product backends (fast complement to /gitea-ci)
|
||||
---
|
||||
|
||||
# Verify All Backends (Local)
|
||||
|
||||
Run typecheck, test, and build across all product backends locally — without needing Gitea.
|
||||
Use this for fast pre-push validation. For full CI verification, use `/gitea-ci` instead.
|
||||
|
||||
**When to use:**
|
||||
|
||||
- After modifying a `@bytelyst/*` shared package
|
||||
- Before a bulk push to all repos
|
||||
- Quick health check without waiting for Gitea runner queue
|
||||
|
||||
## 1. Build common-plat packages first (dependency for all backends)
|
||||
|
||||
```bash
|
||||
cd /Users/sd9235/code/mygh/learning_ai_common_plat && pnpm build
|
||||
```
|
||||
|
||||
## 2. Verify all product backends
|
||||
|
||||
Run typecheck + test + build for each backend. Stops on first failure.
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
FAILURES=""
|
||||
|
||||
for entry in \
|
||||
"learning_ai_notes:@notelett/backend" \
|
||||
"learning_ai_local_memory_gpt:@localmemgpt/backend" \
|
||||
"learning_ai_trails:@actiontrail/backend" \
|
||||
"learning_ai_fastgap:@nomgap/backend" \
|
||||
"learning_ai_clock:@chronomind/backend" \
|
||||
"learning_ai_jarvis_jr:@jarvisjr/backend" \
|
||||
"learning_ai_peakpulse:@peakpulse/backend" \
|
||||
"learning_voice_ai_agent:@lysnrai/backend" \
|
||||
"learning_ai_flowmonk:@flowmonk/backend" \
|
||||
"learning_ai_notes:@notelett/backend"; do
|
||||
|
||||
repo="${entry%%:*}"
|
||||
filter="${entry##*:}"
|
||||
echo ""
|
||||
echo "━━━ $repo ($filter) ━━━"
|
||||
|
||||
cd "$REPOS_DIR/$repo"
|
||||
if pnpm --filter "$filter" run typecheck 2>&1 | tail -3 && \
|
||||
pnpm --filter "$filter" run test 2>&1 | tail -5 && \
|
||||
pnpm --filter "$filter" run build 2>&1 | tail -3; then
|
||||
echo "✅ $repo PASSED"
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo "❌ $repo FAILED"
|
||||
FAILED=$((FAILED + 1))
|
||||
FAILURES="$FAILURES\n - $repo"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Passed: $PASSED"
|
||||
echo "❌ Failed: $FAILED"
|
||||
if [ -n "$FAILURES" ]; then
|
||||
echo -e "Failures:$FAILURES"
|
||||
fi
|
||||
```
|
||||
|
||||
## 3. (Optional) Verify all web apps too
|
||||
|
||||
Web builds take longer. Only run if you suspect web-side breakage.
|
||||
|
||||
```bash
|
||||
REPOS_DIR="/Users/sd9235/code/mygh"
|
||||
|
||||
for entry in \
|
||||
"learning_ai_notes:@notelett/web" \
|
||||
"learning_ai_local_memory_gpt:@localmemgpt/web" \
|
||||
"learning_ai_trails:@actiontrail/web" \
|
||||
"learning_ai_fastgap:@nomgap/web" \
|
||||
"learning_ai_clock:web" \
|
||||
"learning_ai_jarvis_jr:jarvisjr-web" \
|
||||
"learning_voice_ai_agent:user-dashboard-web" \
|
||||
"learning_ai_flowmonk:@flowmonk/web"; do
|
||||
|
||||
repo="${entry%%:*}"
|
||||
filter="${entry##*:}"
|
||||
echo ""
|
||||
echo "━━━ $repo web ($filter) ━━━"
|
||||
|
||||
cd "$REPOS_DIR/$repo"
|
||||
if pnpm --filter "$filter" run typecheck 2>&1 | tail -3 && \
|
||||
pnpm --filter "$filter" run build 2>&1 | tail -5; then
|
||||
echo "✅ $repo web PASSED"
|
||||
else
|
||||
echo "❌ $repo web FAILED"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
## 4. After fixing issues
|
||||
|
||||
If any backend/web failed:
|
||||
|
||||
1. Fix the issue in the affected repo
|
||||
2. Re-run the failing step only to confirm
|
||||
3. Commit with: `fix(scope): description`
|
||||
4. Run `/gitea-ci` for full CI verification
|
||||
Loading…
Reference in New Issue
Block a user