9 Commits

Author SHA1 Message Date
Alex
6030da03d4 fix: Force kaniko to run on GitHub action's environment 2020-07-15 19:03:56 +02:00
Doron Somech
daf41b1e54 feat: Add target option 2020-06-22 08:19:55 +02:00
Doron Somech
79ed56ad90 feat: Add tag_with_latest option for tagging with latest additionally
When skipping the push on unchanged digests, it's not enough to push the current tag,
which is probably semver, we also need to push the latest, so we can later check if
the latest digest equals the currently built image
2020-06-22 08:18:11 +02:00
Doron Somech
94f437184e feat: Allow custom context path 2020-06-22 08:17:58 +02:00
Doron Somech
51211d4483 fix(digest): Add support for GitHub's docker registry
Github registry doesn't support digest yet, we need to download the manifest
and calculate the digest manually

Also fixing a few other issues:
 * Multi-stage dockerfiles override /usr/local/lib, moved jq and reg to /kaniko instead
 * The digest was fetched for the current tag, which doesn't exist yet. Fetching digest for the latest tag instead
2020-06-22 08:14:46 +02:00
Alex Viscreanu
57d6d22cdf chore: Push on first build if skip_unchanged_digest isn't set 2020-06-19 14:10:56 +02:00
Alex Viscreanu
3b9302effb feat: Add option for skip pushing if the digest hasn't changed 2020-06-19 14:10:56 +02:00
Alex Viscreanu
c076596480 chore: Add Makefile for easier development 2020-06-19 13:18:55 +02:00
Alex Viscreanu
edea218783 chore: Rename function to ensure variables being set 2020-06-19 13:14:45 +02:00
6 changed files with 134 additions and 27 deletions

View File

@@ -1,3 +1,3 @@
* *
!entrypoint.sh !entrypoint.sh
.env*

View File

@@ -1,6 +1,20 @@
FROM alpine as certs
RUN apk --update add ca-certificates
FROM gcr.io/kaniko-project/executor:debug FROM gcr.io/kaniko-project/executor:debug
SHELL ["/busybox/sh", "-c"]
RUN wget -O /kaniko/jq \
https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 && \
chmod +x /kaniko/jq && \
wget -O /kaniko/reg \
https://github.com/genuinetools/reg/releases/download/v0.16.1/reg-linux-386 && \
chmod +x /kaniko/reg
COPY entrypoint.sh / COPY entrypoint.sh /
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]

24
Makefile Normal file
View File

@@ -0,0 +1,24 @@
build:
docker build -t aevea/kaniko .
run: build
docker run \
-v $(shell pwd):/tmp \
-e GITHUB_REPOSITORY \
-e GITHUB_REF \
-e GITHUB_ACTOR \
-e GITHUB_TOKEN \
-e GITHUB_WORKSPACE="/tmp" \
-e INPUT_IMAGE \
-e INPUT_CACHE \
-e INPUT_CACHE_TTL \
-e INPUT_CACHE_REGISTRY \
-e INPUT_STRIP_TAG_PREFIX \
-e INPUT_SKIP_UNCHANGED_DIGEST \
aevea/kaniko
shell: build
docker run \
-ti \
--entrypoint sh \
aevea/kaniko

View File

@@ -40,7 +40,7 @@ the most used values. So, technically there is a single required argument
## Optional Arguments ## Optional Arguments
| variable | description | required | default | | variable | description | required | default |
|------------------|----------------------------------------------------------|----------|-----------------------------| |-----------------------|-----------------------------------------------------------------|----------|-----------------|
| registry | Docker registry where the image will be pushed | false | docker.io | | registry | Docker registry where the image will be pushed | false | docker.io |
| username | Username used for authentication to the Docker registry | false | $GITHUB_ACTOR | | username | Username used for authentication to the Docker registry | false | $GITHUB_ACTOR |
| password | Password used for authentication to the Docker registry | false | | | password | Password used for authentication to the Docker registry | false | |
@@ -52,6 +52,10 @@ the most used values. So, technically there is a single required argument
| build_file | Dockerfile filename | false | Dockerfile | | build_file | Dockerfile filename | false | Dockerfile |
| extra_args | Additional arguments to be passed to the kaniko executor | false | | | extra_args | Additional arguments to be passed to the kaniko executor | false | |
| strip_tag_prefix | Prefix to be stripped from the tag | false | | | strip_tag_prefix | Prefix to be stripped from the tag | false | |
| skip_unchanged_digest | Avoids pushing the image if the build generated the same digest | false | |
| path | Path to the build context. Defaults to `.` | false | . |
| tag_with_latest | Tags the built image with additional latest tag | false | |
| target | Sets the target stage to build | false | |
**Here is where it gets specific, as the optional arguments become required depending on the registry targeted** **Here is where it gets specific, as the optional arguments become required depending on the registry targeted**

