Skip to content
Merged
Show file tree
Hide file tree
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
41 changes: 32 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ RUST_TARGETS ?= wasm32-unknown-unknown
DOCKER_BUILD_EXTRA_ARGS ?=
SKIP_BUILD_NETWORK_CHECK ?= 0

# Forward host proxy env vars to Docker build (BuildKit predefined ARGs —
# available in all stages without Dockerfile ARG declarations, excluded
# from cache key so proxy changes don't bust layer cache).
# Rewrite localhost proxy addresses: 127.0.0.1/localhost on the host is the
# container's own loopback during build — host.docker.internal reaches the
# host. The @-patterns catch authenticated proxies (user:pass@127.0.0.1).
_dproxy = $(subst @localhost,@host.docker.internal,$(subst @127.0.0.1,@host.docker.internal,$(subst ://localhost,://host.docker.internal,$(subst ://127.0.0.1,://host.docker.internal,$1))))
PROXY_BUILD_ARGS := \
$(if $(HTTP_PROXY),--build-arg HTTP_PROXY=$(call _dproxy,$(HTTP_PROXY))) \
$(if $(HTTPS_PROXY),--build-arg HTTPS_PROXY=$(call _dproxy,$(HTTPS_PROXY))) \
$(if $(http_proxy),--build-arg http_proxy=$(call _dproxy,$(http_proxy))) \
$(if $(https_proxy),--build-arg https_proxy=$(call _dproxy,$(https_proxy))) \
Comment on lines +55 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Quote proxy build args to preserve credentials

When a proxied make build uses authenticated proxy URLs containing Make or shell metacharacters, these unquoted expansions corrupt the value before Docker receives it; for example, HTTP_PROXY='http://user:pa$ss@127.0.0.1:7890' make -n build-core renders HTTP_PROXY=http://user:pas@host.docker.internal:7890, and &/; in a password would be interpreted by the shell. This breaks the proxy-aware build path specifically for the authenticated proxies this change is trying to support; the proxy values need to be escaped/quoted before being placed into recipe commands.

Useful? React with 👍 / 👎.

$(if $(NO_PROXY),--build-arg NO_PROXY=$(NO_PROXY)) \
$(if $(no_proxy),--build-arg no_proxy=$(no_proxy))

# host.docker.internal resolves implicitly on Docker Desktop/OrbStack only;
# native Linux Engine needs the explicit host-gateway mapping during build.
ifneq ($(strip $(HTTP_PROXY)$(HTTPS_PROXY)$(http_proxy)$(https_proxy)),)
PROXY_BUILD_ARGS += --add-host host.docker.internal:host-gateway
endif

DOCKER_BUILD_FLAGS = $(PROXY_BUILD_ARGS) $(DOCKER_BUILD_EXTRA_ARGS)

TOOLCHAIN_BUILD_ARGS := \
--build-arg NODE_MAJOR=$(NODE_MAJOR) \
--build-arg GO_VERSION=$(GO_VERSION) \
Expand Down Expand Up @@ -112,7 +135,7 @@ build-network-check:
printf '%s\n' \
'FROM node:$(NODE_MAJOR)-bookworm-slim' \
'RUN node -e "require('\''dns'\'').lookup('\''registry.npmjs.org'\'',{all:true},(e,a)=>{if(e){console.error(e);process.exit(1)};console.log(a.map(x=>x.address).slice(0,3).join('\'','\''))})"' \
| docker build $(DOCKER_BUILD_EXTRA_ARGS) --progress=plain --no-cache -f - . >/dev/null; \
| docker build $(DOCKER_BUILD_FLAGS) --progress=plain --no-cache -f - . >/dev/null; \
fi

build-main: build-network-check
Expand Down Expand Up @@ -159,23 +182,23 @@ build-main: build-network-check
fi; \
fi
@echo "Hint: override via GO_VERSION=... CLAUDE_CODE_VERSION=... or run 'make versions-pin'"
docker build $(DOCKER_BUILD_EXTRA_ARGS) -f $(DOCKERFILE) $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
docker build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
@echo "✅ Build completed: $(MAIN_IMAGE)"

rebuild:
@echo "🔨 Rebuilding Docker image (no cache) with $(DOCKERFILE)..."
docker build $(DOCKER_BUILD_EXTRA_ARGS) -f $(DOCKERFILE) --no-cache $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
docker build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) --no-cache $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
@echo "✅ Rebuild completed: $(MAIN_IMAGE)"


build-core:
@echo "🔨 Building stable core image..."
docker build $(DOCKER_BUILD_EXTRA_ARGS) -f $(DOCKERFILE) --target agent-base $(CORE_BUILD_ARGS) -t $(CORE_IMAGE) .
docker build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) --target agent-base $(CORE_BUILD_ARGS) -t $(CORE_IMAGE) .
@echo "✅ Core build completed: $(CORE_IMAGE)"

