initial commit

This commit is contained in:
ThetaDev
2024-03-02 19:28:02 +01:00
commit ea98c81427
6 changed files with 273 additions and 0 deletions

14
.editorconfig Normal file
View File

@@ -0,0 +1,14 @@
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 88
[{Makefile,*.go}]
indent_style = tab
[*.{json,md,rst,ini,yml,yaml,xml,html,js,jsx,ts,tsx,vue,svelte}]
indent_size = 2

32
Dockerfile Normal file
View File

@@ -0,0 +1,32 @@
FROM gcr.io/kaniko-project/executor:v1.21.0-debug
SHELL ["/busybox/sh", "-c"]
# Download crane
RUN set -eux; \
case "$(arch)" in \
'x86_64') \
url='https://github.com/google/go-containerregistry/releases/download/v0.19.0/go-containerregistry_Linux_x86_64.tar.gz'; \
sha256='daa629648e1d1d10fc8bde5e6ce4176cbc0cd48a32211b28c3fd806e0fa5f29b'; \
;; \
'aarch64') \
url='https://github.com/google/go-containerregistry/releases/download/v0.19.0/go-containerregistry_Linux_arm64.tar.gz'; \
sha256='d439957c1a9d6bc0870be921e25753a7fa67bf2b2691b77ce48a6fc25bc719a0'; \
;; \
*) echo >&2 "error: unsupported architecture '$arch' (likely packaging update needed)"; exit 1 ;; \
esac; \
\
cd /workspace; \
wget -O crane.tar.gz "$url"; \
echo "$sha256 crane.tar.gz" | sha256sum -c -; \
tar -xzf crane.tar.gz; \
mv crane /kaniko; \
rm *; \
mkdir /build;
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
LABEL repository="https://code.thetadev.de/ThetaDev/action-kaniko" \
maintainer="ThetaDev <thetadev@magenta.de>"

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2024 ThetaDev
MIT LICENSE
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

1
README.md Normal file
View File

@@ -0,0 +1 @@
# Kaniko image builder

66
action.yml Normal file
View File

@@ -0,0 +1,66 @@
name: "Kaniko builder"
description: "Build and push docker images using Kaniko"
author: ThetaDev <thetadev@magenta.de>
inputs:
path:
description: Path to the build context
required: false
default: "."
registry:
description: "Docker registry where the image will be pushed"
required: false
username:
description: "Username used for authentication to the Docker registry"
required: false
password:
description: "Password used for authentication to the Docker registry"
required: false
image:
description: "Image name"
required: true
tag:
description: "Image tag"
required: false
cache:
description: "Enables build cache"
required: false
cache_ttl:
description: "How long the cache should be considered valid"
required: false
cache_registry:
description: "Docker registry meant to be used as cache"
required: false
cache_directory:
description: "Filesystem path meant to be used as cache"
required: false
build_file:
description: "Dockerfile filename"
required: false
strip_tag_prefix:
description: "Prefix to be stripped from the tag"
required: false
platforms:
description: "Target platforms to build (separated by comma)"
required: false
extra_args:
description: "Additional arguments to be passed to the kaniko executor"
required: false
tag_with_latest:
description: "Tags the built image with additional latest tag"
required: false
target:
description: Sets the target stage to build
required: false
debug:
description: Enables trace for entrypoint.sh
required: false
outputs:
image:
description: "Full reference to the built image with registry and tag"
digest:
description: "Checksum of the build image; Example: sha256:65335ed73cf17abdbcbe90354b75da0f22173486e6b92ab2f0f3d9ff9d928898"
image-tag-digest:
description: "Reference to the build image with registry and checksum; Example: index.docker.io/thetadev256/test-actions-helloworld@sha256:65335ed73cf17abdbcbe90354b75da0f22173486e6b92ab2f0f3d9ff9d928898"
runs:
using: "docker"
image: "Dockerfile"

139
entrypoint.sh Executable file
View File

