#!/busybox/sh # scotty-git shared action: build and push a container image with Kaniko. # Inputs arrive as INPUT_ environment variables (see action.yml). # Never prints credentials. The registry login only exists inside this short-lived container. set -eu fail() { printf '::error::%s\n' "$*"; exit 1; } DESTINATION=${INPUT_DESTINATION:-} CONTEXT=${INPUT_CONTEXT:-.} DOCKERFILE=${INPUT_DOCKERFILE:-Dockerfile} PUSH=${INPUT_PUSH:-true} REGISTRY=${INPUT_REGISTRY:-} USERNAME=${INPUT_USERNAME:-} PASSWORD=${INPUT_PASSWORD:-} GCP_KEY_JSON=${INPUT_GCP_KEY_JSON:-} CACHE_REPO=${INPUT_CACHE_REPO:-} BUILD_ARGS=${INPUT_BUILD_ARGS:-} EXTRA_ARGS=${INPUT_EXTRA_ARGS:-} # ---- Source: the repository the job already checked out ---- WS=${GITHUB_WORKSPACE:-} if [ -z "$WS" ] || [ ! -d "$WS" ]; then fail "No checked-out workspace found. Add 'uses: actions/checkout@v4' before this step."; fi if [ ! -d "$WS/$CONTEXT" ]; then fail "Build context '$CONTEXT' does not exist in the repository."; fi if [ ! -f "$WS/$DOCKERFILE" ]; then fail "Dockerfile '$DOCKERFILE' not found in the repository."; fi # ---- Destinations ---- DESTS=$(printf '%s' "$DESTINATION" | tr ',\n' ' ') if [ "$PUSH" = "true" ] && [ -z "$(printf '%s' "$DESTS" | tr -d ' ')" ]; then fail "'destination' is required when push is true." fi # ---- Registry login (written only inside this container) ---- mkdir -p /kaniko/.docker if [ -z "$REGISTRY" ]; then for d in $DESTS; do REGISTRY=${d%%/*}; break; done if [ -z "$REGISTRY" ] && [ -n "$CACHE_REPO" ]; then REGISTRY=${CACHE_REPO%%/*}; fi fi AUTH="" if [ -n "$GCP_KEY_JSON" ]; then AUTH=$(printf '_json_key:%s' "$GCP_KEY_JSON" | base64 | tr -d '\n') elif [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then AUTH=$(printf '%s:%s' "$USERNAME" "$PASSWORD" | base64 | tr -d '\n') elif [ -n "$USERNAME" ] || [ -n "$PASSWORD" ]; then fail "Set both 'username' and 'password', or neither." fi if [ -n "$AUTH" ]; then if [ -z "$REGISTRY" ]; then fail "Could not tell which registry the credentials are for; set 'registry'."; fi printf '{"auths":{"%s":{"auth":"%s"}}}\n' "$REGISTRY" "$AUTH" > /kaniko/.docker/config.json echo "Logged in to $REGISTRY for this build." fi # ---- Executor flags ---- set -- --context "dir://$WS/$CONTEXT" --dockerfile "$WS/$DOCKERFILE" --cleanup if [ "$PUSH" = "true" ]; then for d in $DESTS; do set -- "$@" --destination "$d"; done set -- "$@" --digest-file /kaniko/digest else set -- "$@" --no-push for d in $DESTS; do set -- "$@" --destination "$d"; done fi if [ -n "$CACHE_REPO" ]; then set -- "$@" --cache=true --cache-repo "$CACHE_REPO"; fi OLDIFS=$IFS IFS=' ' for a in $BUILD_ARGS; do if [ -n "$a" ]; then set -- "$@" --build-arg "$a"; fi done IFS=$OLDIFS # shellcheck disable=SC2086 # extra_args is deliberately split into separate flags if [ -n "$EXTRA_ARGS" ]; then set -- "$@" $EXTRA_ARGS; fi echo "Building $DOCKERFILE (context: $CONTEXT)$( [ "$PUSH" = "true" ] && echo " -> $DESTS" || echo ", not pushing")" /kaniko/executor "$@" # ---- Output ---- if [ "$PUSH" = "true" ] && [ -f /kaniko/digest ]; then DIGEST=$(cat /kaniko/digest) echo "Pushed: $DIGEST" if [ -n "${GITHUB_OUTPUT:-}" ]; then echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"; fi fi exit 0