通常,我的所有服务器端应用程序都有一个 URL GET 路由,它返回当前的 git 哈希,作为检查给定实例上运行的代码的确切版本的简单方法。在解释型语言(例如 Python、Node.js)中,这很容易,您只需检查在子进程中运行 shell 命令的输出。但是我通过使用lein uberjar
.
所以我可以clojure.java.shell
像这样以编程方式获取当前的 git sha:
(defn get-git-sha
[_req]
(trim ((sh "/bin/sh" "-c" "git rev-parse HEAD") :out)))
(defroutes server-routes
(GET "/revision" [] get-git-sha))
(defn serve-http
[port]
(http-server/run-server server-routes {:port port}))
但是我需要一种方法在 uberjar 过程中(而不是在运行时当 jar 不再在 repo 中时)将其嵌入代码中,以便从我使用 compojure 定义并通过 http-kit 提供的 URL 路由返回。如何在编译时或构建时运行该函数并将其转储到常量或其他我可以从路由返回的东西?
虽然我想要一个沿着这些思路的解决方案,正如所说的,这里的最终游戏是能够通过 HTTP 查询正在运行的实例并找到运行的代码的确切版本(强烈喜欢 git sha 而不是例如 semver 编号)生产中的给定实例。
我意识到我可以通过将 repo 克隆到所有实例并通过例如 ansible 在本地构建 jar 并在已知目录中查找 sha 来解决这个问题,但这看起来,嗯,hacky,以及容易出错 vs “签名” jar 文件可以说是在构建时。
编辑:
我的 project.clj 看起来像这样:
(defproject gps-server "0.1.0-SNAPSHOT"
:description "Receives GPS data over TCP"
:url "http://someurl"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [...]
:main ^:skip-aot gps-server.core
:target-path "target/%s"
:profiles {:uberjar {:aot [gps-server.core]}})