fix enterprise release publisher upload issues, add flag to skip build phase

master
Florian Schrofner 2024-02-01 18:37:35 +01:00
parent 227333cb14
commit 5fc3535853
Signed by: schrofi
GPG Key ID: 576B512668FB44EE
2 changed files with 41 additions and 14 deletions

View File

@ -1,6 +1,16 @@
#! /usr/bin/bb #! /usr/bin/bb
(require '[clojure.tools.cli :refer [parse-opts]])
(require '[babashka.curl :as curl]) (require '[babashka.curl :as curl])
(def cli-options
[["-s" "--skip-build" "Skips the building process and will upload the currently built version."
:id :skip-build
:default false]])
(def parsed-params (parse-opts *command-line-args* cli-options))
(def options (:options parsed-params))
(def code (first (:arguments parsed-params)))
;;executes shell command but throws exception on error ;;executes shell command but throws exception on error
(defn- safe-sh [& commands] (defn- safe-sh [& commands]
(as-> (apply shell/sh commands) $ (as-> (apply shell/sh commands) $
@ -20,40 +30,48 @@
"creates the path string of the output folder for the given module & variant" "creates the path string of the output folder for the given module & variant"
(create-path-string wd module "build" "outputs" "apk" variant)) (create-path-string wd module "build" "outputs" "apk" variant))
(defn- parse-generated-metadata-file [module variant]
(json/parse-string (slurp (create-path-string (get-output-folder module variant) metadata-file)) true))
(defn- create-enterprise-release [module variant] (defn- create-enterprise-release [module variant]
"builds the app using the given module & variant and then returns the parsed metadata" "builds the app using the given module & variant and then returns the parsed metadata"
(println "building project..") (println "building project..")
(safe-sh (create-path-string wd "gradlew") (str ":" module ":assemble" (str/capitalize variant))) (safe-sh (create-path-string wd "gradlew") (str ":" module ":assemble" (str/capitalize variant))))
(json/parse-string (slurp (create-path-string (get-output-folder module variant) metadata-file)) true))
(defn- fetch-remote-config [server path file-name]
(defn- fetch-remote-config [server user path file-name]
"fetches and parses the configuration on the remote server" "fetches and parses the configuration on the remote server"
(let [remote-path (str server path "/" file-name ".json")] (let [remote-path (str server path "/" file-name ".json")]
(println "fetching remote config..") (println "fetching remote config..")
(json/parse-string (:body (curl/get remote-path)) true))) (json/parse-string (->
(:body (curl/get remote-path {:raw-args ["-u" (str user ":")]}))
;; remove non printable characters causing parsing issues
(str/replace #"\p{C}" ""))
true)))
(defn- upload-version [config metadata] (defn- upload-version [config metadata]
"uploads the built apk and updates the remote json to reflect the new version" "uploads the built apk and updates the remote json to reflect the new version"
(let [info (second config) (let [info (second config)
server (:server info) server (:server info)
user (:user info)
path (:path info) path (:path info)
file-name (:fileName info) file-name (:fileName info)
output-folder (get-output-folder (:module info) (:variant info)) output-folder (get-output-folder (:module info) (:variant info))
output-file (create-path-string output-folder (get-in metadata [:elements 0 :outputFile])) output-file (create-path-string output-folder (get-in metadata [:elements 0 :outputFile]))
remote-config (fetch-remote-config server path file-name) remote-config (fetch-remote-config server user path file-name)
new-version (get-in metadata [:elements 0 :versionCode]) new-version (get-in metadata [:elements 0 :versionCode])
version-name (get-in metadata [:elements 0 :versionName])] version-name (get-in metadata [:elements 0 :versionName])]
(if (<= new-version (get-in remote-config [:android :version_code])) (if (<= new-version (get-in remote-config [:android :version_code]))
(println "warning: version on remote was higher or the same as uploaded version")) (println "warning: version on remote was higher or the same as uploaded version"))
(println "uploading apk..") (println "uploading apk..")
(curl/post (str server path "/" file-name ".apk") {:raw-args ["-T" output-file]}) (curl/post (str server path "/" file-name ".apk") {:raw-args ["-T" output-file "-u" (str user ":")]})
(println "updating version on remote..") (println "updating version on remote..")
(let [updated-remote-file (create-path-string output-folder (str file-name ".json"))] (let [updated-remote-file (create-path-string output-folder (str file-name ".json"))]
(as-> remote-config $ (as-> remote-config $
(update-in $ [:android :version_code] (fn [x] new-version)) (update-in $ [:android :version_code] (fn [x] new-version))
(json/generate-string $ {:pretty true}) (json/generate-string $ {:pretty true})
(spit updated-remote-file $)) (spit updated-remote-file $))
(curl/post (str server path "/" file-name ".json") {:raw-args ["-T" updated-remote-file]})) (curl/post (str server path "/" file-name ".json") {:raw-args ["-T" updated-remote-file "-u" (str user ":")]}))
(println (str "new version " version-name " (" new-version ")" " successfully uploaded to " (name (first config)))))) (println (str "new version " version-name " (" new-version ")" " successfully uploaded to " (name (first config))))))
(defn- add-git-tag [config metadata] (defn- add-git-tag [config metadata]
@ -70,13 +88,14 @@
(println (str "created tag " tag " and pushed it to remote " remote))) (println (str "created tag " tag " and pushed it to remote " remote)))
(println "warning: there were uncommitted changes. git tag was not automatically created")))) (println "warning: there were uncommitted changes. git tag was not automatically created"))))
(defn- build-and-upload [config] (defn- build-and-upload [config skip-build]
"builds & uploads the application based on the handed over configuration" "builds & uploads the application based on the handed over configuration"
(let [info (second config) (let [info (second config)
module (:module info) module (:module info)
variant (:variant info) variant (:variant info)
git-tag (:gitTag info)] git-tag (:gitTag info)]
(let [metadata (create-enterprise-release module variant)] (if (not skip-build) (create-enterprise-release module variant))
(let [metadata (parse-generated-metadata-file module variant)]
(upload-version config metadata) (upload-version config metadata)
(if (not (nil? git-tag)) (if (not (nil? git-tag))
(add-git-tag git-tag metadata))))) (add-git-tag git-tag metadata)))))
@ -88,8 +107,8 @@
(def selected-config (def selected-config
(if (if
(= (count config) 1) (first config) (= (count config) 1) (first config)
(first (filter #(= (first %) (keyword (first *command-line-args*))) config)))) (first (filter #(= (first %) (keyword code)) config))))
(if (nil? selected-config) (if (nil? selected-config)
(println "error: no matching config found") (println "error: no matching config found")
(build-and-upload selected-config)) (build-and-upload selected-config (:skip-build options)))

View File

@ -9,6 +9,7 @@ This file can contain multiple release configurations and needs to specify a cou
"DEV": { "DEV": {
"module": "app", "module": "app",
"variant": "debug", "variant": "debug",
"user": "www",
"server": "sftp://127.0.0.1", "server": "sftp://127.0.0.1",
"path": "/var/www/apps/projects/test", "path": "/var/www/apps/projects/test",
"fileName": "Enterprise-Test", "fileName": "Enterprise-Test",
@ -20,6 +21,7 @@ This file can contain multiple release configurations and needs to specify a cou
"INT": { "INT": {
"module": "app", "module": "app",
"variant": "release", "variant": "release",
"user": "www",
"server": "sftp://127.0.0.1", "server": "sftp://127.0.0.1",
"path": "/var/www/apps/projects/test", "path": "/var/www/apps/projects/test",
"fileName": "Enterprise-Test" "fileName": "Enterprise-Test"
@ -29,6 +31,7 @@ This file can contain multiple release configurations and needs to specify a cou
- `module`: Specifies the module built with Gradle. - `module`: Specifies the module built with Gradle.
- `variant`: The variant that should be built. It's combined with the module from above to create the proper Gradle command, e.g. `:app:assembleDebug`. - `variant`: The variant that should be built. It's combined with the module from above to create the proper Gradle command, e.g. `:app:assembleDebug`.
- `server`: The server (including protocol) to upload the files to. - `server`: The server (including protocol) to upload the files to.
- `user`: The user (which will be passed to curl) to use for the server.
- `path`: The path on the remote server where the files should be placed. - `path`: The path on the remote server where the files should be placed.
- `fileName`: The name to be used for the apk & json files on the remote. - `fileName`: The name to be used for the apk & json files on the remote.
- `gitTag`: Optional object specifying the format of git tags that should be created automatically. - `gitTag`: Optional object specifying the format of git tags that should be created automatically.
@ -44,13 +47,18 @@ erp.clj
erp.clj "INT" erp.clj "INT"
``` ```
If you do not want to rebuild your project and just upload the currently built apk, you can use the `--skip-build` or `-s` flag to skip the build phase.
```bash
erp.clj --skip-build
erp.clj -s "INT"
```
## ##
### SSH Configuration ### SSH Configuration
I'm assuming that you've properly defined your credentials in `~/.ssh/config`, so you don't have to specify any credentials in your configuration files. You can assign specific credentials to different hosts there. I'm assuming that you've properly defined your credentials in `~/.ssh/config`. Unfortunately curl does not pick up the users defined inside that file, so the actual user still has to be specified inside `enterprise-releases.json`.
``` ```
Host SERVER Host SERVER
User USER
IdentityFile PATH_TO_KEY IdentityFile PATH_TO_KEY
``` ```
@ -59,7 +67,7 @@ If you don't want to add the script itself to your path you can also create a fi
``` ```
function erp function erp
PATH_TO_SCRIPT/erp.clj $argv[1] PATH_TO_SCRIPT/erp.clj $argv
end end
funcsave erp funcsave erp