From d7f180cdbe84605b42abd982bc5293d7ce488b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rahu=CE=BB=20D=C3=A9?= Date: Fri, 15 Apr 2022 18:20:52 +0100 Subject: [PATCH] Bash -> Clojure: Take 2 (#1243) * Bash -> Clojure: Take 2 * Apply better naming * Temp disable circle branch filter * Pass platforms correctly to buildx * Rename platforms, better checks * Add circle and script guards for branch and PR * Fix guard --- .circleci/config.yml | 18 ++++--- .circleci/script/docker | 61 ----------------------- .circleci/script/docker.clj | 98 +++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 67 deletions(-) delete mode 100755 .circleci/script/docker create mode 100644 .circleci/script/docker.clj diff --git a/.circleci/config.yml b/.circleci/config.yml index 2c2c1bd5..ced804a9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,7 @@ commands: command: | docker run --privileged --rm tonistiigi/binfmt --install all docker buildx create --name ci-builder --use + jobs: jvm: docker: @@ -213,7 +214,6 @@ jobs: ./bb .circleci/script/publish_artifact.clj || true linux-aarch64: machine: - enabled: true image: ubuntu-2004:202101-01 resource_class: arm.large working_directory: ~/repo @@ -281,7 +281,6 @@ jobs: ./bb .circleci/script/publish_artifact.clj || true linux-aarch64-static: machine: - enabled: true image: ubuntu-2004:202101-01 resource_class: arm.large working_directory: ~/repo @@ -448,14 +447,22 @@ jobs: image: ubuntu-2004:202111-01 steps: - checkout + - run: + name: "Pull Submodules" + command: | + git submodule init + git submodule update - setup-docker-buildx - attach_workspace: at: /tmp + - run: + name: Build uberjar + command: script/uberjar - run: name: Build Docker image environment: - PLATFORM: linux/amd64,linux/arm64 - command: .circleci/script/docker + PLATFORMS: linux/amd64,linux/arm64 + command: java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj workflows: version: 2 @@ -478,8 +485,7 @@ workflows: - docker: filters: branches: - only: - - master + only: master requires: - linux - linux-static diff --git a/.circleci/script/docker b/.circleci/script/docker deleted file mode 100755 index f16447b6..00000000 --- a/.circleci/script/docker +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -set -eo pipefail - -image_name="babashka/babashka" -image_tag=$(cat resources/BABASHKA_VERSION) -platform=${PLATFORM:-"linux/amd64"} -latest_tag="latest" -label_args=("--label" "'org.opencontainers.image.description=Native, fast starting Clojure interpreter for scripting'" - "--label" "org.opencontainers.image.title=Babashka" - "--label" "org.opencontainers.image.created=$(date -Iseconds)" - "--label" "org.opencontainers.image.url=${CIRCLE_REPOSITORY_URL}" - "--label" "org.opencontainers.image.documentation=${CIRCLE_REPOSITORY_URL}" - "--label" "org.opencontainers.image.source=${CIRCLE_REPOSITORY_URL}" - "--label" "org.opencontainers.image.revision=${CIRCLE_SHA1}" - "--label" "org.opencontainers.image.ref.name=${CIRCLE_TAG}:${CIRCLE_BRANCH}" - "--label" "org.opencontainers.image.version=${image_tag}") - -if [[ $image_tag =~ SNAPSHOT$ ]]; then - echo "This is a snapshot version" - snapshot="true" -else - echo "This is a non-snapshot version" - snapshot="false" -fi - -if [ -z "$CIRCLE_PULL_REQUEST" ] && [ "$CIRCLE_BRANCH" = "master" ]; then - echo "Building & pushing $platform Docker image(s) $image_name:$image_tag" - echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USER" --password-stdin - IFS=',' read -r -a platforms <<< "$platform" - for p in "${platforms[@]}"; do - tarball_platform=${p//\//-} - if [[ $tarball_platform == "linux-arm64" ]]; then tarball_platform="linux-aarch64"; fi - mkdir -p $p - tar zxvf "/tmp/release/babashka-${image_tag}-${tarball_platform}.tar.gz" -C $p - # this overwrites, but this is to work around having built the uberjar/metabom multiple times - cp "/tmp/release/${tarball_platform}-metabom.jar" ./metabom.jar - done - docker buildx build -t "$image_name:$image_tag" --platform "$platform" "${label_args[@]}" --push -f Dockerfile.ci . - if [[ $snapshot == "false" ]]; then - echo "Building & pushing $platform Docker image(s) $image_name:$latest_tag" - docker buildx build -t "$image_name:$latest_tag" --platform "$platform" "${label_args[@]}" --push -f Dockerfile.ci . - fi - for p in "${platforms[@]}"; do - rm -rf $p - done - - # build alpine image for linux-amd64 only (no upstream arm64 support yet) - tar zxvf "/tmp/release/babashka-${image_tag}-linux-amd64-static.tar.gz" - echo "Building & pushing Docker image $image_name:$image_tag-alpine" - docker buildx build -t "$image_name:$image_tag-alpine" --platform=linux/amd64 "${label_args[@]}" --push -f Dockerfile.alpine . - - if [[ $snapshot == "false" ]]; then - echo "Building & pushing Docker image $image_name:alpine" - docker buildx build -t "$image_name:alpine" --platform=linux/amd64 "${label_args[@]}" --push -f Dockerfile.alpine . - fi -else - echo "Not publishing Docker image" -fi - -exit 0; diff --git a/.circleci/script/docker.clj b/.circleci/script/docker.clj new file mode 100644 index 00000000..a884c893 --- /dev/null +++ b/.circleci/script/docker.clj @@ -0,0 +1,98 @@ +(require '[clojure.string :as str] + '[babashka.process :as proc] + '[babashka.fs :as fs]) +(import '[java.time Instant]) + +(defn read-env + ([k] + (read-env k nil)) + ([k default] + (or (System/getenv k) + default))) + +(def image-name "babashka/babashka") + +(def image-tag (slurp "resources/BABASHKA_VERSION")) + +(def latest-tag "latest") + +(def platforms (read-env "PLATFORMS" "linux/amd64")) + +(def circle-repository-url (read-env "CIRCLE_REPOSITORY_URL")) + +(def label-args + ["--label" "'org.opencontainers.image.description=Native, fast starting Clojure interpreter for scripting'" + "--label" "org.opencontainers.image.title=Babashka" + "--label" (str "org.opencontainers.image.created=" (Instant/now)) + "--label" (str "org.opencontainers.image.url=" circle-repository-url) + "--label" (str "org.opencontainers.image.documentation=" circle-repository-url) + "--label" (str "org.opencontainers.image.source=" circle-repository-url) + "--label" (str "org.opencontainers.image.revision=" (read-env "CIRCLE_SHA1")) + "--label" + (format "org.opencontainers.image.ref.name=%s:%s" + (read-env "CIRCLE_TAG") + (read-env "CIRCLE_BRANCH")) + "--label" (str "org.opencontainers.image.version=" image-tag)]) + +(def snapshot? (str/includes? image-tag "SNAPSHOT")) + +(defn exec + [cmd] + (-> cmd + (proc/process {:out :inherit :err :inherit}) + (proc/check))) + +(defn docker-login + [username password] + (exec ["docker" "login" "-u" username "-p" password])) + +(defn build-push + [image-tag platform docker-file] + (println (format "Building and pushing %s Docker image(s) %s:%s" + platform + image-name + image-tag)) + (let [base-cmd ["docker" "buildx" "build" + "-t" (str image-name ":" image-tag) + "--platform" platform + "--push" + "-f" docker-file]] + (exec (concat base-cmd label-args ["."])))) + +(defn build-push-images + [] + (doseq [platform (str/split platforms #",")] + (let [tarball-platform (str/replace platform #"\/" "-") + tarball-platform (if (= "linux-arm64" tarball-platform) + "linux-aarch64" + tarball-platform) + tarball-path (format "/tmp/release/babashka-%s-%s.tar.gz" + image-tag + tarball-platform)] + (fs/create-dirs platform) + (exec ["tar" "zxvf" tarball-path "-C" platform]) + ; this overwrites, but this is to work around having built the uberjar/metabom multiple times + (fs/copy (format "/tmp/release/%s-metabom.jar" tarball-platform) "metabom.jar" {:replace-existing true}))) + (build-push image-tag platforms "Dockerfile.ci") + (when-not snapshot? + (build-push latest-tag platforms "Dockerfile.ci"))) + +(defn build-push-alpine-images + "Build alpine image for linux-amd64 only (no upstream arm64 support yet)" + [] + (exec ["tar" "zxvf" (str "/tmp/release/babashka-" image-tag "-linux-amd64-static.tar.gz")]) + (build-push (str image-tag "-alpine") "linux/amd64" "Dockerfile.alpine") + (when-not snapshot? + (build-push "alpine" "linux/amd64" "Dockerfile.alpine"))) + +(when (= *file* (System/getProperty "babashka.file")) + (if (and (nil? (read-env "CIRCLE_PULL_REQUEST")) + (= "master" (read-env "CIRCLE_BRANCH"))) + (do + (if snapshot? + (println "This is a snapshot version") + (println "This is a non-snapshot version")) + (docker-login (read-env "DOCKERHUB_USER") (read-env "DOCKERHUB_PASS")) + (build-push-images) + (build-push-alpine-images)) + (println "Not publishing docker image(s).")))