mirror of
https://github.com/shadoll/just-commons.git
synced 2025-12-20 03:26:43 +00:00
Initial commit: Add universal Just recipes
- container.just: Universal container operations (start, stop, logs, shell, exec, status) - registry.just: GitHub Container Registry authentication - images.just: Universal image build/push/pull operations - README.md: Documentation and usage instructions These recipes work universally across any project with containerfiles.
This commit is contained in:
49
README.md
Normal file
49
README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Just Commons
|
||||||
|
|
||||||
|
Universal Just command recipes for container management across projects.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This repository contains reusable Just recipes for:
|
||||||
|
- **Container operations**: start, stop, restart, logs, shell, exec, status
|
||||||
|
- **Registry authentication**: login, logout, status checks for GitHub Container Registry
|
||||||
|
- **Image operations**: build, push, pull, tag, test, info, clean
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add as a Git submodule to your project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule add git@github.com:shadoll/just-commons.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Import in your `justfile`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Import universal commands
|
||||||
|
import 'just-commons/container.just'
|
||||||
|
import 'just-commons/registry.just'
|
||||||
|
import 'just-commons/images.just'
|
||||||
|
|
||||||
|
# Your project-specific commands
|
||||||
|
import 'just/postgres.just'
|
||||||
|
import 'just/servapp.just'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- `container.just` - Universal container operations (start, stop, logs, shell, exec, status)
|
||||||
|
- `registry.just` - GitHub Container Registry authentication
|
||||||
|
- `images.just` - Universal image build/push/pull operations
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Just command runner
|
||||||
|
- Docker or Podman
|
||||||
|
- Git
|
||||||
|
|
||||||
|
## Projects Using This
|
||||||
|
|
||||||
|
- [servass](https://github.com/shadoll/servass) - Universal container image management
|
||||||
|
- [servass_sh](https://github.com/shadoll/servass_sh) - Production deployment (SH)
|
||||||
|
- [servass_ri](https://github.com/shadoll/servass_ri) - Production deployment (RI)
|
||||||
321
container.just
Normal file
321
container.just
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
# Additional helper commands for service management
|
||||||
|
|
||||||
|
# Environment detection
|
||||||
|
env-check:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "================================================"
|
||||||
|
echo " Container Environment Detection"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check Docker
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
if docker info >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✓ Docker Engine detected and running${NC}"
|
||||||
|
docker_available=true
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠ Docker is installed but daemon is not running${NC}"
|
||||||
|
docker_available=false
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Docker not found${NC}"
|
||||||
|
docker_available=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Podman
|
||||||
|
if command -v podman >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✓ Podman detected${NC}"
|
||||||
|
podman_available=true
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Podman not found${NC}"
|
||||||
|
podman_available=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================"
|
||||||
|
echo " SUMMARY"
|
||||||
|
echo "================================================"
|
||||||
|
|
||||||
|
if [ "$docker_available" = true ] || [ "$podman_available" = true ]; then
|
||||||
|
echo -e "${GREEN}🎉 Container runtime available!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "You can use these commands:"
|
||||||
|
echo " just build postgres # Build PostgreSQL image"
|
||||||
|
echo " just build servapp # Build ServApp image"
|
||||||
|
echo " just login # Login to registry"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ No container runtime available${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Please install Docker or Podman:"
|
||||||
|
echo " • Docker: https://docs.docker.com/get-docker/"
|
||||||
|
echo " • Podman: https://podman.io/getting-started/installation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start service (helper command)
|
||||||
|
start service:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
if [ ! -d "$service" ]; then
|
||||||
|
echo "Error: Service directory '$service' not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}Starting $service service...${NC}"
|
||||||
|
cd "$service"
|
||||||
|
|
||||||
|
# Detect compose command based on available and working container runtime
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||||
|
# Docker daemon is running, check for compose
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
docker compose up -d
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
docker-compose up -d
|
||||||
|
else
|
||||||
|
echo "Error: Docker is running but no compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif command -v podman >/dev/null 2>&1 && command -v podman-compose >/dev/null 2>&1; then
|
||||||
|
podman-compose up -d
|
||||||
|
else
|
||||||
|
echo "Error: No working container runtime with compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ $service service started${NC}"
|
||||||
|
|
||||||
|
# Stop service (helper command)
|
||||||
|
stop service:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
|
||||||
|
if [ ! -d "$service" ]; then
|
||||||
|
echo "Error: Service directory '$service' not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}Stopping $service service...${NC}"
|
||||||
|
cd "$service"
|
||||||
|
|
||||||
|
# Detect compose command based on available and working container runtime
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||||
|
# Docker daemon is running, check for compose
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
docker compose down
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
docker-compose down
|
||||||
|
else
|
||||||
|
echo "Error: Docker is running but no compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif command -v podman >/dev/null 2>&1 && command -v podman-compose >/dev/null 2>&1; then
|
||||||
|
podman-compose down
|
||||||
|
else
|
||||||
|
echo "Error: No working container runtime with compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ $service service stopped${NC}"
|
||||||
|
|
||||||
|
# Show service logs (helper command)
|
||||||
|
logs service:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
|
||||||
|
if [ ! -d "$service" ]; then
|
||||||
|
echo "Error: Service directory '$service' not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$service"
|
||||||
|
|
||||||
|
# Detect compose command based on available and working container runtime
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||||
|
# Docker daemon is running, check for compose
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
docker compose logs -f
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
docker-compose logs -f
|
||||||
|
else
|
||||||
|
echo "Error: Docker is running but no compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif command -v podman >/dev/null 2>&1 && command -v podman-compose >/dev/null 2>&1; then
|
||||||
|
podman-compose logs -f
|
||||||
|
else
|
||||||
|
echo "Error: No working container runtime with compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Open shell in running container (helper command)
|
||||||
|
shell service:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
# Get first running container for this service
|
||||||
|
container_id=$($runtime ps -q --filter "label=com.docker.compose.project=$service" | head -n1)
|
||||||
|
if [ -n "$container_id" ]; then
|
||||||
|
$runtime exec -it "$container_id" /bin/bash || \
|
||||||
|
$runtime exec -it "$container_id" /bin/sh
|
||||||
|
else
|
||||||
|
echo -e "${RED}No running containers found for $service${NC}"
|
||||||
|
echo "Start the service first with: just start $service"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute command in service container (helper command)
|
||||||
|
exec service cmd:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
command="{{cmd}}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
if [ -z "$command" ]; then
|
||||||
|
echo -e "${RED}No command specified${NC}" >&2
|
||||||
|
echo "Usage: just exec $service \"command to execute\"" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get first running container for this service
|
||||||
|
container_id=$($runtime ps -q --filter "label=com.docker.compose.project=$service" | head -n1)
|
||||||
|
if [ -n "$container_id" ]; then
|
||||||
|
$runtime exec -it "$container_id" sh -c "$command"
|
||||||
|
else
|
||||||
|
echo -e "${RED}No running containers found for $service${NC}"
|
||||||
|
echo "Start the service first with: just start $service"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show service status (helper command)
|
||||||
|
status service:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
service="{{service}}"
|
||||||
|
|
||||||
|
if [ ! -d "$service" ]; then
|
||||||
|
echo "Error: Service directory '$service' not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$service"
|
||||||
|
|
||||||
|
# Detect compose command based on available and working container runtime
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||||
|
# Docker daemon is running, check for compose
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
docker compose ps
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
docker-compose ps
|
||||||
|
else
|
||||||
|
echo "Error: Docker is running but no compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif command -v podman >/dev/null 2>&1 && command -v podman-compose >/dev/null 2>&1; then
|
||||||
|
podman-compose ps
|
||||||
|
else
|
||||||
|
echo "Error: No working container runtime with compose tool found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Quick development setup
|
||||||
|
dev-setup:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}Setting up development environment...${NC}"
|
||||||
|
|
||||||
|
# Check environment
|
||||||
|
just env-check
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Building development images...${NC}"
|
||||||
|
|
||||||
|
# Build development images
|
||||||
|
just postgres-dev
|
||||||
|
just servapp-dev
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✓ Development environment ready!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Available commands:${NC}"
|
||||||
|
echo " just start postgres # Start PostgreSQL service"
|
||||||
|
echo " just start servapp # Start ServApp service"
|
||||||
|
echo " just logs postgres # View PostgreSQL logs"
|
||||||
|
echo " just shell postgres # Connect to PostgreSQL container"
|
||||||
|
|
||||||
|
# Clean all development artifacts
|
||||||
|
dev-clean:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}Cleaning development environment...${NC}"
|
||||||
|
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
# Stop any running services
|
||||||
|
echo -e "${YELLOW}Stopping services...${NC}"
|
||||||
|
just stop postgres 2>/dev/null || true
|
||||||
|
just stop servapp 2>/dev/null || true
|
||||||
|
|
||||||
|
# Clean images
|
||||||
|
echo -e "${YELLOW}Cleaning development images...${NC}"
|
||||||
|
just clean postgres 2>/dev/null || true
|
||||||
|
just clean servapp 2>/dev/null || true
|
||||||
|
|
||||||
|
# Remove dev tags
|
||||||
|
$runtime rmi postgres:dev servapp:dev 2>/dev/null || true
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Development environment cleaned${NC}"
|
||||||
383
images.just
Normal file
383
images.just
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
# Universal image operations - works for any project
|
||||||
|
|
||||||
|
# Detect container runtime
|
||||||
|
_detect_runtime:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||||
|
echo "docker"
|
||||||
|
elif command -v podman >/dev/null 2>&1; then
|
||||||
|
echo "podman"
|
||||||
|
else
|
||||||
|
echo "Error: No container runtime available (docker or podman)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build any project's container image
|
||||||
|
build project *args="":
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
args="{{args}}"
|
||||||
|
|
||||||
|
# Use default tag if not specified
|
||||||
|
tag="commit-$(git rev-parse --short HEAD)"
|
||||||
|
|
||||||
|
# Validate project directory exists
|
||||||
|
if [ ! -d "$project" ]; then
|
||||||
|
echo -e "${RED}Error: Project directory '$project' not found${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Look for Containerfile or Dockerfile
|
||||||
|
containerfile=""
|
||||||
|
if [ -f "$project/Containerfile" ]; then
|
||||||
|
containerfile="Containerfile"
|
||||||
|
elif [ -f "$project/Dockerfile" ]; then
|
||||||
|
containerfile="Dockerfile"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Error: No Containerfile or Dockerfile found in '$project'${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect runtime
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
# Build image
|
||||||
|
echo -e "${BLUE}Building $project image with tag: $tag${NC}"
|
||||||
|
cd "$project"
|
||||||
|
|
||||||
|
# Create full image name with registry
|
||||||
|
full_image_name="{{REGISTRY}}/${GITHUB_USERNAME:-local}/$project:$tag"
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Building: $full_image_name${NC}"
|
||||||
|
$runtime build $args -t "$full_image_name" -f "$containerfile" .
|
||||||
|
|
||||||
|
# Also tag as local for development
|
||||||
|
$runtime tag "$full_image_name" "$project:$tag"
|
||||||
|
$runtime tag "$full_image_name" "$project:latest"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Image $project:$tag built successfully${NC}"
|
||||||
|
echo -e "${GREEN}✓ Tagged as: $full_image_name${NC}"
|
||||||
|
echo -e "${GREEN}✓ Local tags: $project:$tag, $project:latest${NC}"
|
||||||
|
|
||||||
|
# Push any project's image to registry
|
||||||
|
push project tag=DEFAULT_TAG:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
tag="{{tag}}"
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
source .env
|
||||||
|
else
|
||||||
|
echo -e "${RED}Error: .env file not found${NC}" >&2
|
||||||
|
echo "Create .env file with your GitHub credentials" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check loaded variables
|
||||||
|
if [ -z "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
echo -e "${RED}Error: GITHUB_USERNAME not set in .env file${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${GITHUB_TOKEN:-}" ]; then
|
||||||
|
echo -e "${RED}Error: GITHUB_TOKEN not set in .env file${NC}" >&2
|
||||||
|
echo "Add your token to .env file: GITHUB_TOKEN=your-token" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect runtime
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
# Login first
|
||||||
|
echo "$GITHUB_TOKEN" | $runtime login {{REGISTRY}} -u "$GITHUB_USERNAME" --password-stdin
|
||||||
|
|
||||||
|
# Handle special case: pushing as "latest" means push both commit tag and latest
|
||||||
|
if [ "$tag" = "latest" ]; then
|
||||||
|
# Get current commit tag
|
||||||
|
if git rev-parse --git-dir >/dev/null 2>&1; then
|
||||||
|
commit_tag="commit-$(git rev-parse --short HEAD)"
|
||||||
|
else
|
||||||
|
commit_tag="build-$(date '+%Y%m%d-%H%M%S')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
commit_image_name="{{REGISTRY}}/$GITHUB_USERNAME/$project:$commit_tag"
|
||||||
|
latest_image_name="{{REGISTRY}}/$GITHUB_USERNAME/$project:latest"
|
||||||
|
|
||||||
|
echo -e "${BLUE}Pushing $project as latest (both $commit_tag and latest tags)...${NC}"
|
||||||
|
|
||||||
|
# Tag the local image with both commit and latest registry tags
|
||||||
|
$runtime tag "$project:latest" "$commit_image_name"
|
||||||
|
$runtime tag "$project:latest" "$latest_image_name"
|
||||||
|
|
||||||
|
# Push both tags
|
||||||
|
$runtime push "$commit_image_name"
|
||||||
|
$runtime push "$latest_image_name"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Pushed as: $commit_image_name${NC}"
|
||||||
|
echo -e "${GREEN}✓ Pushed as: $latest_image_name${NC}"
|
||||||
|
else
|
||||||
|
# Normal push: just push the specific tag
|
||||||
|
full_image_name="{{REGISTRY}}/$GITHUB_USERNAME/$project:$tag"
|
||||||
|
|
||||||
|
echo -e "${BLUE}Pushing $project:$tag to registry...${NC}"
|
||||||
|
$runtime push "$full_image_name"
|
||||||
|
echo -e "${GREEN}✓ Image pushed successfully: $full_image_name${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull any project's image from registry
|
||||||
|
pull project tag=DEFAULT_TAG:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
tag="{{tag}}"
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
source .env
|
||||||
|
else
|
||||||
|
echo -e "${RED}Error: .env file not found${NC}" >&2
|
||||||
|
echo "Create .env file with your GitHub credentials" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check loaded variables
|
||||||
|
if [ -z "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
echo -e "${RED}Error: GITHUB_USERNAME not set in .env file${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect runtime
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
# Create full image name
|
||||||
|
full_image_name="{{REGISTRY}}/$GITHUB_USERNAME/$project:$tag"
|
||||||
|
|
||||||
|
echo -e "${BLUE}Pulling $project:$tag from registry...${NC}"
|
||||||
|
|
||||||
|
$runtime pull "$full_image_name"
|
||||||
|
|
||||||
|
# Tag locally for convenience
|
||||||
|
$runtime tag "$full_image_name" "$project:$tag"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Image pulled successfully: $full_image_name${NC}"
|
||||||
|
echo -e "${GREEN}✓ Tagged locally as: $project:$tag${NC}"
|
||||||
|
|
||||||
|
# Tag any project's existing image
|
||||||
|
tag project new_tag:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
new_tag="{{new_tag}}"
|
||||||
|
|
||||||
|
# Detect runtime
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}Tagging $project:latest as $project:$new_tag${NC}"
|
||||||
|
|
||||||
|
$runtime tag "$project:latest" "$project:$new_tag"
|
||||||
|
|
||||||
|
# Also create registry tag if username is set
|
||||||
|
if [ -n "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
registry_tag="{{REGISTRY}}/$GITHUB_USERNAME/$project:$new_tag"
|
||||||
|
$runtime tag "$project:latest" "$registry_tag"
|
||||||
|
echo -e "${GREEN}✓ Tagged as: $project:$new_tag and $registry_tag${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓ Tagged as: $project:$new_tag${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test any project's image
|
||||||
|
test project tag="latest":
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
tag="{{tag}}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}Testing $project image: $project:$tag${NC}"
|
||||||
|
|
||||||
|
# Check if image exists
|
||||||
|
if ! $runtime images "$project:$tag" | grep -q "$project"; then
|
||||||
|
echo -e "${RED}Error: Image $project:$tag not found${NC}" >&2
|
||||||
|
echo "Build it first with: just build $project $tag" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Starting temporary $project container for testing...${NC}"
|
||||||
|
|
||||||
|
# Run temporary container
|
||||||
|
container_id=$($runtime run -d --rm "$project:$tag" sleep 30)
|
||||||
|
|
||||||
|
echo "Container ID: $container_id"
|
||||||
|
|
||||||
|
# Wait for container to start
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Basic test - check if container is running
|
||||||
|
if $runtime exec "$container_id" echo "Container is responsive" >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✓ Container is responsive${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Container test failed${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
echo -e "${YELLOW}Cleaning up test container...${NC}"
|
||||||
|
$runtime stop "$container_id" >/dev/null 2>&1
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ $project image test completed${NC}"
|
||||||
|
|
||||||
|
# Show any project's image information
|
||||||
|
info project tag="latest":
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
tag="{{tag}}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}$project Image Information: $project:$tag${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if $runtime images "$project:$tag" | grep -q "$project"; then
|
||||||
|
echo -e "${GREEN}Image Details:${NC}"
|
||||||
|
$runtime images "$project:$tag"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo -e "${GREEN}Image History (last 10 layers):${NC}"
|
||||||
|
$runtime history "$project:$tag" | head -10
|
||||||
|
else
|
||||||
|
echo "Image $project:$tag not found locally"
|
||||||
|
echo "Build it with: just build $project $tag"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List all project images
|
||||||
|
list:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}Local Project Images:${NC}"
|
||||||
|
|
||||||
|
# List images for known projects
|
||||||
|
for project in postgres servapp; do
|
||||||
|
if [ -d "$project" ]; then
|
||||||
|
echo -e "\n${BLUE}$project images:${NC}"
|
||||||
|
$runtime images "$project" 2>/dev/null || echo " No images found"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# List any other images that might be project images
|
||||||
|
echo -e "\n${BLUE}Registry images:${NC}"
|
||||||
|
if [ -n "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
$runtime images | grep "{{REGISTRY}}/$GITHUB_USERNAME" || echo " No registry images found"
|
||||||
|
else
|
||||||
|
echo " Set GITHUB_USERNAME to see registry images"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove any project's local images
|
||||||
|
clean project:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
project="{{project}}"
|
||||||
|
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Removing all local images for: $project${NC}"
|
||||||
|
|
||||||
|
# Remove local tags (disable pipefail temporarily for this section)
|
||||||
|
set +e
|
||||||
|
|
||||||
|
# Remove common local project tags
|
||||||
|
for tag in latest commit-* build-*; do
|
||||||
|
$runtime rmi "$project:$tag" 2>/dev/null || true
|
||||||
|
$runtime rmi "localhost/$project:$tag" 2>/dev/null || true
|
||||||
|
$runtime rmi "localhost/${project}_${project}:$tag" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove all images matching project name patterns
|
||||||
|
$runtime images --format "\{\{.Repository\}\}:\{\{.Tag\}\}" | grep -E "^($project|localhost/$project|localhost/${project}_${project})" | while read -r img; do
|
||||||
|
[ -n "$img" ] && $runtime rmi "$img" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove registry tags if they exist
|
||||||
|
if [ -n "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
$runtime images --format "\{\{.Repository\}\}:\{\{.Tag\}\}" | grep "{{REGISTRY}}/$GITHUB_USERNAME/$project" | while read -r img; do
|
||||||
|
[ -n "$img" ] && $runtime rmi "$img" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Re-enable strict error handling
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Cleaned local images for: $project${NC}"
|
||||||
|
|
||||||
|
# Quick build all known projects
|
||||||
|
build-all:
|
||||||
|
@echo "{{BLUE}}Building all known projects...{{NC}}"
|
||||||
|
@just build postgres
|
||||||
|
@just build servapp
|
||||||
|
@echo "{{GREEN}}✓ All projects built successfully{{NC}}"
|
||||||
|
|
||||||
|
# Quick push all known projects
|
||||||
|
push-all tag=DEFAULT_TAG:
|
||||||
|
@echo "{{BLUE}}Pushing all known projects with tag: {{tag}}{{NC}}"
|
||||||
|
@just push postgres {{tag}}
|
||||||
|
@just push servapp {{tag}}
|
||||||
|
@echo "{{GREEN}}✓ All projects pushed successfully{{NC}}"
|
||||||
172
registry.just
Normal file
172
registry.just
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
# Registry operations
|
||||||
|
|
||||||
|
# Login to container registry
|
||||||
|
registry-login:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
source .env
|
||||||
|
else
|
||||||
|
echo -e "${RED}Error: .env file not found${NC}" >&2
|
||||||
|
echo "Create .env file with:" >&2
|
||||||
|
echo "GITHUB_USERNAME=your-username" >&2
|
||||||
|
echo "GITHUB_TOKEN=your-token" >&2
|
||||||
|
echo "Or copy from .env.example and modify" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check loaded variables
|
||||||
|
if [ -z "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
echo -e "${RED}Error: GITHUB_USERNAME not set in .env file${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${GITHUB_TOKEN:-}" ]; then
|
||||||
|
echo -e "${RED}Error: GITHUB_TOKEN not set in .env file${NC}" >&2
|
||||||
|
echo "Add your token to .env file: GITHUB_TOKEN=your-token" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect runtime
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}Logging in to {{REGISTRY}} as $GITHUB_USERNAME...${NC}"
|
||||||
|
|
||||||
|
if echo "$GITHUB_TOKEN" | $runtime login {{REGISTRY}} -u "$GITHUB_USERNAME" --password-stdin; then
|
||||||
|
echo -e "${GREEN}✓ Successfully logged in to {{REGISTRY}}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Failed to login to {{REGISTRY}}${NC}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Logout from container registry
|
||||||
|
registry-logout:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
echo -e "${BLUE}Logging out from {{REGISTRY}}...${NC}"
|
||||||
|
|
||||||
|
$runtime logout {{REGISTRY}}
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ Successfully logged out from {{REGISTRY}}${NC}"
|
||||||
|
|
||||||
|
|
||||||
|
# Check authentication and registry status
|
||||||
|
registry-check:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}=== Authentication Status ===${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check .env file and variables
|
||||||
|
echo -e "${BLUE}1. Environment Configuration (.env file):${NC}"
|
||||||
|
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo -e "${RED} ✗ .env file not found${NC}"
|
||||||
|
echo " Edit .env file manually or copy from .env.example"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source .env
|
||||||
|
|
||||||
|
if [ -n "${GITHUB_USERNAME:-}" ]; then
|
||||||
|
echo -e "${GREEN} ✓ GITHUB_USERNAME: $GITHUB_USERNAME${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED} ✗ GITHUB_USERNAME: not set in .env${NC}"
|
||||||
|
echo " Add GITHUB_USERNAME=your-username to .env file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||||
|
# Show masked token
|
||||||
|
token_len=${#GITHUB_TOKEN}
|
||||||
|
if [ $token_len -gt 8 ]; then
|
||||||
|
prefix=${GITHUB_TOKEN:0:4}
|
||||||
|
suffix=${GITHUB_TOKEN: -4}
|
||||||
|
masked_middle=$(printf "%*s" $((token_len-8)) | tr ' ' '*')
|
||||||
|
echo -e "${GREEN} ✓ GITHUB_TOKEN: ${prefix}${masked_middle}${suffix} (${token_len} chars)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN} ✓ GITHUB_TOKEN: $(printf "%*s" $token_len | tr ' ' '*') (${token_len} chars)${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED} ✗ GITHUB_TOKEN: not set in .env${NC}"
|
||||||
|
echo " Add GITHUB_TOKEN=your-token to .env file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check token validity
|
||||||
|
echo -e "${BLUE}2. GitHub API Authentication:${NC}"
|
||||||
|
response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user)
|
||||||
|
|
||||||
|
if echo "$response" | grep -q '"login"'; then
|
||||||
|
username=$(echo "$response" | grep '"login"' | sed 's/.*"login": "\([^"]*\)".*/\1/')
|
||||||
|
echo -e "${GREEN} ✓ Token is valid - authenticated as: $username${NC}"
|
||||||
|
|
||||||
|
# Check token scopes
|
||||||
|
scopes_response=$(curl -s -I -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user)
|
||||||
|
if echo "$scopes_response" | grep -i "x-oauth-scopes" > /dev/null; then
|
||||||
|
scopes=$(echo "$scopes_response" | grep -i "x-oauth-scopes" | cut -d: -f2- | tr -d '\r')
|
||||||
|
|
||||||
|
# Check for required scopes
|
||||||
|
if echo "$scopes" | grep -q "write:packages"; then
|
||||||
|
echo -e "${GREEN} ✓ Has write:packages scope (push enabled)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW} ⚠ Missing write:packages scope (push disabled)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "$scopes" | grep -q "read:packages"; then
|
||||||
|
echo -e "${GREEN} ✓ Has read:packages scope (pull enabled)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW} ⚠ Missing read:packages scope (pull may fail)${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED} ✗ Token is invalid or expired${NC}"
|
||||||
|
if echo "$response" | grep -q "Bad credentials"; then
|
||||||
|
echo " The token appears to be malformed or expired"
|
||||||
|
elif echo "$response" | grep -q "rate limit"; then
|
||||||
|
echo " Rate limited - try again later"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check registry login
|
||||||
|
echo -e "${BLUE}3. Container Registry Test:${NC}"
|
||||||
|
runtime=$(just _detect_runtime)
|
||||||
|
|
||||||
|
if echo "$GITHUB_TOKEN" | $runtime login {{REGISTRY}} -u "$GITHUB_USERNAME" --password-stdin >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN} ✓ Registry login successful${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED} ✗ Registry login failed${NC}"
|
||||||
|
echo " Check your token permissions"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✓ All authentication checks passed!${NC}"
|
||||||
|
echo -e "${BLUE}You can now use: just push <project>, just pull <project>${NC}"
|
||||||
Reference in New Issue
Block a user