Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 89 additions & 31 deletions bootstrap_docker.sh
Original file line number Diff line number Diff line change
@@ -1,50 +1,108 @@
#!/bin/bash
# This script builds the monorepo projects listed in the build_local script, terminating when it reaches TARGET_PROJECT.
# It performs the build inside a docker image that can launch further docker builds by mapping the users docker daemon
# socket into the container. A kind of simulated "docker-in-docker".
# We copy the monorepo entire working tree into this container, excluding any build output.
# The mechanics of this are, we mount the users repo into the container, then clone it into a directory within the
# container, and also apply modified/untracked/deleted changes to the internal repo.
# The result is we have a fresh copy of the repo, with only the working changes applied, that we can modify as we wish.
#!/usr/bin/env bash
# 🛡️ PORTABILITY: Use 'env bash' for broader OS compatibility.

set -e
# Strict mode: Fail on error, unset variables, and pipe failures.
set -euo pipefail

TARGET_PROJECT="${1:-}"
REPO="aztec3-circuits"

TARGET_PROJECT=$1
REPO=aztec3-circuits
# 🛡️ SAFETY: Get absolute path to the repo root to avoid relative path issues.
REPO_ROOT=$(git rev-parse --show-toplevel)
COMMIT_HASH=$(git rev-parse HEAD)

# If we're calling this script from within a project directory, that's the target project.
# 🔍 LOGIC FIX: Handle project detection safely.
# If TARGET_PROJECT is empty, try to detect it from the current directory context.
if [ -z "$TARGET_PROJECT" ]; then
TARGET_PROJECT=$(git rev-parse --show-prefix)
if [ -n "$TARGET_PROJECT" ]; then
# We are in a project folder.
# Get path relative to repo root
CURRENT_PREFIX=$(git rev-parse --show-prefix)

if [ -n "$CURRENT_PREFIX" ]; then
# We are inside a subdirectory.
ONLY_TARGET=true
TARGET_PROJECT=$(basename $TARGET_PROJECT)
cd $(git rev-parse --show-cdup)
# Remove trailing slash if present and get basename
TARGET_PROJECT=$(basename "${CURRENT_PREFIX%/}")

# 🧹 CLEANUP: Instead of risky 'cd', we just use REPO_ROOT for operations.
echo "Detected target project from directory: $TARGET_PROJECT"
fi
fi

docker build -t $REPO-build - <<EOF
FROM ubuntu:latest
RUN apt update && apt install -y git rsync docker.io
# 🐳 DOCKER SOCKET DISCOVERY
# We need to find where the docker daemon is listening to map it correctly.
DOCKER_SOCK=""
if [ -S "/var/run/docker.sock" ]; then
DOCKER_SOCK="/var/run/docker.sock"
elif [ -S "/run/user/$UID/docker.sock" ]; then
DOCKER_SOCK="/run/user/$UID/docker.sock"
elif [ -n "${DOCKER_HOST:-}" ]; then
# Handle cases where DOCKER_HOST is set (e.g., unix:///...)
DOCKER_SOCK=${DOCKER_HOST#unix://}
fi

if [ -z "$DOCKER_SOCK" ] || [ ! -S "$DOCKER_SOCK" ]; then
echo "Error: Could not locate Docker socket. Please ensure Docker is running."
exit 1
fi

echo "Using Docker socket: $DOCKER_SOCK"

# 🏗️ BUILDER IMAGE
# Pinned Ubuntu version for reproducibility and added apt cleanup to reduce layer noise.
docker build -t "$REPO-build" - <<EOF
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y git rsync docker.io && \
rm -rf /var/lib/apt/lists/*
EOF

docker run -ti --rm -v/run/user/$UID/docker.sock:/var/run/docker.sock -v$(git rev-parse --show-toplevel):/repo:ro $REPO-build /bin/bash -c "
# Checkout head.
mkdir /$REPO
echo "Launching build container..."

# 🚀 EXECUTION
# 1. Map Docker socket (DIND simulation).
# 2. Mount the host repo as read-only to /repo_host (safety first).
# 3. Reconstruct the "dirty" state inside /repo_internal.
docker run -ti --rm \
-v "$DOCKER_SOCK:/var/run/docker.sock" \
-v "$REPO_ROOT:/repo_host:ro" \
"$REPO-build" /bin/bash -c "
set -e

# 1. Initialize a fresh git repo internally
mkdir -p /$REPO
cd /$REPO
git init
git remote add origin /repo
git remote add origin /repo_host

# 2. Fetch specifically the commit we are on (efficient shallow fetch)
git fetch --depth 1 origin $COMMIT_HASH
git checkout FETCH_HEAD

# Copy untracked and modified files, and remove deleted files, from our current repo.
cd /repo
# 3. SYNC: Replicate the 'Working Tree' state
# We rsync uncommitted/modified files from the host mount to the container.
# 'git -C /repo_host' lets us run git commands against the mounted dir.
echo 'Syncing uncommitted changes...'
cd /repo_host
{ git ls-files --others --exclude-standard ; git diff --name-only --diff-filter=TMAR HEAD ; } | rsync -a --files-from=- . /$REPO
for F in \$(git ls-files --deleted); do rm /$REPO/\$F > /dev/null 2>&1; done

# Setup build environment.
source ./build-system/scripts/setup_env $COMMIT_HASH '' mainframe_$USER /repo
# 4. CLEANUP: Remove files that are deleted in the working tree
for F in \$(git ls-files --deleted); do
rm -f /$REPO/\$F
done

# 5. Build Execution
cd /$REPO
echo 'Setting up environment...'
# Ensure the script is executable and exists before sourcing
if [ -f \"./build-system/scripts/setup_env\" ]; then
source ./build-system/scripts/setup_env \"$COMMIT_HASH\" '' \"mainframe_$USER\" /repo_host
else
echo 'Error: setup_env script not found!'
exit 1
fi

build_local $TARGET_PROJECT $ONLY_TARGET
"
echo \"Starting build for: \${TARGET_PROJECT:-ALL}\"
# Call the build function (assumed to be loaded by setup_env)
build_local \"$TARGET_PROJECT\" \"${ONLY_TARGET:-}\"
"