#!/usr/bin/env bash # Exit on error. Append "|| true" if you expect an error. set -o errexit # Exit on error inside any functions or subshells. set -o errtrace # Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR set -o nounset # Catch pipeline errors set -o pipefail # Turn on traces, useful while debugging but commented out by default # set -o xtrace # Configuration readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" readonly ENV_FILE="${SCRIPT_DIR}/.env" readonly IMAGE_NAME="finance-devcontainer" readonly IMAGE_TAG="latest" # Check for required username argument if [[ $# -lt 1 ]]; then echo >&2 "Error: GitHub username is required" echo >&2 "Usage: $0 " echo >&2 "Example: $0 acedanger" exit 1 fi readonly GITHUB_USERNAME="$1" readonly DOCKERFILE_PATH="${SCRIPT_DIR}/Dockerfile" readonly FULL_IMAGE_NAME="ghcr.io/${GITHUB_USERNAME}/${IMAGE_NAME}:${IMAGE_TAG}" # Check for required tools for cmd in docker gh; do if ! command -v "${cmd}" >/dev/null 2>&1; then echo >&2 "Error: ${cmd} is required but not installed" exit 1 fi done # Load environment variables from .env file if it exists if [[ ! -f "${ENV_FILE}" ]]; then echo >&2 "Error: Environment file not found: ${ENV_FILE}" exit 1 fi echo "Loading environment from ${ENV_FILE}" # Read the env file line by line to handle special characters correctly while IFS= read -r line || [[ -n "${line}" ]]; do # Skip comments and empty lines [[ "${line}" =~ ^[[:space:]]*# ]] && continue [[ -z "${line}" ]] && continue # Export the variable if it's the PAT if [[ "${line}" =~ ^GITHUB_PERSONAL_ACCESS_TOKEN= ]]; then export "${line}" break fi done < "${ENV_FILE}" # Verify PAT is loaded if [[ -z "${GITHUB_PERSONAL_ACCESS_TOKEN:-}" ]]; then echo >&2 "Error: GITHUB_PERSONAL_ACCESS_TOKEN is not set in ${ENV_FILE}" exit 1 fi # Check GitHub authentication if ! gh auth status >/dev/null 2>&1; then echo >&2 "Error: Not authenticated with GitHub. Please run 'gh auth login' first" exit 1 fi echo "=== Building Development Container ===" echo "Username: ${GITHUB_USERNAME}" echo "Image: ${FULL_IMAGE_NAME}" echo "Dockerfile: ${DOCKERFILE_PATH}" echo "Using PAT: ${GITHUB_PERSONAL_ACCESS_TOKEN:0:4}... (first 4 chars)" # Build the image echo -e "\n=> Building image..." if ! docker build -t "${FULL_IMAGE_NAME}" -f "${DOCKERFILE_PATH}" "${SCRIPT_DIR}"; then echo >&2 "Error: Docker build failed" exit 1 fi # Log in to GitHub Container Registry echo -e "\n=> Logging into GitHub Container Registry..." if ! echo "${GITHUB_PERSONAL_ACCESS_TOKEN}" | docker login ghcr.io -u "${GITHUB_USERNAME}" --password-stdin; then echo >&2 "Error: Failed to log in to GitHub Container Registry" exit 1 fi # Push to GitHub Container Registry echo -e "\n=> Pushing image to GitHub Container Registry..." if ! docker push "${FULL_IMAGE_NAME}"; then echo >&2 "Error: Failed to push image" echo >&2 "Please check your GitHub PAT has the required permissions:" echo >&2 " - read:packages" echo >&2 " - write:packages" exit 1 fi echo -e "\n=== Success! ===" echo "The development container image has been built and pushed" echo -e "\nTo use this image, update your devcontainer.json with:" cat << EOF { "image": "${FULL_IMAGE_NAME}" } EOF echo -e "\nNext steps:" echo "1. Update .devcontainer/devcontainer.json with the image reference above" echo "2. Rebuild your development container in VS Code" echo " (Command Palette -> 'Dev Containers: Rebuild Container')"