View File

@@ -5,6 +5,10 @@ branding:
icon: anchor icon: anchor
color: orange color: orange
inputs: inputs:
path:
description: Path to the build context
required: false
default: "."
registry: registry:
description: "Docker registry where the image will be pushed" description: "Docker registry where the image will be pushed"
required: false required: false
@@ -41,6 +45,15 @@ inputs:
extra_args: extra_args:
description: "Additional arguments to be passed to the kaniko executor" description: "Additional arguments to be passed to the kaniko executor"
required: false required: false
skip_unchanged_digest:
description: "Avoids pushing the image if the build generated the same digest"
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
runs: runs:
using: "docker" using: "docker"
image: "Dockerfile" image: "Dockerfile"

View File

@@ -9,24 +9,33 @@ export TAG=${TAG:-"latest"}
export TAG=${TAG#$INPUT_STRIP_TAG_PREFIX} export TAG=${TAG#$INPUT_STRIP_TAG_PREFIX}
export USERNAME=${INPUT_USERNAME:-$GITHUB_ACTOR} export USERNAME=${INPUT_USERNAME:-$GITHUB_ACTOR}
export PASSWORD=${INPUT_PASSWORD:-$GITHUB_TOKEN} export PASSWORD=${INPUT_PASSWORD:-$GITHUB_TOKEN}
export REPOSITORY=$IMAGE
export IMAGE_LATEST=${INPUT_TAG_WITH_LATEST:+"$IMAGE:latest"}
export IMAGE=$IMAGE:$TAG export IMAGE=$IMAGE:$TAG
export CONTEXT_PATH=${INPUT_PATH}
function sanitize() { function ensure() {
if [ -z "${1}" ]; then if [ -z "${1}" ]; then
echo >&2 "Unable to find the ${2}. Did you set with.${2}?" echo >&2 "Unable to find the ${2} variable. Did you set with.${2}?"
exit 1 exit 1
fi fi
} }
sanitize "${REGISTRY}" "registry" ensure "${REGISTRY}" "registry"
sanitize "${USERNAME}" "username" ensure "${USERNAME}" "username"
sanitize "${PASSWORD}" "password" ensure "${PASSWORD}" "password"
sanitize "${IMAGE}" "image" ensure "${IMAGE}" "image"
sanitize "${TAG}" "tag" ensure "${TAG}" "tag"
ensure "${CONTEXT_PATH}" "path"
if [ "$REGISTRY" == "docker.pkg.github.com" ]; then if [ "$REGISTRY" == "docker.pkg.github.com" ]; then
IMAGE_NAMESPACE="$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')" IMAGE_NAMESPACE="$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')"
export IMAGE="$IMAGE_NAMESPACE/$IMAGE" export IMAGE="$IMAGE_NAMESPACE/$IMAGE"
export REPOSITORY="$IMAGE_NAMESPACE/$REPOSITORY"
if [ ! -z $IMAGE_LATEST ]; then
export IMAGE_LATEST="$IMAGE_NAMESPACE/$IMAGE_LATEST"
fi
if [ ! -z $INPUT_CACHE_REGISTRY ]; then if [ ! -z $INPUT_CACHE_REGISTRY ]; then
export INPUT_CACHE_REGISTRY="$REGISTRY/$IMAGE_NAMESPACE/$INPUT_CACHE_REGISTRY" export INPUT_CACHE_REGISTRY="$REGISTRY/$IMAGE_NAMESPACE/$INPUT_CACHE_REGISTRY"
@@ -37,18 +46,30 @@ if [ "$REGISTRY" == "docker.io" ]; then
export REGISTRY="index.${REGISTRY}/v1/" export REGISTRY="index.${REGISTRY}/v1/"
else else
export IMAGE="$REGISTRY/$IMAGE" export IMAGE="$REGISTRY/$IMAGE"
if [ ! -z $IMAGE_LATEST ]; then
export IMAGE_LATEST="$REGISTRY/$IMAGE_LATEST"
fi
fi fi
export CACHE=${INPUT_CACHE:+"--cache=true"} export CACHE=${INPUT_CACHE:+"--cache=true"}
export CACHE=$CACHE${INPUT_CACHE_TTL:+" --cache-ttl=$INPUT_CACHE_TTL"} export CACHE=$CACHE${INPUT_CACHE_TTL:+" --cache-ttl=$INPUT_CACHE_TTL"}
export CACHE=$CACHE${INPUT_CACHE_REGISTRY:+" --cache-repo=$INPUT_CACHE_REGISTRY"} export CACHE=$CACHE${INPUT_CACHE_REGISTRY:+" --cache-repo=$INPUT_CACHE_REGISTRY"}
export CACHE=$CACHE${INPUT_CACHE_DIRECTORY:+" --cache-dir=$INPUT_CACHE_DIRECTORY"} export CACHE=$CACHE${INPUT_CACHE_DIRECTORY:+" --cache-dir=$INPUT_CACHE_DIRECTORY"}
export CONTEXT="--context $GITHUB_WORKSPACE" export CONTEXT="--context $GITHUB_WORKSPACE/$CONTEXT_PATH"
export DOCKERFILE="--dockerfile ${INPUT_BUILD_FILE:-Dockerfile}" export DOCKERFILE="--dockerfile $CONTEXT_PATH/${INPUT_BUILD_FILE:-Dockerfile}"
export DESTINATION="--destination $IMAGE" export TARGET=${INPUT_TARGET:+"--target=$INPUT_TARGET"}
export ARGS="$CACHE $CONTEXT $DOCKERFILE $DESTINATION $INPUT_EXTRA_ARGS" if [ ! -z $INPUT_SKIP_UNCHANGED_DIGEST ]; then
echo $ARGS export DESTINATION="--no-push --digest-file digest"
else
export DESTINATION="--destination $IMAGE"
if [ ! -z $IMAGE_LATEST ]; then
export DESTINATION="$DESTINATION --destination $IMAGE_LATEST"
fi
fi
export ARGS="$CACHE $CONTEXT $DOCKERFILE $TARGET $DESTINATION $INPUT_EXTRA_ARGS"
cat <<EOF >/kaniko/.docker/config.json cat <<EOF >/kaniko/.docker/config.json
{ {
@@ -61,4 +82,35 @@ cat <<EOF >/kaniko/.docker/config.json
} }
EOF EOF
/kaniko/executor $ARGS # https://github.com/GoogleContainerTools/kaniko/issues/1349
/kaniko/executor --reproducible --force $ARGS
if [ ! -z $INPUT_SKIP_UNCHANGED_DIGEST ]; then
export DIGEST=$(cat digest)
if [ "$REGISTRY" == "docker.pkg.github.com" ]; then
wget -q -O manifest --header "Authorization: Basic $(echo -n $USERNAME:$PASSWORD | base64)" https://docker.pkg.github.com/v2/$REPOSITORY/manifests/latest || true
export REMOTE="sha256:$(cat manifest | sha256sum | awk '{ print $1 }')"
else
export REMOTE=$(reg digest -u $USERNAME -p $PASSWORD $REGISTRY/$REPOSITORY | tail -1)
fi
if [ "$DIGEST" == "$REMOTE" ]; then
echo "Digest hasn't changed, skipping, $DIGEST"
echo "Done 🎉️"
exit 0
fi
export DESTINATION="--destination $IMAGE"
if [ ! -z $IMAGE_LATEST ]; then
export DESTINATION="$DESTINATION --destination $IMAGE_LATEST"
fi
export ARGS="$CACHE $CONTEXT $DOCKERFILE $TARGET $DESTINATION $INPUT_EXTRA_ARGS"
echo "Pushing image..."
/kaniko/executor --reproducible $ARGS >/dev/null 2>&1
echo "Done 🎉️"
fi