@@ -0,0 +1,139 @@
#!/bin/sh
set -e pipefail
if [ "$INPUT_DEBUG" = "true" ]; then
set -x
fi
REGISTRY="${INPUT_REGISTRY:-"docker.io"}"
IMAGE="$INPUT_IMAGE"
BRANCH=$(echo "$GITHUB_REF" | sed -E "s/refs\/(heads|tags)\///g" | sed -e "s/\//-/g")
TAG=${INPUT_TAG:-$([ "$BRANCH" = "master" ] && echo latest || echo "$BRANCH")}
TAG="${TAG:-"latest"}"
TAG="${TAG#$INPUT_STRIP_TAG_PREFIX}"
USERNAME="${INPUT_USERNAME:-$GITHUB_ACTOR}"
PASSWORD="${INPUT_PASSWORD:-$GITHUB_TOKEN}"
REPOSITORY="$IMAGE"
IMAGE="${IMAGE}:${TAG}"
CONTEXT_PATH="$INPUT_PATH"
if [ "$INPUT_TAG_WITH_LATEST" = "true" ]; then
IMAGE_LATEST="${REPOSITORY}:latest"
fi
ensure() {
if [ -z "${1}" ]; then
echo >&2 "Unable to find the ${2} variable. Did you set with.${2}?"
exit 1
fi
}
ensure "${REGISTRY}" "registry"
ensure "${USERNAME}" "username"
ensure "${PASSWORD}" "password"
ensure "${IMAGE}" "image"
ensure "${TAG}" "tag"
ensure "${CONTEXT_PATH}" "path"
if [ "$REGISTRY" = "ghcr.io" ]; then
IMAGE_NAMESPACE="$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')"
# Set `/` separator, unless image is pre-fixed with dash or slash
[ -n "$REPOSITORY" ] && [[ ! "$REPOSITORY" =~ ^[-/] ]] && SEPARATOR="/"
IMAGE="$IMAGE_NAMESPACE$SEPARATOR$IMAGE"
REPOSITORY="$IMAGE_NAMESPACE$SEPARATOR$REPOSITORY"
if [ -n "$IMAGE_LATEST" ]; then
IMAGE_LATEST="${IMAGE_NAMESPACE}/${IMAGE_LATEST}"
fi
if [ -n "$INPUT_CACHE_REGISTRY" ]; then
INPUT_CACHE_REGISTRY="${REGISTRY}/${IMAGE_NAMESPACE}/${INPUT_CACHE_REGISTRY}"
fi
fi
if [ "$REGISTRY" = "docker.io" ]; then
REGISTRY="index.${REGISTRY}/v1/"
else
IMAGE="${REGISTRY}/${IMAGE}"
if [ -n "$IMAGE_LATEST" ]; then
IMAGE_LATEST="${REGISTRY}/${IMAGE_LATEST}"
fi
fi
CACHE="${INPUT_CACHE:+"--cache=true"}"
CACHE="$CACHE"${INPUT_CACHE_TTL:+" --cache-ttl=$INPUT_CACHE_TTL"}
CACHE="$CACHE"${INPUT_CACHE_REGISTRY:+" --cache-repo=$INPUT_CACHE_REGISTRY"}
CACHE="$CACHE"${INPUT_CACHE_DIRECTORY:+" --cache-dir=$INPUT_CACHE_DIRECTORY"}
CONTEXT="--context $GITHUB_WORKSPACE/$CONTEXT_PATH"
DOCKERFILE="--dockerfile $CONTEXT_PATH/${INPUT_BUILD_FILE:-Dockerfile}"
TARGET=${INPUT_TARGET:+"--target=$INPUT_TARGET"}
ARGS="$CACHE $CONTEXT $DOCKERFILE $TARGET $INPUT_EXTRA_ARGS"
cat <<EOF >/kaniko/.docker/config.json
{
"auths": {
"https://${REGISTRY}": {
"username": "${USERNAME}",
"password": "${PASSWORD}"
}
}
}
EOF
runKaniko() {
# https://github.com/GoogleContainerTools/kaniko/issues/1803
# https://github.com/GoogleContainerTools/kaniko/issues/1349
IFS=''
kaniko_cmd="executor ${1} --reproducible --force"
echo "Running kaniko command ${kaniko_cmd}"
eval "${kaniko_cmd}"
}
if [ -n "$PLATFORMS" ]; then
# Build image for all platforms, then push the manifest
platformArray=$(echo "$PLATFORMS" | sed 's/,/ /g' )
for platform in $platformArray; do
platformFn=$(echo "$platform" | sed 's#/#-#g')
DESTINATION="--no-push --tarPath /build/${platformFn}.tar --destination $IMAGE"
DIGEST="--image-name-tag-with-digest-file=/build/${platformFn}_image-tag-digest"
runKaniko "${ARGS} $DESTINATION $DIGEST"
done
crane auth login "$REGISTRY" -u "$USERNAME" -p "$PASSWORD"
DIGESTS=""
for platform in $platformArray; do
crane push "/build/${platformFn}.tar" "$IMAGE"
DIGESTS="$DIGESTS -m $(cat "/build/${platformFn}_image-tag-digest")"
done
TAGS="-t $IMAGE"
if [ -n "$IMAGE_LATEST" ]; then
TAGS="$TAGS -t $IMAGE_LATEST"
fi
manifest_cmd="crane index append $TAGS $DIGESTS"
echo "Running crane command ${manifest_cmd}"
IMAGE_TAG_DIGEST=$(eval "$manifest_cmd")
else
# Build and push image for the default platform
DESTINATION="--destination $IMAGE"
if [ -n "$IMAGE_LATEST" ]; then
DESTINATION="$DESTINATION --destination $IMAGE_LATEST"
fi
DIGEST="--image-name-tag-with-digest-file=/build/image-tag-digest"
runKaniko "${ARGS} $DESTINATION $DIGEST"
IMAGE_TAG_DIGEST=$(cat /build/image-tag-digest)
fi
DIGEST=$(echo "$IMAGE_TAG_DIGEST" | cut -f2 -d '@')
echo "image=$IMAGE" >> "$GITHUB_OUTPUT"
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"
echo "image-tag-digest=IMAGE_TAG_DIGEST" >> "$GITHUB_OUTPUT"
echo "🎉 Successfully built $IMAGE_TAG_DIGEST"