From 8412f44da3895b47bdd0bda79bad9b16710a092f Mon Sep 17 00:00:00 2001 From: Cam Saul <1455846+camsaul@users.noreply.github.com> Date: Thu, 8 Oct 2020 13:55:33 -0700 Subject: [PATCH] Revert merge release script [ci skip] (#13416) --- release/README.md | 16 -- release/deps.edn | 11 -- release/release-template.md | 30 --- release/release.clj | 48 ----- release/release/build.clj | 48 ----- release/release/check_prereqs.clj | 83 -------- release/release/common.clj | 275 -------------------------- release/release/common/github.clj | 47 ----- release/release/draft_release.clj | 49 ----- release/release/publish.clj | 185 ----------------- release/release/set_build_options.clj | 30 --- release/release/validate.clj | 7 - 12 files changed, 829 deletions(-) delete mode 100644 release/README.md delete mode 100644 release/deps.edn delete mode 100644 release/release-template.md delete mode 100644 release/release.clj delete mode 100644 release/release/build.clj delete mode 100644 release/release/check_prereqs.clj delete mode 100644 release/release/common.clj delete mode 100644 release/release/common/github.clj delete mode 100644 release/release/draft_release.clj delete mode 100644 release/release/publish.clj delete mode 100644 release/release/set_build_options.clj delete mode 100644 release/release/validate.clj diff --git a/release/README.md b/release/README.md deleted file mode 100644 index 4f9a1be9c72e7..0000000000000 --- a/release/README.md +++ /dev/null @@ -1,16 +0,0 @@ -## Metabase Release Script 3.0 - -#### Prereqs - -1. Install Clojure CLI -- see [https://clojure.org/guides/getting_started]. Don't use `apt install clojure` as this - installs a version that doesn't understand `deps.edn`. - -1. Script will interactively prompt for other prereqs and env vars - -#### Running - -```bash -# Run from the same directory as this README file -cd /path/to/metabase/release -clojure -m release -``` diff --git a/release/deps.edn b/release/deps.edn deleted file mode 100644 index 647057439ece9..0000000000000 --- a/release/deps.edn +++ /dev/null @@ -1,11 +0,0 @@ -{:paths ["./"] - - :deps - {cheshire {:mvn/version "5.8.1"} - clj-http {:mvn/version "3.9.1"} - commons-io/commons-io {:mvn/version "2.6"} - colorize {:mvn/version "0.1.1"} - environ {:mvn/version "1.1.0"} - hiccup {:mvn/version "1.0.5"} - org.flatland/ordered {:mvn/version "1.5.7"} - stencil {:mvn/version "0.5.0"}}} diff --git a/release/release-template.md b/release/release-template.md deleted file mode 100644 index 69c08f4c7f4d6..0000000000000 --- a/release/release-template.md +++ /dev/null @@ -1,30 +0,0 @@ -# NOTE: clean up 'Enhancements' and 'Bug fixes' sections and remove this line before publishing! - -**Enhancements** - -{{#enhancements}} -* {{title}} (#{{number}}) -{{/enhancements}} - -**Bug fixes** - -{{#bug-fixes}} -* {{title}} (#{{number}}) -{{/bug-fixes}} - -**Upgrading** - -You can download a .jar of the release, or get the latest on Docker. Make sure to back up your Metabase -database before you upgrade! Need help? Check out our -[upgrading instructions](https://metabase.com/docs/latest/operations-guide/upgrading-metabase.html). - -Docker image: `{{docker-tag}}` -Download the JAR here: {{download-url}} - -**Notes** - -SHA-256 checksum for the {{version}} JAR: - -``` -{{checksum}} -``` diff --git a/release/release.clj b/release/release.clj deleted file mode 100644 index a4cca05a9227c..0000000000000 --- a/release/release.clj +++ /dev/null @@ -1,48 +0,0 @@ -(ns release - (:require [colorize.core :as colorize] - [flatland.ordered.map :as ordered-map] - [release - [build :as build] - [check-prereqs :as check-prereqs] - [common :as c] - [draft-release :as draft-release] - [publish :as publish] - [set-build-options :as set-build-options] - [validate :as validate]])) - -(set! *warn-on-reflection* true) - -(def ^:private steps* - (ordered-map/ordered-map - :check-prereqs check-prereqs/check-prereqs - :set-options set-build-options/prompt-and-set-build-options! - :build build/build! - :draft-release draft-release/create-draft-release! - :publish publish/publish! - :validate validate/validate-release - ;; TODO -- we should loop in the Mac App build code here as well - )) - -(defn- do-step! [step-name] - (let [thunk (or (get steps* (keyword step-name)) - (throw (ex-info (format "Invalid step name: %s" step-name) - {:found (set (keys steps*))})))] - (println (colorize/magenta (format "Running step %s..." step-name))) - (thunk))) - -(defn- do-steps! - [steps] - (c/announce "Running steps: %s" steps) - (doseq [step-name steps] - (do-step! step-name)) - (c/announce "Success.")) - -(defn -main [& steps] - (let [steps (or (seq steps) - (keys steps*))] - (try - (do-steps! steps) - (catch Throwable e - (println (colorize/red (pr-str e))) - (System/exit -1))) - (System/exit 0))) diff --git a/release/release/build.clj b/release/release/build.clj deleted file mode 100644 index c55a79e97ad3f..0000000000000 --- a/release/release/build.clj +++ /dev/null @@ -1,48 +0,0 @@ -(ns release.build - (:require [clojure.string :as str] - [environ.core :as env] - [release.common :as c])) - -(def ^:private bin-version-file - (str c/root-directory "/bin/version")) - -(defn- update-version-info! [] - (c/step (format "Update %s if needed" (c/assert-file-exists bin-version-file)) - (c/step "Update version in bin/version" - (let [lines (str/split-lines (slurp bin-version-file)) - updated-lines (for [line lines] - (if (re-matches #".*VERSION=.*" line) - (format "VERSION='v%s'" (c/version)) - line))] - (if (= lines updated-lines) - (c/announce "Correct version is already set.") - (do - (c/announce "Version set to 'v%s'" (c/version)) - (spit bin-version-file (str/join (interleave updated-lines (repeat "\n")))) - (c/sh "chmod" "+x" bin-version-file) - (c/step "Commit updated bin/version" - (c/sh "git" "add" bin-version-file) - (c/sh "git" "commit" "-m" (str \v (c/version)) bin-version-file)))))))) - -(defn- build-uberjar! [] - (c/step "Run bin/build to build uberjar" - (c/delete-file! (str c/root-directory "/target")) - (c/sh {:dir c/root-directory} "bin/build") - (c/step "Verify uberjar exists" - (c/assert-file-exists c/uberjar-path)))) - -(defn- build-docker-image! [] - (c/step "Build Docker image" - (c/copy-file! (c/assert-file-exists c/uberjar-path) (str c/root-directory "/bin/docker/metabase.jar")) - (c/sh "docker" "build" "-t" (c/docker-tag) (str c/root-directory "/bin/docker")))) - -(defn build! [] - (c/step "Build release" - (c/slack-notify "%s started preparing %s `v%s` from branch `%s`..." - (env/env :user) - (str/upper-case (name (c/edition))) - (c/version) - (c/branch)) - (update-version-info!) - (build-uberjar!) - (build-docker-image!))) diff --git a/release/release/check_prereqs.clj b/release/release/check_prereqs.clj deleted file mode 100644 index d3b9e746df7a0..0000000000000 --- a/release/release/check_prereqs.clj +++ /dev/null @@ -1,83 +0,0 @@ -(ns release.check-prereqs - (:require [clojure.string :as str] - [environ.core :as env] - [release.common :as c])) - -(def ^:private required-commands - ["yarn" "aws" "docker" "java"]) - -(defn- check-for-required-commands [] - (c/step "Verify required external commands are available" - (doseq [cmd required-commands] - (c/step (format "Verify command %s is available" (pr-str cmd))) - (loop [] - (let [result (try - (c/sh "which" cmd) - (catch Throwable _ - :fail))] - (when (= result :fail) - (printf "The %s command is not available locally. Please install it and press any key to continue, or Ctrl-C to quit." - (pr-str cmd)) - (flush) - (read-line) - (recur))))) - (c/announce "All required external commands are available."))) - -(def ^:private required-env-vars - (filter - some? - [:github-token - :dockerhub-username - :dockerhub-password - :aws-default-profile - ;; Slack Webhook URL is required unless you set `NO_SLACK` - (when-not (env/env :no-slack) :slack-webhook-url)])) - -(defn- check-for-required-env-vars [] - (c/step "Verify required env vars are set" - (doseq [env-var required-env-vars - :let [actual-env-var (str/upper-case (str/replace (name env-var) #"-" "_"))]] - (c/step (format "Verify env var %s is set" actual-env-var) - (if (get env/env env-var) - (c/announce "Found %s" actual-env-var) - (c/step "Prompt for value" - (c/announce "%s is not set." actual-env-var) - (let [val (c/read-line-with-prompt "Please enter a value to use, or press Ctrl-C to quit:")] - (alter-var-root #'env/env assoc env-var val)))))))) - -(defn- check-docker-is-running [] - (c/step "Verify Docker is running" - (loop [] - (let [result (try - (c/sh {:quiet? true} "docker" "ps") - (c/announce "Docker is running.") - (catch Throwable _ - :fail))] - (when (= result :fail) - (printf "Docker is not running. Please make sure it is running and press any key to continue or Ctrl-C to quit.") - (flush) - (read-line) - (recur)))))) - -(defn- java-version - "Get `major.minor` version of the `java` command, e.g. `14.0` or `1.8` (Java 8)." - [] - (when-let [[_ version] (re-find #"version \"(\d+\.\d+)\..*\"" (first (c/sh "java" "-version")))] - (Double/parseDouble version))) - -(defn- check-java-8 [] - (c/step "Verify Java version is Java 8" - (let [version (or (java-version) - (throw (Exception. "Unable to determine Java major version.")))] - ;; TODO -- is it possible to invoke `jabba` or some other command programmatically, or prompt for a different - ;; `JAVA_HOME`/`PATH` to use? - (when-not (#{1.8 8} version) - (throw (Exception. "The Metabase build script currently requires Java 8 to run. Please change your Java version and try again."))) - (c/announce "Java version is Java 8.")))) - -(defn check-prereqs [] - (c/step "Check prereqs" - (check-for-required-commands) - (check-for-required-env-vars) - (check-docker-is-running) - (check-java-8))) diff --git a/release/release/common.clj b/release/release/common.clj deleted file mode 100644 index d455b1e2cb021..0000000000000 --- a/release/release/common.clj +++ /dev/null @@ -1,275 +0,0 @@ -(ns release.common - (:require [cheshire.core :as json] - [clj-http.client :as http] - [clojure.string :as str] - [colorize.core :as colorize] - [environ.core :as env]) - (:import [java.io BufferedReader File InputStreamReader] - org.apache.commons.io.FileUtils)) - -(assert (str/ends-with? (env/env :user-dir) "/release") - "Please run release.clj from the `release` directory e.g. `cd release; clojure -m release`") - -(defn env-or-throw - "Fetch an env var value or throw an Exception if it is unset." - [k] - (or (get env/env k) - (throw (Exception. (format "%s is unset. Please set it and try again." (str/upper-case (str/replace (name k) #"-" "_"))))))) - -(def ^String root-directory - "e.g. /Users/cam/metabase" - (.getParent (File. (env/env :user-dir)))) - -(def ^String uberjar-path - (str root-directory "/target/uberjar/metabase.jar")) - -(defonce ^:private build-options - (atom nil)) - -(defn version - "Version tag we are currently building, e.g. `0.36.0`" - [] - (or (:version @build-options) - (throw (Exception. "Version is not set. Run :set-build-options to set it.")))) - -(defn set-version! [new-version] - ;; strip off initial `v` if present - (swap! build-options assoc :version (str/replace new-version #"^v" ""))) - -(defn branch - "Branch we are building from, e.g. `release-0.36.x`" - [] - (or (:branch @build-options) - (throw (Exception. "Branch is not set. Run :set-build-options to set it.")))) - -(defn set-branch! [new-branch] - (swap! build-options assoc :branch new-branch)) - -(defn edition - "Either `:ce` (Community Edition) or `:ee` (Enterprise Edition)." - [] - (or (:edition @build-options) - (Exception. "Edition is not set. Run :set-build-options to set it."))) - -(defn set-edition! [new-edition] - (assert (#{:ce :ee} new-edition)) - (swap! build-options assoc :edition new-edition)) - -(defn pre-release-version? - "Whether this version should be considered a prerelease. True if the version doesn't follow the usual - `major.minor.patch[.build]` format." - [] - (not (re-matches #"^\d+\.\d+\.\d+(?:\.\d+)?$" (version)))) - -(defn docker-repo [] - (case (edition) - :ce "metabase/metabase" - :ee "metabase/metabase-enterprise")) - -(defn downloads-url [] - (case (edition) - :ce "downloads.metabase.com" - :ee "downloads.metabase.com/enterprise")) - -(defn artifact-download-url - "Public-facing URL where you can download the artifact after it has been uploaded." - [filename] - (format "https://%s/v%s/%s" (downloads-url) (version) filename)) - -(defn s3-artifact-url [filename] - (format "s3://%s/v%s/%s" (downloads-url) (version) filename)) - -(defn website-repo [] - (case (edition) - :ce "metabase/metabase.github.io" - nil)) - -(defn heroku-buildpack-repo [] - (case (edition) - :ce "metabase/metabase-buildpack" - nil)) - -(defn version-info-url [] - (case (edition) - :ce "static.metabase.com/version-info.json" - nil)) - -(defn metabase-repo [] - (case (edition) - :ce "metabase/metabase" - :ee "metabase/metabase-enterprise")) - -(defn docker-tag [] - (format "%s:v%s" (docker-repo) (version))) - -;;; ---------------------------------------------------- Util Fns ---------------------------------------------------- - -(def ^:dynamic *steps* []) - -(def ^:private step-indent (str/join (repeat 2 \space))) - -(defn- steps-indent [] - (str/join (repeat (count *steps*) step-indent))) - -(defn safe-println [& args] - (locking println - (print (steps-indent)) - (apply println args))) - -(defn announce - "Like `println` + `format`, but outputs text in green. Use this for printing messages such as when starting build - steps." - ([s] - (safe-println (colorize/magenta s))) - - ([format-string & args] - (announce (apply format (str format-string) args)))) - -(defn do-step [step thunk] - (safe-println (colorize/green (str step))) - (binding [*steps* (conj *steps* step)] - (try - (thunk) - (catch Throwable e - (throw (ex-info (str step) {} e)))))) - -(defmacro step {:style/indent 1} [step & body] - `(do-step ~step (fn [] ~@body))) - -(defn exists? [^String filename] - (when filename - (.exists (File. filename)))) - -(defn assert-file-exists - "If file with `filename` exists, return `filename` as is; otherwise, throw Exception." - ^String [filename & [message]] - (when-not (exists? filename) - (throw (ex-info (format "File %s does not exist. %s" (pr-str filename) (or message "")) {:filename filename}))) - (str filename)) - -(defn create-directory-unless-exists! [^String dir] - (when-not (exists? dir) - (step (format "Creating directory %s..." dir) - (.mkdirs (File. dir)))) - dir) - -(defn delete-file! - "Delete a file or directory if it exists." - ([^String filename] - (step (format "Deleting %s..." filename) - (if (exists? filename) - (let [file (File. filename)] - (if (.isDirectory file) - (FileUtils/deleteDirectory file) - (.delete file)) - (safe-println (format "Deleted %s." filename))) - (safe-println (format "Don't need to delete %s, file does not exist." filename))) - (assert (not (exists? filename))))) - - ([file & more] - (dorun (map delete-file! (cons file more))))) - -(declare sh) - -(defn copy-file! [^String source ^String dest] - (let [source-file (File. (assert-file-exists source)) - dest-file (File. dest)] - ;; Use native `cp` rather than FileUtils or the like because codesigning is broken when you use those because they - ;; don't preserve symlinks or something like that. - (if (.isDirectory source-file) - (step (format "Copying directory %s -> %s" source dest) - (sh "cp" "-R" source dest)) - (step (format "Copying file %s -> %s" source dest) - (sh "cp" source dest)))) - (assert-file-exists dest)) - -(defn- read-lines [^java.io.BufferedReader reader {:keys [quiet? err?]}] - (loop [lines []] - (if-let [line (.readLine reader)] - (do - (when-not quiet? - (safe-println (if err? (colorize/red line) line))) - (recur (conj lines line))) - lines))) - -(defn- deref-with-timeout [dereffable timeout-ms] - (let [result (deref dereffable timeout-ms ::timed-out)] - (when (= result ::timed-out) - (throw (ex-info (format "Timed out after %d ms." timeout-ms) {}))) - result)) - -(def ^:private command-timeout-ms (* 15 60 1000)) ; 15 minutes - -(defn sh* - "Run a shell command. Like `clojure.java.shell/sh`, but prints output to stdout/stderr and returns results as a vector - of lines." - {:arglists '([cmd & args] [{:keys [dir quiet?]} cmd & args])} - [& args] - (step (colorize/blue (str "$ " (str/join " " (map (comp pr-str str) (if (map? (first args)) - (rest args) - args))))) - (let [[opts & args] (if (map? (first args)) - args - (cons nil args)) - {:keys [dir]} opts - cmd-array (into-array (map str args)) - proc (.exec (Runtime/getRuntime) ^"[Ljava.lang.String;" cmd-array nil ^File (when dir (File. ^String dir)))] - (with-open [out-reader (BufferedReader. (InputStreamReader. (.getInputStream proc))) - err-reader (BufferedReader. (InputStreamReader. (.getErrorStream proc)))] - (let [exit-code (future (.waitFor proc)) - out (future (read-lines out-reader opts)) - err (future (read-lines err-reader (assoc opts :err? true)))] - {:exit (deref-with-timeout exit-code command-timeout-ms) - :out (deref-with-timeout out command-timeout-ms) - :err (deref-with-timeout err command-timeout-ms)}))))) - -(defn sh - "Run a shell command, returning its output if it returns zero or throwning an Exception if it returns non-zero." - {:arglists '([cmd & args] [{:keys [dir quiet?]} cmd & args])} - [& args] - (let [{:keys [exit out err], :as response} (apply sh* args)] - (if (zero? exit) - (concat out err) - (throw (ex-info (str/join "\n" (concat out err)) response))))) - -(defn read-line-with-prompt - "Prompt for and read a value from stdin. Accepts two options: `:default`, which is the default value to use if the - user does not enter something else; and `:validator`, a one-arg function that should return an error message if the - value is invalid, or `nil` if it is valid." - [prompt & {:keys [default validator]}] - (loop [] - (print (str prompt " ")) - (when default - (printf "(default %s) " (pr-str default))) - (flush) - (let [line (or (not-empty (str/trim (read-line))) - default)] - (newline) - (flush) - (cond - (empty? line) - (recur) - - validator - (let [error (validator line)] - (if error - (do - (println error) - (recur)) - line)) - - :else - line)))) - -(defn slack-notify - "Posts a message to the Slack a channel using `SLACK_WEBHOOK_URL`. If `NO_SLACK` is set, this is a no-op." - ([format-string & args] - (slack-notify (apply format format-string args))) - - ([msg] - (when-not (env/env :no-slack) - (let [slack-webhook-url (env-or-throw :slack-webhook-url) - body (json/generate-string {:text (str msg)})] - (http/post slack-webhook-url {:headers {"Content-Type" "application/json"} - :body body}) - :ok)))) diff --git a/release/release/common/github.clj b/release/release/common/github.clj deleted file mode 100644 index 6bb3d8347f14f..0000000000000 --- a/release/release/common/github.clj +++ /dev/null @@ -1,47 +0,0 @@ -(ns release.common.github - (:require [cheshire.core :as json] - [clj-http.client :as http] - [clojure.string :as str] - [release.common :as c])) - -(defn github-api-base [] - (str "https://api.github.com/repos/" (c/metabase-repo))) - -(defn github-api-request-headers [] - {"Content-Type" "application/json" - "Authorization" (format "token %s" (c/env-or-throw :github-token))}) - -(defn milestones - "Fetch open GitHub milestones for the current repo." - [] - (-> (http/get (str (github-api-base) "/milestones") {:headers (github-api-request-headers)}) - :body - (json/parse-string true))) - -(defn matching-milestone - "Return the GitHub milestone matching the version we're releasing, if any." - [] - (some - (fn [{:keys [title], :as milestone}] - (when (str/starts-with? (c/version) title) - milestone)) - (milestones))) - -(defn milestone-issues - "Fetch the issues in the GitHub `milestone` corresponding to this release." - [] - (when-let [{milestone-number :number} (matching-milestone)] - (-> (http/get (format "%s/issues?milestone=%d&state=closed" (github-api-base) milestone-number) - {:headers (github-api-request-headers)}) - :body - (json/parse-string true)))) - -(defn issue-type - "Whether this issue is a `:bug` (if it has a `Type:Bug` tag) or `:enhancement` (if it does not)." - [{:keys [labels]}] - (if (some - (fn [{label-name :name}] - (= label-name "Type:Bug")) - labels) - :bug - :enhancement)) diff --git a/release/release/draft_release.clj b/release/release/draft_release.clj deleted file mode 100644 index 144f2fede1af9..0000000000000 --- a/release/release/draft_release.clj +++ /dev/null @@ -1,49 +0,0 @@ -(ns release.draft-release - (:require [cheshire.core :as json] - [clj-http.client :as http] - [clojure.core.cache :as cache] - [clojure.java.io :as io] - [release.common :as c] - [release.common.github :as github] - [stencil loader - [core :as stencil]]) - (:import org.apache.commons.codec.digest.DigestUtils)) - -;; Disable caching of our template files for easier REPL debugging, we're only rendering them once anyways -(stencil.loader/set-cache (cache/ttl-cache-factory {} :ttl 0)) - -(defn- sha-256-sum [filename] - (with-open [is (io/input-stream (c/assert-file-exists filename))] - (DigestUtils/sha256Hex is))) - -(defn- generate-draft-changelog [] - (c/step "Generate draft changelog" - (let [pre-release? (c/pre-release-version?) - {bugs :bug, enhancements :enhancement} (group-by github/issue-type (github/milestone-issues))] - (stencil/render-file (c/assert-file-exists "release-template.md") - {:enhancements enhancements - :bug-fixes bugs - :docker-tag (c/docker-tag) - :download-url (c/artifact-download-url "metabase.jar") - :version (c/version) - :checksum (sha-256-sum c/uberjar-path)})))) - - - -(defn- upload-draft-changelog! [changelog] - (c/step "Upload draft changelog (create draft release)" - (let [body (json/generate-string {:tag_name (format "v%s" (c/version)) - :target_commitish (c/branch) - :name (format "Metabase v%s" (c/version)) - :draft true - :prerelease (c/pre-release-version?) - :body changelog})] - (http/post (str (github/github-api-base) "/releases") - {:headers (github/github-api-request-headers) - :body body})))) - -(defn create-draft-release! [] - (c/step "Create draft release" - (let [changelog (generate-draft-changelog)] - (upload-draft-changelog! changelog) - (c/announce "GitHub draft release for %s created." (c/version))))) diff --git a/release/release/publish.clj b/release/release/publish.clj deleted file mode 100644 index 22adda7e5299e..0000000000000 --- a/release/release/publish.clj +++ /dev/null @@ -1,185 +0,0 @@ -(ns release.publish - (:require [cheshire.core :as json] - [clj-http.client :as http] - [release.common :as c] - [release.common.github :as github])) - -(def ^:private version-info-url - "static.metabase.com/version-info.json") - -(def ^:private tmp-version-info-filename - "/tmp/version-info.json") - -(defn- current-version-info - "Fetch the current version of `version-info.json`." - [] - (-> (http/get (str "http://" version-info-url)) - :body - (json/parse-string true))) - -(defn- patch-version? - "Is `version` a patch release? True for versions that end in things like `.1` (non-zero patch number)" - [version] - (if-let [[_ patch] (re-matches #"^\d+\.\d+\.(\d+).*$" version)] - (not (zero? (Integer/parseUnsignedInt patch))) - false)) - -(defn- info-for-new-version - "The info map for the version we're currently releasing to add to `version-info.json`." - [] - {:version (str "v" (c/version)) - :released (str (java.time.LocalDate/now)) - :patch (patch-version? (c/version)) - ;; TODO -- these need to be curated a bit before publishing... - :highlights (mapv :title (github/milestone-issues))}) - -(defn- generate-version-info! [] - (c/step "Generate version info file" - (cond - (c/pre-release-version?) - (c/announce "Pre-release version -- not generating version info file") - - (= (c/edition) :ee) - (c/announce "EE build -- not generating version info file") - - :else - (c/step (format "Generate %s" tmp-version-info-filename) - (c/delete-file! tmp-version-info-filename) - (let [{:keys [latest], :as info} (current-version-info)] - (spit tmp-version-info-filename (-> info - ;; move the current `:latest` to the beginning of `:older` - (update :older (fn [older] - (cons latest older))) - (assoc :latest (info-for-new-version)) - json/generate-string))))))) - -(defn- s3-copy! [source dest] - (c/step (format "[S3] Copy %s -> %s" source dest) - (c/sh "aws" "s3" "cp" source dest))) - -(defn- upload-artifacts! [] - (c/step "Upload artifacts" - (c/step "Upload uberjar" - (s3-copy! (c/assert-file-exists c/uberjar-path) (c/s3-artifact-url "metabase.jar"))) - (c/step "Upload version info" - (cond - (c/pre-release-version?) - (c/announce "Pre-release version -- not uploading version info file") - - (= (c/edition) :ee) - (c/announce "EE build -- not uploading version info file") - - :else - (do - (s3-copy! (format "s3://%s" version-info-url) (format "s3://%s.previous" version-info-url)) - (s3-copy! (c/assert-file-exists tmp-version-info-filename) (format "s3://%s" version-info-url))))))) - -(defn- push-docker-image! [] - (c/step "Push Docker image" - (c/sh "docker" "push" (c/docker-tag)) - (when (and (= (c/edition) :ee) - (not (c/pre-release-version?))) - (let [latest-tag "metabase/metabase-enterprise:latest"] - (c/step (format "Pushing tag %s" latest-tag) - (c/sh "docker" "tag" (c/docker-tag) latest-tag) - (c/sh "docker" "push" latest-tag )))))) - -;; TODO -- we should merge the EB build logic into this script, it's still an ancient bash script -(defn- publish-elastic-beanstalk-artifacts! [] - (c/step "Create and publish Elastic Beanstalk artifacts" - (c/sh {:dir c/root-directory} "./bin/aws-eb-docker/release-eb-version.sh" (str "v" (c/version))))) - -;; TODO -- I think most of this should be done as part of `build` -- everything besides publishing -(defn- push-heroku-buildpack! [] - (c/step "Update Metabase Heroku buildpack" - (cond - (c/pre-release-version?) - (c/announce "Pre-release version -- not updating Heroku buildpack ") - - (= (c/edition) :ee) - (c/announce "EE build -- not updating Herkou buildpack") - - :else - (let [heroku-repo "metabase/metabase-buildpack" - dir "/tmp/metabase-heroku-buildpack"] - (c/step "Clone Herkou Buildpack repo" - (c/delete-file! dir) - (c/sh "git" "clone" (format "git@github.com:%s.git" heroku-repo) dir)) - (let [version-file (c/assert-file-exists (str dir "/bin/version"))] - (c/step (format "Update %s" (pr-str version-file)) - (spit version-file (str (c/version) "\n")) - (c/sh {:dir dir} "git" "commit" "-m" (format "v%s" (c/version))))) - (c/step "Delete old tags" - (try - (c/sh {:dir dir} "git" "push" "--delete" "origin" (c/version)) - (catch Throwable _ - (c/announce "Nothing to delete.")))) - (c/step "Push updated tag" - (c/sh {:dir dir} "git" "tag" (c/version)) - (c/sh {:dir dir} "git" "push") - (c/sh {:dir dir} "git" "push" "--tags" "origin" "master")))))) - -;; TODO -- is it ok that this happens here, or should it happen *before* the draft release? -(defn- push-tags! [] - (c/step "Push updated tags to GitHub" - (c/step "Delete old tags" - (try - (c/sh "git" "push" "--delete" "origin" (str "v" (c/version))) - (catch Throwable _ - (c/announce "Nothing to delete.")))) - (c/step "Push updated tag" - (c/sh "git" "tag" "-a" (str "v" (c/version)) "-m" (str "v" (c/version))) - (c/sh "git" "push" "--follow-tags" "-u" "origin" (c/branch))) - (c/announce "Tags updated."))) - -;; TODO -- consider whether this should go in its own namespace -(defn- publish-docs! [] - (c/step "Update Metabase docs" - (cond - (c/pre-release-version?) - (c/announce "Pre-release version -- not updating Metabase docs") - - (= (c/edition) :ee) - (c/announce "EE build -- not updating Metabase docs") - - :else - (do - ;; TODO - ;; - ;; if [ "${METABASE_WEBSITE_REPO-}" ]; then - ;; pull-repo "$METABASE_WEBSITE_REPO" "$METABASE_WEBSITE_BRANCH" - ;; fi - ;; - ;; pushd "$METABASE_WEBSITE_DIR" - ;; - ;; yarn install - ;; - ;; ./script/docs "v$VERSION" $* - ;; - ;; git add . - ;; git commit -m "v$VERSION" || true - ;; - ;; echo "delete old tags" - ;; git push --delete origin "v$VERSION" || true - ;; git tag --delete "v$VERSION" || true - - ;; echo "tag it" - ;; git tag -a "v$VERSION" -m "v$VERSION" - ;; git push --follow-tags -u origin "$METABASE_WEBSITE_BRANCH" - ;; - ;; popd - ;; - ;; echo "Updating website to latest release" - ;; release-docs --latest - )))) - -(defn publish! [] - (c/step "Publish release" - (generate-version-info!) - (upload-artifacts!) - (push-docker-image!) - (publish-elastic-beanstalk-artifacts!) - (push-heroku-buildpack!) - (push-tags!) - (publish-docs!) - (c/announce "Release published successfully."))) diff --git a/release/release/set_build_options.clj b/release/release/set_build_options.clj deleted file mode 100644 index 8f8e888220d26..0000000000000 --- a/release/release/set_build_options.clj +++ /dev/null @@ -1,30 +0,0 @@ -(ns release.set-build-options - (:require [clojure.string :as str] - [release.common :as c])) - -(defn prompt-and-set-build-options! [] - (let [[current-branch] (c/step "Determine current branch" - (c/sh "git" "symbolic-ref" "--short" "HEAD"))] - (loop [] - (let [version (c/read-line-with-prompt "What version are we building (e.g. 0.36.0)?") - branch (c/read-line-with-prompt "What branch are we building from?" :default current-branch) - edition (c/read-line-with-prompt "Is this a [C]ommunity Edition release or an [E]nterprise Edition release? (type C or E)" - :validator (fn [line] - (when-not (#{"c" "e"} (str/lower-case line)) - "Please enter 'C' or 'E'"))) - edition (case (str/lower-case edition) - "c" :ce - "e" :ee) - y-or-n (c/read-line-with-prompt (format "Building %s version %s from branch %s. Is this correct? [y/n]" - (pr-str edition) (pr-str version) (pr-str branch)) - :validator (fn [line] - (when-not (#{"y" "n"} (str/lower-case line)) - "Please type 'y' or 'n'")))] - (if (= y-or-n "n") - (do - (println "Please enter new build options, or press Ctrl-C to quit.") - (recur)) - (do - (c/set-version! version) - (c/set-branch! branch) - (c/set-edition! edition))))))) diff --git a/release/release/validate.clj b/release/release/validate.clj deleted file mode 100644 index b8a329613e6ea..0000000000000 --- a/release/release/validate.clj +++ /dev/null @@ -1,7 +0,0 @@ -(ns release.validate) - -(defn validate-release [] - ;; notify "Prepared v$VERSION ($METABASE_REPO) release! Validating..." - ;; PREPARE=1 validate - ;; notify "Validation complete. Don't forget to publish the release!" - )