diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f75c431..2c2c1bd5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,6 @@ commands: command: | docker run --privileged --rm tonistiigi/binfmt --install all docker buildx create --name ci-builder --use - jobs: jvm: docker: @@ -214,6 +213,7 @@ 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,6 +281,7 @@ 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 @@ -447,22 +448,14 @@ 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: java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj + command: .circleci/script/docker workflows: version: 2 @@ -485,7 +478,8 @@ workflows: - docker: filters: branches: - only: master + only: + - master requires: - linux - linux-static diff --git a/.circleci/script/docker b/.circleci/script/docker new file mode 100755 index 00000000..f16447b6 --- /dev/null +++ b/.circleci/script/docker @@ -0,0 +1,61 @@ +#!/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 deleted file mode 100644 index 975c5277..00000000 --- a/.circleci/script/docker.clj +++ /dev/null @@ -1,94 +0,0 @@ -(require '[clojure.string :as s] - '[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 "PLATFORM" "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 (= "SNAPSHOT" image-tag)) - -(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 (s/split platforms #",")] - (let [tarball-platform (s/replace platform #"\/" "-") - tarball-platform (if (= "linux-arm64") - "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 platform "Dockerfile.ci") - (when-not snapshot - (build-push latest-tag platform "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 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))