build-rust-image: build-network-check
@echo "🔨 Building Rust Docker image..."
docker build $(DOCKER_BUILD_EXTRA_ARGS) -f $(RUST_DOCKERFILE) \
docker build $(DOCKER_BUILD_FLAGS) -f $(RUST_DOCKERFILE) \
--build-arg BASE_IMAGE=$(CORE_IMAGE) \
$(RUST_BUILD_ARGS) \
-t $(RUST_IMAGE) .
Expand All @@ -192,27 +215,27 @@ build-all:

buildx:
@echo "🔨 Building with docker buildx..."
docker buildx build -f $(DOCKERFILE) --load $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
docker buildx build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) --load $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
@echo "✅ Buildx completed: $(MAIN_IMAGE)"

buildx-multi:
@echo "🔨 Building multi-arch images for amd64 and arm64..."
docker buildx build -f $(DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
docker buildx build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
$(MAIN_BUILD_ARGS) \
--push -t $(MAIN_IMAGE) .
@echo "✅ Multi-arch build completed and pushed: $(MAIN_IMAGE)"

buildx-multi-rust:
@echo "🔨 Building multi-arch Rust images for amd64 and arm64..."
docker buildx build -f $(RUST_DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
docker buildx build $(DOCKER_BUILD_FLAGS) -f $(RUST_DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
--build-arg BASE_IMAGE=$(MAIN_IMAGE) \
$(RUST_BUILD_ARGS) \
--push -t $(RUST_IMAGE) .
@echo "✅ Multi-arch Rust build completed and pushed: $(RUST_IMAGE)"

buildx-multi-local:
@echo "🔨 Building multi-arch images locally..."
docker buildx build -f $(DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
docker buildx build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) --platform $(MULTI_ARCH_PLATFORMS) \
$(MAIN_BUILD_ARGS) \
-t $(MAIN_IMAGE) .
@echo "✅ Multi-arch build completed locally: $(MAIN_IMAGE)"
Expand Down
17 changes: 17 additions & 0 deletions scripts/install-agent-tooling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,25 @@ download_to() {
curl -fsSL "$url" -o "$dest"
}

log_proxy_config() {
# Proxy userinfo is credential material and this output lands in build
# logs — redact user:pass@ before printing.
local has_proxy=0
for var in HTTP_PROXY HTTPS_PROXY http_proxy https_proxy NO_PROXY no_proxy; do
if [ -n "${!var:-}" ]; then
log " $var=$(printf '%s' "${!var}" | sed -E 's#://[^@/]*@#://***@#')"
has_proxy=1
fi
done
if [ "$has_proxy" -eq 0 ]; then
log " (no proxy configured)"
fi
}

install_npm_agent_tooling() {
log "Installing npm agent tooling"
log "Proxy config:"
log_proxy_config
log "Requested versions: claude=${CLAUDE_CODE_VERSION} codex=${CODEX_VERSION} gemini=${GEMINI_CLI_VERSION} grok=${GROK_CLI_VERSION}"

mkdir -p "$DEVA_HOME/.npm-global" "$DEVA_HOME/.local/bin"
Expand Down
16 changes: 13 additions & 3 deletions scripts/release-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,23 @@ format_datetime() {
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Version Fetching (by type)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
_npm_registry_latest() {
curl -fsSL --max-time 10 \
"https://registry.npmjs.org/-/package/$1/dist-tags" 2>/dev/null | \
sed -n 's/.*"latest":"\([^"]*\)".*/\1/p'
}

fetch_latest_version() {
local tool=$1
local type=$(get_tool_field "$tool" type)
local source=$(get_tool_field "$tool" source)

case $type in
npm)
npm view "$source" version 2>/dev/null || echo ""
# Soft-fail like the gh arms below: a transient registry error
# must reach load_versions' warn-and-fallback path, not abort
# the whole run under set -e.
_npm_registry_latest "$source" || echo ""
;;
github-release)
gh api "repos/$source/releases/latest" --jq '.tag_name' 2>/dev/null || echo ""
Expand All @@ -203,8 +212,9 @@ fetch_version_date() {
case $type in
npm)
local v=$(normalize_version "$version")
npm view "$source@$v" time --json 2>/dev/null | \
jq -r --arg ver "$v" '.[$ver] // .' 2>/dev/null | head -1 || echo ""
local encoded=${source/\//%2f}
curl -fsSL --max-time 10 "https://registry.npmjs.org/$encoded" 2>/dev/null | \
jq -r --arg ver "$v" '.time[$ver] // empty' 2>/dev/null | head -1 || echo ""
;;
github-release)
gh api "repos/$source/releases/tags/$version" --jq '.published_at' 2>/dev/null || echo ""
Expand Down
4 changes: 3 additions & 1 deletion scripts/update-version-pins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ EOF
}

fetch_npm_version() {
npm view "$1" version 2>/dev/null || true
curl -fsSL --max-time 10 \
"https://registry.npmjs.org/-/package/$1/dist-tags" 2>/dev/null | \
sed -n 's/.*"latest":"\([^"]*\)".*/\1/p' || true
}

fetch_latest_git_tag() {
Expand Down
29 changes: 29 additions & 0 deletions scripts/version-upgrade.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ source "$SCRIPT_DIR/version-pins.sh"
CHECK_IMAGE=${MAIN_IMAGE:-ghcr.io/thevibeworks/deva:latest}
BUILD_IMAGE=${BUILD_IMAGE:-ghcr.io/thevibeworks/deva:latest}
CORE_IMAGE=${CORE_IMAGE:-ghcr.io/thevibeworks/deva:core}

# Forward host proxy env vars to Docker build stages.
# Rewrite 127.0.0.1/localhost → host.docker.internal so the build
# container reaches the host's proxy instead of its own loopback.
# The @-patterns catch authenticated proxies (user:pass@127.0.0.1).
_dproxy() { sed 's|://127\.0\.0\.1|://host.docker.internal|g; s|://localhost|://host.docker.internal|g; s|@127\.0\.0\.1|@host.docker.internal|g; s|@localhost|@host.docker.internal|g' <<< "$1"; }
# Proxy userinfo is credential material — never print it raw.
_redact_proxy() { sed -E 's#://[^@/]*@#://***@#' <<< "$1"; }
PROXY_ARGS=()
[[ -n ${HTTP_PROXY:-} ]] && PROXY_ARGS+=(--build-arg "HTTP_PROXY=$(_dproxy "$HTTP_PROXY")")
[[ -n ${HTTPS_PROXY:-} ]] && PROXY_ARGS+=(--build-arg "HTTPS_PROXY=$(_dproxy "$HTTPS_PROXY")")
[[ -n ${http_proxy:-} ]] && PROXY_ARGS+=(--build-arg "http_proxy=$(_dproxy "$http_proxy")")
[[ -n ${https_proxy:-} ]] && PROXY_ARGS+=(--build-arg "https_proxy=$(_dproxy "$https_proxy")")
[[ -n ${NO_PROXY:-} ]] && PROXY_ARGS+=(--build-arg "NO_PROXY=$NO_PROXY")
[[ -n ${no_proxy:-} ]] && PROXY_ARGS+=(--build-arg "no_proxy=$no_proxy")
# host.docker.internal resolves implicitly on Docker Desktop/OrbStack only;
# native Linux Engine needs the explicit host-gateway mapping during build.
[[ ${#PROXY_ARGS[@]} -gt 0 ]] && PROXY_ARGS+=(--add-host "host.docker.internal:host-gateway")
RUST_IMAGE=${RUST_IMAGE:-ghcr.io/thevibeworks/deva:rust}
DOCKERFILE=${DOCKERFILE:-Dockerfile}
RUST_DOCKERFILE=${RUST_DOCKERFILE:-Dockerfile.rust}
Expand Down Expand Up @@ -200,8 +218,17 @@ main() {
echo -e "${GREEN}Proceeding with build...${RESET}"
echo ""

if [[ ${#PROXY_ARGS[@]} -gt 0 ]]; then
echo -e "${DIM}Proxy forwarding to Docker build:${RESET}"
for _pa in "${PROXY_ARGS[@]}"; do
echo -e " ${DIM}$(_redact_proxy "${_pa#--build-arg }")${RESET}"
done
Comment on lines +223 to +225
echo ""
fi

section "Building Core Image"
docker build -f "$DOCKERFILE" \
${PROXY_ARGS[@]+"${PROXY_ARGS[@]}"} \
--target agent-base \
--build-arg NODE_MAJOR="$NODE_MAJOR" \
--build-arg GO_VERSION="$GO_VERSION" \
Expand All @@ -215,6 +242,7 @@ main() {
echo ""
section "Building Main Image"
docker build -f "$DOCKERFILE" \
${PROXY_ARGS[@]+"${PROXY_ARGS[@]}"} \
--build-arg NODE_MAJOR="$NODE_MAJOR" \
--build-arg GO_VERSION="$GO_VERSION" \
--build-arg PYTHON_VERSION="$PYTHON_VERSION" \
Expand All @@ -233,6 +261,7 @@ main() {
echo ""
section "Building Rust Image"
docker build -f "$RUST_DOCKERFILE" \
${PROXY_ARGS[@]+"${PROXY_ARGS[@]}"} \
--build-arg BASE_IMAGE="$CORE_IMAGE" \
--build-arg CLAUDE_CODE_VERSION="$claude_ver" \
--build-arg CCTRACE_VERSION="$cctrace_ver" \
Expand Down
Loading
Loading