From a0b7f159ee990ef9ccb514eee13beb854affe5a9 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Wed, 14 Feb 2024 16:56:43 +0100 Subject: [PATCH 1/7] wip: create util script for building/pushing Docker images --- bin/docker-helper.sh | 124 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 bin/docker-helper.sh diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh new file mode 100755 index 0000000000000..d5ca4e713b1d6 --- /dev/null +++ b/bin/docker-helper.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash + +set -e + +function usage() { + echo "A set of commands that facilitate building and pushing versioned Docker images" + echo "" + echo "USAGE" + echo " docker-helper [options]" + echo "" + echo "Commands:" + echo " build" + echo " Build the Docker image for the project in the working directory" + echo "" + echo " push" + echo " Push the Docker image for the project in the working directory" + echo "" + echo " help" + echo " Show this message" +} + +function get_current_version() { + egrep -h "^__version__ = " ${VERSION_FILE} | sed -r 's/^__version__ = "(.*)"/\1/g' +} + +function set_defaults() { + if [ "$DOCKERFILE" = "" ]; then DOCKERFILE=Dockerfile; fi + if [ "$SOURCE_IMAGE_NAME" = "" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi + if [ "$TARGET_IMAGE_NAME" = "" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi +} + +function docker_build() { + # start build + # --add-host: Fix for Centos host OS + # --build-arg BUILDKIT_INLINE_CACHE=1: Instruct buildkit to inline the caching information into the image + # --cache-from: Use the inlined caching information when building the image + DOCKER_BUILDKIT=1 docker buildx build --pull --progress=plain \ + --cache-from $TAG --build-arg BUILDKIT_INLINE_CACHE=1 \ + --build-arg LOCALSTACK_PRE_RELEASE=$(cat localstack/__init__.py | grep '^__version__ =' | grep -v '.dev' >> /dev/null && echo "0" || echo "1") \ + --build-arg LOCALSTACK_BUILD_GIT_HASH=$(git rev-parse --short HEAD) \ + --build-arg=LOCALSTACK_BUILD_DATE=$(date -u +"%Y-%m-%d") \ + --build-arg=LOCALSTACK_BUILD_VERSION=$IMAGE_TAG \ + --add-host="localhost.localdomain:127.0.0.1" \ + -t $TAG $DOCKER_BUILD_FLAGS . -f $DOCKERFILE +} + +function docker_build_multiarch() { + ## Build the Multi-Arch full Docker image + # Make sure to prepare your environment for cross-platform docker builds! (see doc/developer_guides/README.md) + # Multi-Platform builds cannot be loaded to the docker daemon from buildx, so we can't add "--load". + DOCKER_BUILD_FLAGS="--platform linux/amd64,linux/arm64" docker_build +} + +function docker_push_main() { + # Push a single platform-specific Docker image to registry IF we are currently on the master branch + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^master$$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*master$$' | sed 's/[* ]//g' || true`; \ + test "$$CURRENT_BRANCH" != 'master' && echo "Not on master branch.") || \ + ((test "$$DOCKER_USERNAME" = '' || test "$$DOCKER_PASSWORD" = '' ) && \ + echo "Skipping docker push as no credentials are provided.") || \ + (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $$2}'`"; \ + test "$$REMOTE_ORIGIN" != 'https://github.com/localstack/localstack.git' && \ + test "$$REMOTE_ORIGIN" != 'git@github.com:localstack/localstack.git' && \ + echo "This is a fork and not the main repo.") || \ + ( \ + docker info | grep Username || docker login -u $$DOCKER_USERNAME -p $$DOCKER_PASSWORD; \ + docker tag $SOURCE_IMAGE_NAME:latest $TARGET_IMAGE_NAME:latest-$PLATFORM && \ + ((! (git diff HEAD~1 localstack/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ + echo "Only pushing tag 'latest' as version has not changed.") || \ + (docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:stable-$PLATFORM && \ + docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:$IMAGE_TAG-$PLATFORM && \ + docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:$MAJOR_VERSION-$PLATFORM && \ + docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION-$PLATFORM && \ + docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION-$PLATFORM && \ + docker push $TARGET_IMAGE_NAME:stable-$PLATFORM && \ + docker push $TARGET_IMAGE_NAME:$IMAGE_TAG-$PLATFORM && \ + docker push $TARGET_IMAGE_NAME:$MAJOR_VERSION-$PLATFORM && \ + docker push $TARGET_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION-$PLATFORM && \ + docker push $TARGET_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION-$PLATFORM \ + )) && \ + docker push $TARGET_IMAGE_NAME:latest-$PLATFORM \ + ) +} + + +# commands + +function cmd-build() { + set_defaults + docker_build +} + +function cmd-build-multiarch() { + set_defaults + docker_build_multiarch +} + +function cmd-push() { + set_defaults + docker_push +} + +function cmd-push-main() { + set_defaults + docker_push_main +} + +function main() { + [[ $# -lt 1 ]] && { usage; exit 1; } + + command_name=$1 + shift + + # invoke command + case $command_name in + "build") cmd-build "$@" ;; + "build-multiarch") cmd-build-multiarch "$@" ;; + "push") cmd-push "$@" ;; + "push-main") cmd-push-main "$@" ;; + "help") usage && exit 0 ;; + *) usage && exit 1 ;; + esac +} + +main "$@" From 6122bc090107f278b805c37d4188868dd6fbebc6 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Thu, 15 Feb 2024 15:51:16 +0100 Subject: [PATCH 2/7] auto-determine $PYTHON_CODE_DIR --- bin/docker-helper.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index d5ca4e713b1d6..f8555925beaa2 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -24,6 +24,19 @@ function get_current_version() { } function set_defaults() { + if [ "$PYTHON_CODE_DIR" = "" ]; then + # try to determine the main Python code directory + entries=$(find . -name '*.py' | grep -v .venv | xargs grep -R '^__version__ =' | wc -l) + if [[ $entries -gt 1 ]]; then + echo "Unable to find __version__ in project Python files." + echo "Please configure PYTHON_CODE_DIR with the path to the main Python code directory" + exit 1 + fi + entry=$(find . -name '*.py' | grep -v .venv | xargs grep -R '^__version__ =' | sed -ne 's/\(.*\):.*/\1/') + PYTHON_CODE_DIR=$(dirname entry) + fi + + # set defaults if [ "$DOCKERFILE" = "" ]; then DOCKERFILE=Dockerfile; fi if [ "$SOURCE_IMAGE_NAME" = "" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi if [ "$TARGET_IMAGE_NAME" = "" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi @@ -36,7 +49,7 @@ function docker_build() { # --cache-from: Use the inlined caching information when building the image DOCKER_BUILDKIT=1 docker buildx build --pull --progress=plain \ --cache-from $TAG --build-arg BUILDKIT_INLINE_CACHE=1 \ - --build-arg LOCALSTACK_PRE_RELEASE=$(cat localstack/__init__.py | grep '^__version__ =' | grep -v '.dev' >> /dev/null && echo "0" || echo "1") \ + --build-arg LOCALSTACK_PRE_RELEASE=$(cat $PYTHON_CODE_DIR/__init__.py | grep '^__version__ =' | grep -v '.dev' >> /dev/null && echo "0" || echo "1") \ --build-arg LOCALSTACK_BUILD_GIT_HASH=$(git rev-parse --short HEAD) \ --build-arg=LOCALSTACK_BUILD_DATE=$(date -u +"%Y-%m-%d") \ --build-arg=LOCALSTACK_BUILD_VERSION=$IMAGE_TAG \ @@ -58,13 +71,13 @@ function docker_push_main() { ((test "$$DOCKER_USERNAME" = '' || test "$$DOCKER_PASSWORD" = '' ) && \ echo "Skipping docker push as no credentials are provided.") || \ (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $$2}'`"; \ - test "$$REMOTE_ORIGIN" != 'https://github.com/localstack/localstack.git' && \ - test "$$REMOTE_ORIGIN" != 'git@github.com:localstack/localstack.git' && \ + test "$$REMOTE_ORIGIN" != 'https://github.com/localstack/'* && \ + test "$$REMOTE_ORIGIN" != 'git@github.com:localstack/'* && \ echo "This is a fork and not the main repo.") || \ ( \ docker info | grep Username || docker login -u $$DOCKER_USERNAME -p $$DOCKER_PASSWORD; \ docker tag $SOURCE_IMAGE_NAME:latest $TARGET_IMAGE_NAME:latest-$PLATFORM && \ - ((! (git diff HEAD~1 localstack/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ + ((! (git diff HEAD~1 $PYTHON_CODE_DIR/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ echo "Only pushing tag 'latest' as version has not changed.") || \ (docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:stable-$PLATFORM && \ docker tag $TARGET_IMAGE_NAME:latest-$PLATFORM $TARGET_IMAGE_NAME:$IMAGE_TAG-$PLATFORM && \ From aefc26b2a30eabf2b87de20e161eeb1705a009b9 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Thu, 15 Feb 2024 16:44:51 +0100 Subject: [PATCH 3/7] minor extensions --- bin/docker-helper.sh | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index f8555925beaa2..aea0cc38a2b48 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -24,37 +24,46 @@ function get_current_version() { } function set_defaults() { - if [ "$PYTHON_CODE_DIR" = "" ]; then + # assert required variables are defined + if [ -z "$IMAGE_NAME" ]; then echo "Please define Docker image name via IMAGE_NAME"; exit 1; fi + + # set defaults + + if [ -z "$PYTHON_CODE_DIR" ]; then # try to determine the main Python code directory entries=$(find . -name '*.py' | grep -v .venv | xargs grep -R '^__version__ =' | wc -l) - if [[ $entries -gt 1 ]]; then + if [[ $entries -ne 1 ]]; then echo "Unable to find __version__ in project Python files." echo "Please configure PYTHON_CODE_DIR with the path to the main Python code directory" exit 1 fi - entry=$(find . -name '*.py' | grep -v .venv | xargs grep -R '^__version__ =' | sed -ne 's/\(.*\):.*/\1/') - PYTHON_CODE_DIR=$(dirname entry) + entry=$(find . -name '*.py' | grep -v .venv | xargs grep -R '^__version__ =' | sed -e 's/\(.*\):.*/\1/') + PYTHON_CODE_DIR=$(dirname $entry) fi - # set defaults - if [ "$DOCKERFILE" = "" ]; then DOCKERFILE=Dockerfile; fi - if [ "$SOURCE_IMAGE_NAME" = "" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi - if [ "$TARGET_IMAGE_NAME" = "" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi + if [ -z "$DOCKERFILE" ]; then DOCKERFILE=Dockerfile; fi + if [ -z "$SOURCE_IMAGE_NAME" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi + if [ -z "$TARGET_IMAGE_NAME" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi + if [ -z "$TAG" ]; then TAG=$IMAGE_NAME; fi + if [ -z "$MAIN_BRANCH" ]; then MAIN_BRANCH=master; fi } function docker_build() { # start build + + # by default we load the result to the docker daemon + if [ "$DOCKER_BUILD_FLAGS" = "" ]; then DOCKER_BUILD_FLAGS="--load"; fi # --add-host: Fix for Centos host OS # --build-arg BUILDKIT_INLINE_CACHE=1: Instruct buildkit to inline the caching information into the image # --cache-from: Use the inlined caching information when building the image DOCKER_BUILDKIT=1 docker buildx build --pull --progress=plain \ - --cache-from $TAG --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$TAG" --build-arg BUILDKIT_INLINE_CACHE=1 \ --build-arg LOCALSTACK_PRE_RELEASE=$(cat $PYTHON_CODE_DIR/__init__.py | grep '^__version__ =' | grep -v '.dev' >> /dev/null && echo "0" || echo "1") \ --build-arg LOCALSTACK_BUILD_GIT_HASH=$(git rev-parse --short HEAD) \ --build-arg=LOCALSTACK_BUILD_DATE=$(date -u +"%Y-%m-%d") \ --build-arg=LOCALSTACK_BUILD_VERSION=$IMAGE_TAG \ --add-host="localhost.localdomain:127.0.0.1" \ - -t $TAG $DOCKER_BUILD_FLAGS . -f $DOCKERFILE + -t "$TAG" $DOCKER_BUILD_FLAGS . -f $DOCKERFILE } function docker_build_multiarch() { @@ -66,16 +75,16 @@ function docker_build_multiarch() { function docker_push_main() { # Push a single platform-specific Docker image to registry IF we are currently on the master branch - (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^master$$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*master$$' | sed 's/[* ]//g' || true`; \ - test "$$CURRENT_BRANCH" != 'master' && echo "Not on master branch.") || \ - ((test "$$DOCKER_USERNAME" = '' || test "$$DOCKER_PASSWORD" = '' ) && \ + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^master$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*master$' | sed 's/[* ]//g' || true`; \ + test "$CURRENT_BRANCH" != 'master' && echo "Not on master branch.") || \ + ((test "$DOCKER_USERNAME" = '' || test "$DOCKER_PASSWORD" = '' ) && \ echo "Skipping docker push as no credentials are provided.") || \ - (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $$2}'`"; \ - test "$$REMOTE_ORIGIN" != 'https://github.com/localstack/'* && \ - test "$$REMOTE_ORIGIN" != 'git@github.com:localstack/'* && \ + (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $2}'`"; \ + test "$REMOTE_ORIGIN" != 'https://github.com/localstack/'* && \ + test "$REMOTE_ORIGIN" != 'git@github.com:localstack/'* && \ echo "This is a fork and not the main repo.") || \ ( \ - docker info | grep Username || docker login -u $$DOCKER_USERNAME -p $$DOCKER_PASSWORD; \ + docker info | grep Username || docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ docker tag $SOURCE_IMAGE_NAME:latest $TARGET_IMAGE_NAME:latest-$PLATFORM && \ ((! (git diff HEAD~1 $PYTHON_CODE_DIR/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ echo "Only pushing tag 'latest' as version has not changed.") || \ From 438068797e6e475b2172fdb1215ead4c46563e2c Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Fri, 16 Feb 2024 00:31:48 +0100 Subject: [PATCH 4/7] add push-manifests target --- bin/docker-helper.sh | 66 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index aea0cc38a2b48..3bb459284fb65 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -74,9 +74,9 @@ function docker_build_multiarch() { } function docker_push_main() { - # Push a single platform-specific Docker image to registry IF we are currently on the master branch - (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^master$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*master$' | sed 's/[* ]//g' || true`; \ - test "$CURRENT_BRANCH" != 'master' && echo "Not on master branch.") || \ + ## Push a single platform-specific Docker image to registry, if we are currently on the main branch + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; \ + test "$CURRENT_BRANCH" != "$MAIN_BRANCH" && echo "Not on main branch.") || \ ((test "$DOCKER_USERNAME" = '' || test "$DOCKER_PASSWORD" = '' ) && \ echo "Skipping docker push as no credentials are provided.") || \ (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $2}'`"; \ @@ -103,6 +103,45 @@ function docker_push_main() { ) } +function docker_push_manifests_main() { + ## Create and push manifests for the multi-arch Docker image, if we are currently on the main branch + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; \ + test "$CURRENT_BRANCH" != "$MAIN_BRANCH" && echo "Not on main branch.") || \ + ((test "$DOCKER_USERNAME" = '' || test "$DOCKER_PASSWORD" = '' ) && \ + echo "Skipping docker manifest push as no credentials are provided.") || \ + (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $2}'`"; \ + test "$REMOTE_ORIGIN" != 'https://github.com/localstack/localstack.git' && \ + test "$REMOTE_ORIGIN" != 'git@github.com:localstack/localstack.git' && \ + echo "This is a fork and not the main repo.") || \ + ( \ + docker info | grep Username || docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ + docker manifest create $MANIFEST_IMAGE_NAME:latest --amend $MANIFEST_IMAGE_NAME:latest-amd64 --amend $MANIFEST_IMAGE_NAME:latest-arm64 && \ + ((! (git diff HEAD~1 localstack/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ + echo "Only pushing tag 'latest' as version has not changed.") || \ + (docker manifest create $MANIFEST_IMAGE_NAME:$IMAGE_TAG \ + --amend $MANIFEST_IMAGE_NAME:$IMAGE_TAG-amd64 \ + --amend $MANIFEST_IMAGE_NAME:$IMAGE_TAG-arm64 && \ + docker manifest create $MANIFEST_IMAGE_NAME:stable \ + --amend $MANIFEST_IMAGE_NAME:stable-amd64 \ + --amend $MANIFEST_IMAGE_NAME:stable-arm64 && \ + docker manifest create $MANIFEST_IMAGE_NAME:$MAJOR_VERSION \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION-amd64 \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION-arm64 && \ + docker manifest create $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION-amd64 \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION-arm64 && \ + docker manifest create $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION-amd64 \ + --amend $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION-arm64 && \ + docker manifest push $MANIFEST_IMAGE_NAME:stable && \ + docker manifest push $MANIFEST_IMAGE_NAME:$IMAGE_TAG && \ + docker manifest push $MANIFEST_IMAGE_NAME:$MAJOR_VERSION && \ + docker manifest push $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION && \ + docker manifest push $MANIFEST_IMAGE_NAME:$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION)) && \ + docker manifest push $MANIFEST_IMAGE_NAME:latest \ + ) +} + # commands @@ -116,14 +155,14 @@ function cmd-build-multiarch() { docker_build_multiarch } -function cmd-push() { +function cmd-push-main() { set_defaults - docker_push + docker_push_main } -function cmd-push-main() { +function cmd-push-manifests-main() { set_defaults - docker_push_main + docker_push_manifests_main } function main() { @@ -134,12 +173,13 @@ function main() { # invoke command case $command_name in - "build") cmd-build "$@" ;; - "build-multiarch") cmd-build-multiarch "$@" ;; - "push") cmd-push "$@" ;; - "push-main") cmd-push-main "$@" ;; - "help") usage && exit 0 ;; - *) usage && exit 1 ;; + "build") cmd-build "$@" ;; + "build-multiarch") cmd-build-multiarch "$@" ;; + "push") cmd-push "$@" ;; + "push-main") cmd-push-main "$@" ;; + "push-manifests-main") cmd-push-manifests-main "$@" ;; + "help") usage && exit 0 ;; + *) usage && exit 1 ;; esac } From a3cba16d41b2672f79c55cd621cb065f941afc41 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Mon, 19 Feb 2024 08:57:15 +0100 Subject: [PATCH 5/7] minor fixes --- bin/docker-helper.sh | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index 3bb459284fb65..502f43f57135f 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -44,6 +44,7 @@ function set_defaults() { if [ -z "$DOCKERFILE" ]; then DOCKERFILE=Dockerfile; fi if [ -z "$SOURCE_IMAGE_NAME" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi if [ -z "$TARGET_IMAGE_NAME" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi + if [ -z "$MANIFEST_IMAGE_NAME" ]; then MANIFEST_IMAGE_NAME=$IMAGE_NAME; fi if [ -z "$TAG" ]; then TAG=$IMAGE_NAME; fi if [ -z "$MAIN_BRANCH" ]; then MAIN_BRANCH=master; fi } @@ -75,16 +76,18 @@ function docker_build_multiarch() { function docker_push_main() { ## Push a single platform-specific Docker image to registry, if we are currently on the main branch - (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; \ - test "$CURRENT_BRANCH" != "$MAIN_BRANCH" && echo "Not on main branch.") || \ + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || \ + ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z/_-]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; + echo "Current git branch: '$CURRENT_BRANCH'" + test "$CURRENT_BRANCH" != "$MAIN_BRANCH" && echo "Not on main branch.") || \ ((test "$DOCKER_USERNAME" = '' || test "$DOCKER_PASSWORD" = '' ) && \ echo "Skipping docker push as no credentials are provided.") || \ - (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $2}'`"; \ - test "$REMOTE_ORIGIN" != 'https://github.com/localstack/'* && \ - test "$REMOTE_ORIGIN" != 'git@github.com:localstack/'* && \ + (REMOTE_ORIGIN="`git remote -v | grep 'localstack/' | grep origin | grep push | awk '{print $2}'`"; \ + [[ "$REMOTE_ORIGIN" != 'https://github.com/localstack/'* ]] && \ + [[ "$REMOTE_ORIGIN" != 'git@github.com:localstack/'* ]] && \ echo "This is a fork and not the main repo.") || \ ( \ - docker info | grep Username || docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ docker tag $SOURCE_IMAGE_NAME:latest $TARGET_IMAGE_NAME:latest-$PLATFORM && \ ((! (git diff HEAD~1 $PYTHON_CODE_DIR/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ echo "Only pushing tag 'latest' as version has not changed.") || \ @@ -105,18 +108,20 @@ function docker_push_main() { function docker_push_manifests_main() { ## Create and push manifests for the multi-arch Docker image, if we are currently on the main branch - (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; \ + (CURRENT_BRANCH=`(git rev-parse --abbrev-ref HEAD | grep '^'$MAIN_BRANCH'$' || \ + ((git branch -a | grep 'HEAD detached at [0-9a-zA-Z/_-]*)') && git branch -a)) | grep '^[* ]*'$MAIN_BRANCH'$' | sed 's/[* ]//g' || true`; + echo "Current git branch: '$CURRENT_BRANCH'" test "$CURRENT_BRANCH" != "$MAIN_BRANCH" && echo "Not on main branch.") || \ ((test "$DOCKER_USERNAME" = '' || test "$DOCKER_PASSWORD" = '' ) && \ echo "Skipping docker manifest push as no credentials are provided.") || \ - (REMOTE_ORIGIN="`git remote -v | grep '/localstack' | grep origin | grep push | awk '{print $2}'`"; \ - test "$REMOTE_ORIGIN" != 'https://github.com/localstack/localstack.git' && \ - test "$REMOTE_ORIGIN" != 'git@github.com:localstack/localstack.git' && \ + (REMOTE_ORIGIN="`git remote -v | grep 'localstack/' | grep origin | grep push | awk '{print $2}'`"; \ + [[ "$REMOTE_ORIGIN" != 'https://github.com/localstack/'* ]] && \ + [[ "$REMOTE_ORIGIN" != 'git@github.com:localstack/'* ]] && \ echo "This is a fork and not the main repo.") || \ ( \ - docker info | grep Username || docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD; \ docker manifest create $MANIFEST_IMAGE_NAME:latest --amend $MANIFEST_IMAGE_NAME:latest-amd64 --amend $MANIFEST_IMAGE_NAME:latest-arm64 && \ - ((! (git diff HEAD~1 localstack/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ + ((! (git diff HEAD~1 $PYTHON_CODE_DIR/__init__.py | grep '^+__version__ =' | grep -v '.dev') && \ echo "Only pushing tag 'latest' as version has not changed.") || \ (docker manifest create $MANIFEST_IMAGE_NAME:$IMAGE_TAG \ --amend $MANIFEST_IMAGE_NAME:$IMAGE_TAG-amd64 \ @@ -175,7 +180,6 @@ function main() { case $command_name in "build") cmd-build "$@" ;; "build-multiarch") cmd-build-multiarch "$@" ;; - "push") cmd-push "$@" ;; "push-main") cmd-push-main "$@" ;; "push-manifests-main") cmd-push-manifests-main "$@" ;; "help") usage && exit 0 ;; From 0c4b4b3044e260980677b6f4386cfe6d4b395d41 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Sat, 24 Feb 2024 14:58:49 +0100 Subject: [PATCH 6/7] add parsing of major/minor/patch versions --- bin/docker-helper.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index 502f43f57135f..57535e2ab02fb 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -12,8 +12,11 @@ function usage() { echo " build" echo " Build the Docker image for the project in the working directory" echo "" - echo " push" - echo " Push the Docker image for the project in the working directory" + echo " push-main" + echo " Push the Docker image for the project if we're on the main branch" + echo "" + echo " push-manifests-main" + echo " Push the multi-arch Docker manifests if we're on the main branch" echo "" echo " help" echo " Show this message" @@ -41,6 +44,12 @@ function set_defaults() { PYTHON_CODE_DIR=$(dirname $entry) fi + # determine major/minor/patch versions + IMAGE_TAG?=$(cat $PYTHON_CODE_DIR/__init__.py | grep '^__version__ =' | sed "s/__version__ = ['\"]\(.*\)['\"].*/\1/") + MAJOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f1) + MINOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f2) + PATCH_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f3) + if [ -z "$DOCKERFILE" ]; then DOCKERFILE=Dockerfile; fi if [ -z "$SOURCE_IMAGE_NAME" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi if [ -z "$TARGET_IMAGE_NAME" ]; then TARGET_IMAGE_NAME=$IMAGE_NAME; fi @@ -50,7 +59,7 @@ function set_defaults() { } function docker_build() { - # start build + # start build of a platform-specific image (this target will get called for multiple archs like AMD64/ARM64) # by default we load the result to the docker daemon if [ "$DOCKER_BUILD_FLAGS" = "" ]; then DOCKER_BUILD_FLAGS="--load"; fi From be2cbf2ace5edbca7f724682c5386127d6a84f43 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Mon, 26 Feb 2024 18:45:55 +0100 Subject: [PATCH 7/7] minor fix in version parsing --- bin/docker-helper.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/docker-helper.sh b/bin/docker-helper.sh index 57535e2ab02fb..934f0ab3c233d 100755 --- a/bin/docker-helper.sh +++ b/bin/docker-helper.sh @@ -45,10 +45,12 @@ function set_defaults() { fi # determine major/minor/patch versions - IMAGE_TAG?=$(cat $PYTHON_CODE_DIR/__init__.py | grep '^__version__ =' | sed "s/__version__ = ['\"]\(.*\)['\"].*/\1/") - MAJOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f1) - MINOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f2) - PATCH_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f3) + if [ -z "$IMAGE_TAG" ]; then + IMAGE_TAG=$(cat $PYTHON_CODE_DIR/__init__.py | grep '^__version__ =' | sed "s/__version__ = ['\"]\(.*\)['\"].*/\1/") + fi + if [ -z "$MAJOR_VERSION" ]; then MAJOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f1); fi + if [ -z "$MINOR_VERSION" ]; then MINOR_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f2); fi + if [ -z "$PATCH_VERSION" ]; then PATCH_VERSION=$(echo ${IMAGE_TAG} | cut -d '.' -f3); fi if [ -z "$DOCKERFILE" ]; then DOCKERFILE=Dockerfile; fi if [ -z "$SOURCE_IMAGE_NAME" ]; then SOURCE_IMAGE_NAME=$IMAGE_NAME; fi