Files
just-commons/images/mod.just

345 lines
10 KiB
Plaintext

# Universal container image operations
# Build project image (auto-discovers Dockerfile if project not specified)
[no-cd]
build project="" tag="":
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
tag="{{tag}}"
# Determine discovery directory
if [ -z "$project" ]; then
discovery_dir="."
echo -e "{{BLUE}}🔍 Auto-discovering Dockerfile/Containerfile...{{NORMAL}}"
else
# Check if project directory exists
if [ ! -d "$project" ]; then
echo "{{BOLD}}{{RED}}Error:{{NORMAL}} Project directory '$project' not found" >&2
exit 1
fi
discovery_dir="$project"
echo -e "{{BLUE}}🔍 Auto-discovering Dockerfile/Containerfile in $project...{{NORMAL}}"
fi
# Use unified discovery logic
discovery_result=$(just _discover_containerfile_in "$discovery_dir")
read -r containerfile discovered_project build_context <<< "$discovery_result"
# Use discovered project name if not explicitly set
if [ -z "$project" ]; then
project="$discovered_project"
fi
echo -e "{{GREEN}}✓ Found $containerfile{{NORMAL}}"
# Generate tag if not provided
if [ -z "$tag" ]; then
if git rev-parse --git-dir >/dev/null 2>&1; then
tag="commit-$(git rev-parse --short HEAD)"
else
tag="build-$(date '+%Y%m%d-%H%M%S')"
fi
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -n "$username" ]; then
image_name="$registry/$username/$project:$tag"
else
image_name="$project:$tag"
fi
echo -e "{{BLUE}}Building image: $image_name{{NORMAL}}"
echo -e "{{YELLOW}}Using: $containerfile{{NORMAL}}"
echo -e "{{YELLOW}}Build context: $build_context{{NORMAL}}"
# Handle cross-platform builds with macOS compatibility workaround
if grep -q "FROM.*--platform" "$containerfile"; then
echo -e "{{YELLOW}}Cross-platform build detected, using macOS compatibility workaround{{NORMAL}}"
# Create temporary Containerfile without platform specification for local build
temp_containerfile="/tmp/Containerfile.local.$$"
sed 's/FROM --platform=[^ ]* /FROM /' "$containerfile" > "$temp_containerfile"
echo -e "{{BLUE}}Building without platform emulation (will be multi-arch compatible){{NORMAL}}"
$runtime build -f "$temp_containerfile" -t "$image_name" --load "$build_context"
# Clean up temp file
rm -f "$temp_containerfile"
else
$runtime build -f "$containerfile" -t "$image_name" --load "$build_context"
fi
echo -e "{{GREEN}}✓ Successfully built: $image_name{{NORMAL}}"
# Push project image to registry
[no-cd]
push project="" tag="":
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
tag="{{tag}}"
# Auto-discover project if not specified
if [ -z "$project" ]; then
echo -e "{{BLUE}}🔍 Auto-discovering project...{{NORMAL}}"
project=$(just _discover_project)
echo -e "{{GREEN}}✓ Using project: $project{{NORMAL}}"
fi
# Generate tag if not provided
if [ -z "$tag" ]; then
if git rev-parse --git-dir >/dev/null 2>&1; then
tag="commit-$(git rev-parse --short HEAD)"
else
tag="latest"
fi
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -z "$username" ]; then
echo "{{BOLD}}{{RED}}Error:{{NORMAL}} GITHUB_USERNAME not set" >&2
echo "{{YELLOW}}Set GITHUB_USERNAME in .env file{{NORMAL}}" >&2
exit 1
fi
image_name="$registry/$username/$project:$tag"
echo -e "{{BLUE}}Pushing image: $image_name{{NORMAL}}"
$runtime push "$image_name"
echo -e "{{GREEN}}✓ Successfully pushed: $image_name{{NORMAL}}"
# Pull project image from registry
[no-cd]
pull project="" tag="latest":
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
tag="{{tag}}"
# Auto-discover project if not specified
if [ -z "$project" ]; then
echo -e "{{BLUE}}🔍 Auto-discovering project...{{NORMAL}}"
project=$(just _discover_project)
echo -e "{{GREEN}}✓ Using project: $project{{NORMAL}}"
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -z "$username" ]; then
echo "{{BOLD}}{{RED}}Error:{{NORMAL}} GITHUB_USERNAME not set" >&2
echo "{{YELLOW}}Set GITHUB_USERNAME in .env file{{NORMAL}}" >&2
exit 1
fi
image_name="$registry/$username/$project:$tag"
echo -e "{{BLUE}}Pulling image: $image_name{{NORMAL}}"
$runtime pull "$image_name"
echo -e "{{GREEN}}✓ Successfully pulled: $image_name{{NORMAL}}"
# Tag existing image
[no-cd]
tag project new_tag:
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
new_tag="{{new_tag}}"
if [ -z "$project" ] || [ -z "$new_tag" ]; then
echo "{{BOLD}}{{RED}}Error:{{NORMAL}} Project name and new tag are required" >&2
echo "{{YELLOW}}Usage:{{NORMAL}} just images tag myproject newtag" >&2
exit 1
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -n "$username" ]; then
old_image="$registry/$username/$project"
new_image="$registry/$username/$project:$new_tag"
else
old_image="$project"
new_image="$project:$new_tag"
fi
# Find the most recent tag for the project
latest_image=$($runtime images | grep "^$old_image" | awk '{print $1":"$2}' | head -1)
if [ -z "$latest_image" ]; then
echo "{{BOLD}}{{RED}}Error:{{NORMAL}} No images found for project: $project" >&2
exit 1
fi
echo -e "{{BLUE}}Tagging image: $latest_image → $new_image{{NORMAL}}"
$runtime tag "$latest_image" "$new_image"
echo -e "{{GREEN}}✓ Successfully tagged: $new_image{{NORMAL}}"
# Show image information
[no-cd]
info project="" tag="":
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
tag="{{tag}}"
# Auto-discover project if not specified
if [ -z "$project" ]; then
echo -e "{{BLUE}}🔍 Auto-discovering project...{{NORMAL}}"
project=$(just _discover_project)
echo -e "{{GREEN}}✓ Using project: $project{{NORMAL}}"
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -n "$username" ]; then
image_base="$registry/$username/$project"
else
image_base="$project"
fi
if [ -n "$tag" ]; then
image_name="$image_base:$tag"
else
image_name="$image_base"
fi
echo ""
echo -e "{{BLUE}}Image information for: $image_name{{NORMAL}}"
# Show image details
$runtime images "$image_name"
echo ""
echo -e "{{BLUE}}Image history:{{NORMAL}}"
$runtime history "$image_name" 2>/dev/null || echo "Image not found locally"
# Remove project images
[confirm]
[no-cd]
clean project="":
#!/usr/bin/env bash
set -euo pipefail
project="{{project}}"
# Auto-discover project if not specified
if [ -z "$project" ]; then
echo -e "{{BLUE}}🔍 Auto-discovering project...{{NORMAL}}"
project=$(just _discover_project)
echo -e "{{GREEN}}✓ Using project: $project{{NORMAL}}"
fi
runtime=$(just _detect_runtime)
registry="${REGISTRY:-ghcr.io}"
username="${GITHUB_USERNAME:-}"
if [ -n "$username" ]; then
image_pattern="$registry/$username/$project"
else
image_pattern="$project"
fi
echo -e "{{YELLOW}}Removing all images for project: $project{{NORMAL}}"
# Find and remove all images for the project
images=$($runtime images --format "{{{{.Repository}}}}:{{{{.Tag}}}}" | grep "^$image_pattern" || true)
if [ -z "$images" ]; then
echo -e "{{YELLOW}}No images found for project: $project{{NORMAL}}"
exit 0
fi
echo -e "{{BLUE}}Images to remove:{{NORMAL}}"
echo "$images"
echo ""
echo "$images" | while IFS= read -r image; do
if [ -n "$image" ]; then
echo -e "{{BLUE}}Removing: $image{{NORMAL}}"
$runtime rmi "$image" 2>/dev/null || true
fi
done
echo -e "{{GREEN}}✓ Project images cleaned{{NORMAL}}"
# Build all known projects
[no-cd]
build-all:
#!/usr/bin/env bash
set -euo pipefail
echo -e "{{BLUE}}Building all projects with Containerfiles...{{NORMAL}}"
# Find all directories with Containerfile or Dockerfile using discovery logic
projects=""
# Check current directory first (handles docker/ subfolder case)
has_current_project=false
if just _discover_containerfile_in "." >/dev/null 2>&1; then
current_project=$(just _discover_project)
has_current_project=true
echo -e "{{GREEN}}✓ Found project in current directory: $current_project{{NORMAL}}"
fi
# Check subdirectories
for dir in */; do
if [ -d "$dir" ]; then
dir_name="${dir%/}"
# Skip docker directory to avoid duplicate detection
if [ "$dir_name" != "docker" ] && just _discover_containerfile_in "$dir_name" >/dev/null 2>&1; then
projects="$projects $dir_name"
fi
fi
done
if [ -z "$projects" ] && [ "$has_current_project" = false ]; then
echo -e "{{YELLOW}}No projects with Containerfile/Dockerfile found{{NORMAL}}"
exit 0
fi
# Show discovered projects
if [ "$has_current_project" = true ]; then
echo -e "{{BLUE}}Found projects: $current_project (current directory)$projects{{NORMAL}}"
else
echo -e "{{BLUE}}Found projects:$projects{{NORMAL}}"
fi
echo ""
# Build current project first if found
if [ "$has_current_project" = true ]; then
echo -e "{{CYAN}}Building project: $current_project (current directory){{NORMAL}}"
just images build
echo ""
fi
# Build subdirectory projects
for project in $projects; do
if [ -n "$project" ]; then
echo -e "{{CYAN}}Building project: $project{{NORMAL}}"
just images build "$project"
echo ""
fi
done
echo -e "{{GREEN}}✓ All projects built successfully{{NORMAL}}"