diff --git a/.circleci/config.yml b/.circleci/config.yml index 2c2c1bd5..3f75c431 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 + 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..975c5277 --- /dev/null +++ b/.circleci/script/docker.clj @@ -0,0 +1,94 @@ +(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))