|
#!/bin/bash
|
|
set -eo pipefail
|
|
|
|
|
|
image_name=""
|
|
org_name=""
|
|
push=0
|
|
load=0
|
|
tag_suffix=""
|
|
|
|
|
|
usage() {
|
|
echo "Usage: $0 -i <image_name> [-o <org_name>] [--push] [--load] [-t <tag_suffix>]"
|
|
echo " -i: Image name (required)"
|
|
echo " -o: Organization name"
|
|
echo " --push: Push the image"
|
|
echo " --load: Load the image"
|
|
echo " -t: Tag suffix"
|
|
exit 1
|
|
}
|
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-i) image_name="$2"; shift 2 ;;
|
|
-o) org_name="$2"; shift 2 ;;
|
|
--push) push=1; shift ;;
|
|
--load) load=1; shift ;;
|
|
-t) tag_suffix="$2"; shift 2 ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$image_name" ]]; then
|
|
echo "Error: Image name is required."
|
|
usage
|
|
fi
|
|
|
|
echo "Building: $image_name"
|
|
tags=()
|
|
|
|
OPENHANDS_BUILD_VERSION="dev"
|
|
|
|
cache_tag_base="buildcache"
|
|
cache_tag="$cache_tag_base"
|
|
|
|
if [[ -n $RELEVANT_SHA ]]; then
|
|
git_hash=$(git rev-parse --short "$RELEVANT_SHA")
|
|
tags+=("$git_hash")
|
|
tags+=("$RELEVANT_SHA")
|
|
fi
|
|
|
|
if [[ -n $GITHUB_REF_NAME ]]; then
|
|
|
|
if [[ $GITHUB_REF_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
major_version=$(echo "$GITHUB_REF_NAME" | cut -d. -f1)
|
|
minor_version=$(echo "$GITHUB_REF_NAME" | cut -d. -f1,2)
|
|
tags+=("$major_version" "$minor_version")
|
|
tags+=("latest")
|
|
fi
|
|
sanitized_ref_name=$(echo "$GITHUB_REF_NAME" | sed 's/[^a-zA-Z0-9.-]\+/-/g')
|
|
OPENHANDS_BUILD_VERSION=$sanitized_ref_name
|
|
sanitized_ref_name=$(echo "$sanitized_ref_name" | tr '[:upper:]' '[:lower:]')
|
|
tags+=("$sanitized_ref_name")
|
|
cache_tag+="-${sanitized_ref_name}"
|
|
fi
|
|
|
|
if [[ -n $tag_suffix ]]; then
|
|
cache_tag+="-${tag_suffix}"
|
|
for i in "${!tags[@]}"; do
|
|
tags[$i]="${tags[$i]}-$tag_suffix"
|
|
done
|
|
fi
|
|
|
|
echo "Tags: ${tags[@]}"
|
|
|
|
if [[ "$image_name" == "openhands" ]]; then
|
|
dir="./containers/app"
|
|
elif [[ "$image_name" == "runtime" ]]; then
|
|
dir="./containers/runtime"
|
|
else
|
|
dir="./containers/$image_name"
|
|
fi
|
|
|
|
if [[ (! -f "$dir/Dockerfile") && "$image_name" != "runtime" ]]; then
|
|
|
|
echo "No Dockerfile found"
|
|
exit 1
|
|
fi
|
|
if [[ ! -f "$dir/config.sh" ]]; then
|
|
echo "No config.sh found for Dockerfile"
|
|
exit 1
|
|
fi
|
|
|
|
source "$dir/config.sh"
|
|
|
|
if [[ -n "$org_name" ]]; then
|
|
DOCKER_ORG="$org_name"
|
|
fi
|
|
|
|
|
|
if [[ -n "$DOCKER_IMAGE_SOURCE_TAG" ]]; then
|
|
tags+=("$DOCKER_IMAGE_SOURCE_TAG")
|
|
fi
|
|
|
|
if [[ -n "$DOCKER_IMAGE_TAG" ]]; then
|
|
tags+=("$DOCKER_IMAGE_TAG")
|
|
fi
|
|
|
|
DOCKER_REPOSITORY="$DOCKER_REGISTRY/$DOCKER_ORG/$DOCKER_IMAGE"
|
|
DOCKER_REPOSITORY=${DOCKER_REPOSITORY,,}
|
|
echo "Repo: $DOCKER_REPOSITORY"
|
|
echo "Base dir: $DOCKER_BASE_DIR"
|
|
|
|
args=""
|
|
for tag in "${tags[@]}"; do
|
|
args+=" -t $DOCKER_REPOSITORY:$tag"
|
|
done
|
|
|
|
if [[ $push -eq 1 ]]; then
|
|
args+=" --push"
|
|
args+=" --cache-to=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag,mode=max"
|
|
fi
|
|
|
|
if [[ $load -eq 1 ]]; then
|
|
args+=" --load"
|
|
fi
|
|
|
|
echo "Args: $args"
|
|
|
|
|
|
if [[ $load -eq 1 ]]; then
|
|
|
|
platform=$(docker version -f '{{.Server.Os}}/{{.Server.Arch}}')
|
|
else
|
|
|
|
platform="linux/amd64,linux/arm64"
|
|
fi
|
|
|
|
echo "Building for platform(s): $platform"
|
|
|
|
docker buildx build \
|
|
$args \
|
|
--build-arg OPENHANDS_BUILD_VERSION="$OPENHANDS_BUILD_VERSION" \
|
|
--cache-from=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag \
|
|
--cache-from=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag_base-main \
|
|
--platform $platform \
|
|
--provenance=false \
|
|
-f "$dir/Dockerfile" \
|
|
"$DOCKER_BASE_DIR"
|
|
|
|
|
|
if [[ $load -eq 1 ]]; then
|
|
echo "Local images built:"
|
|
docker images "$DOCKER_REPOSITORY" --format "{{.Repository}}:{{.Tag}}"
|
|
fi
|
|
|