From 40a0a87530c43d68bb5b165ebdb2c63c5967eed6 Mon Sep 17 00:00:00 2001 From: 0x1def <0x1def@flakybit.net> Date: Tue, 3 Sep 2024 22:08:33 +0300 Subject: [PATCH] Imported CI --- .ci/image.sh | 18 ++++++++++ .ci/lib.sh | 77 ++++++++++++++++++++++++++++++++++++++++ .ci/login-ecr.sh | 12 +++++++ .ci/publish-external.sh | 19 ++++++++++ .ci/set-env.sh | 26 ++++++++++++++ .woodpecker.yaml | 78 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 230 insertions(+) create mode 100755 .ci/image.sh create mode 100755 .ci/lib.sh create mode 100755 .ci/login-ecr.sh create mode 100755 .ci/publish-external.sh create mode 100755 .ci/set-env.sh create mode 100644 .woodpecker.yaml diff --git a/.ci/image.sh b/.ci/image.sh new file mode 100755 index 0000000..23828a8 --- /dev/null +++ b/.ci/image.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -eu + +set -a +. .ci/lib.sh +set +a + +echo "Setting authentication for $HARBOR_REGISTRY" +setRegistryAuth "$KANIKO_AUTH_FILE" "$HARBOR_REGISTRY" "$HARBOR_CREDS" + +image="$APP_NAME/$APP_COMPONENT:$APP_VERSION" +dockerfile="./Dockerfile" + +echo "Building $image image" +executor -c ./ -f "$dockerfile" -d "$HARBOR_REGISTRY/$image" + +echo 'Done' + diff --git a/.ci/lib.sh b/.ci/lib.sh new file mode 100755 index 0000000..894cc35 --- /dev/null +++ b/.ci/lib.sh @@ -0,0 +1,77 @@ +#!/bin/sh +set -eu + +export CI_ENV_FILE='.ci/env' +if [ -f "$CI_ENV_FILE" ]; then + . "$CI_ENV_FILE" +fi + + +# $1 - retries count +retry () { + retries="$1" + shift + + count=0 + wait=5 + until "$@"; do + exit=$? + wait=$((wait * 2)) + count=$((count + 1)) + if [ $count -lt "$retries" ]; then + echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." + sleep $wait + else + echo "Retry $count/$retries exited $exit, no more retries left." + return $exit + fi + done + + unset retries count wait + return 0 +} + +getAppVersion () { + app_version=$(printf '%s' "$CI_COMMIT_SHA" | head -c 8) + if [ -n "${CI_MANUAL_TAG-}" ]; then + app_version="$CI_MANUAL_TAG" + elif [ -n "${CI_COMMIT_TAG-}" ]; then + app_version="$CI_COMMIT_TAG" + fi + + printf '%s' "$app_version" + unset app_version +} + +getAppRelease () { + release=false + if [ -n "${CI_MANUAL_TAG-}" ]; then + release=true + elif [ -n "${CI_COMMIT_TAG-}" ]; then + release=true + fi + + printf '%s' "$release" + unset release +} + +# $1 - configuration file +# $2 - registry +# $3 - registry creds in form of 'user:pass' +setRegistryAuth () { + auth=$(printf '%s' "$3" | base64 -w 0) + auths=$(printf '{"auths":{"%s":{"auth":"%s"}}}' "$2" "$auth") + printf '%s' "$auths" > "$1" + + unset auth auths +} + +# AWS_ACCESS_KEY_ID - login +# AWS_SECRET_ACCESS_KEY - password +# $1 - file with token +setAwsEcrCreds () { + password=$(aws ecr-public get-login-password --region us-east-1) + printf '%s:%s' "AWS" "$password" > "$1" + + unset password +} diff --git a/.ci/login-ecr.sh b/.ci/login-ecr.sh new file mode 100755 index 0000000..f96af09 --- /dev/null +++ b/.ci/login-ecr.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -eu + +set -a +. .ci/lib.sh +set +a + +echo Obtaining AWS Public ECR credentials + +setAwsEcrCreds "$AWS_CREDS_FILE" + +echo Done diff --git a/.ci/publish-external.sh b/.ci/publish-external.sh new file mode 100755 index 0000000..d66d48f --- /dev/null +++ b/.ci/publish-external.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +set -a +. .ci/lib.sh +set +a + +src_image="$HARBOR_REGISTRY/$APP_NAME/$APP_COMPONENT:$APP_VERSION" +dst_image="$DEST_REGISTRY/$EXTERNAL_REGISTRY_NAMESPACE/$APP_NAME-$APP_COMPONENT:$APP_VERSION" + +if printf '%s' "$DEST_REGISTRY" | grep -q "ecr.aws"; then + dst_image="$DEST_REGISTRY/$EXTERNAL_REGISTRY_NAMESPACE/$APP_NAME/$APP_COMPONENT:$APP_VERSION" + DEST_CREDS=$(cat "$AWS_CREDS_FILE") +fi + +echo "Pushing $dst_image" +retry 2 skopeo copy --dest-creds="$DEST_CREDS" "docker://$src_image" "docker://$dst_image" + +echo 'Done' diff --git a/.ci/set-env.sh b/.ci/set-env.sh new file mode 100755 index 0000000..ec397fa --- /dev/null +++ b/.ci/set-env.sh @@ -0,0 +1,26 @@ +#!/bin/sh +set -eu + +set -a +. .ci/lib.sh +set +a + +echo Setting up environment + +app_name='mongodb' +printf 'APP_NAME=%s\n' "$app_name" >> "$CI_ENV_FILE" + +app_component='server' +printf 'APP_COMPONENT=%s\n' "$app_component" >> "$CI_ENV_FILE" + +printf 'APP_VERSION=%s\n' "$(getAppVersion)" >> "$CI_ENV_FILE" + +printf 'HARBOR_REGISTRY=%s\n' 'harbor.flakybit.net' >> "$CI_ENV_FILE" +printf 'EXTERNAL_REGISTRY_NAMESPACE=%s\n' 'flakybitnet' >> "$CI_ENV_FILE" + +printf 'KANIKO_AUTH_FILE=%s\n' '/kaniko/.docker/config.json' >> "$CI_ENV_FILE" +printf 'AWS_CREDS_FILE=%s\n' '.ci/aws-ecr-creds' >> "$CI_ENV_FILE" + +cat "$CI_ENV_FILE" + +echo Done diff --git a/.woodpecker.yaml b/.woodpecker.yaml new file mode 100644 index 0000000..46a5aeb --- /dev/null +++ b/.woodpecker.yaml @@ -0,0 +1,78 @@ +# Environments +# RUN_PHASES=build-image|publish-quay|publish-ghcr|publish-ecr - execute workflow phases +# CI_MANUAL_TAG=0.0.1 - application release version, gets priority over CI_COMMIT_TAG + +variables: + - &debian_image 'public.ecr.aws/docker/library/debian:bookworm-slim' + - &kaniko_image "gcr.io/kaniko-project/executor:v1.23.2-debug" + - &skopeo_image "quay.io/containers/skopeo:v1.15.2" + - &awscli_image "public.ecr.aws/aws-cli/aws-cli:2.17.42" + +when: + - branch: main + event: + - manual + - branch: + exclude: main + event: + - manual + - tag + +steps: + # prepare + set-env: + image: *debian_image + commands: + - .ci/set-env.sh + + # image + image: + when: + evaluate: 'RUN_PHASES == "" || "build-image" in split(RUN_PHASES, ",")' + image: *kaniko_image + environment: + HARBOR_CREDS: + from_secret: fb_harbor_creds + commands: + - .ci/image.sh + + # publish external + publish-quay: + when: + evaluate: '(RUN_PHASES == "" || "publish-quay" in split(RUN_PHASES, ",")) && (CI_COMMIT_TAG != "" || CI_MANUAL_TAG != "")' + image: *skopeo_image + environment: + DEST_REGISTRY: quay.io + DEST_CREDS: + from_secret: fb_quay_creds + commands: + - .ci/publish-external.sh + publish-ghcr: + when: + evaluate: '(RUN_PHASES == "" || "publish-ghcr" in split(RUN_PHASES, ",")) && (CI_COMMIT_TAG != "" || CI_MANUAL_TAG != "")' + image: *skopeo_image + environment: + DEST_REGISTRY: ghcr.io + DEST_CREDS: + from_secret: fb_ghcr_creds + commands: + - .ci/publish-external.sh + login-ecr: + when: + evaluate: '(RUN_PHASES == "" || "publish-ecr" in split(RUN_PHASES, ",")) && (CI_COMMIT_TAG != "" || CI_MANUAL_TAG != "")' + image: *awscli_image + environment: + AWS_ACCESS_KEY_ID: + from_secret: fb_ecr_key_id + AWS_SECRET_ACCESS_KEY: + from_secret: fb_ecr_key + commands: + - .ci/login-ecr.sh + publish-ecr: + environment: + DEST_REGISTRY: public.ecr.aws + when: + evaluate: '(RUN_PHASES == "" || "publish-ecr" in split(RUN_PHASES, ",")) && (CI_COMMIT_TAG != "" || CI_MANUAL_TAG != "")' + image: *skopeo_image + commands: + - .ci/publish-external.sh