diff --git a/src/wrike_ist/azure.cljs b/src/wrike_ist/azure.cljs index cd89211..3a68bc1 100644 --- a/src/wrike_ist/azure.cljs +++ b/src/wrike_ist/azure.cljs @@ -13,72 +13,9 @@ {:Authorization (str "Basic " (js/btoa (str ":" (azure-token)))) :Content-Type "application/json"}) -(defn fetch-work-item - [id] - (let [uri (str "https://dev.azure.com/" organization "/" project "/_apis/wit/workitems/" id "?api-version=6.0")] - (-> (http/get uri {:headers (headers)}) - (.then (fn [response] - (js->clj (js/JSON.parse (:body response)))))))) - -(defn update-work-item-status - [id new-status] - (let [uri (str "https://dev.azure.com/" organization "/" project "/_apis/wit/workitems/" id "?api-version=6.0") - patch-body [{:op "add" - :path "/fields/System.State" - :value new-status}] - params (clj->js patch-body)] - (-> (http/patch uri {:headers (headers) - :body (js/JSON.stringify params)}) - (.then (fn [response] - (js->clj (js/JSON.parse (:body response)))))))) - -(defn link-pr - [{:keys [work-item-id pr-url]}] - (let [comment-text (str "Pull Request")] - (-> (fetch-work-item work-item-id) ;; Fetch work item - (.then (fn [work-item] - (let [uri (str "https://dev.azure.com/" organization "/" project "/_apis/wit/workitems/" work-item-id "/comments?api-version=6.0")] - (-> (http/post uri {:headers (headers) - :body (js/JSON.stringify {:text comment-text - :plainText false})}) - (.then (fn [response] - (js/console.log (js/JSON.parse (:body response))) - (js/console.log "PR link added to work item"))) - (.catch (fn [error] - (js/console.error "Failed to add PR link:" error))))))) - (.catch (fn [error] - (js/console.error "Failed to fetch work item:" error)))))) - -(defn check-valid-work-item - [id target-branch] - (if (and target-branch (str/starts-with? target-branch "release")) - (-> (fetch-work-item id) - (.then - (fn [work-item] - (let [status (get-in work-item ["fields" "System.State"])] - (if (some #{status} ["Active" "New" "Approved"]) - (do - (js/console.log "Work item is valid") - (js/Promise.resolve true)) - (do - (js/console.log "Work item is not valid") - (js/Promise.resolve false)))))) - (.catch (fn [error] - (js/console.error "Error checking work item validity:" error)))) - (do - (js/console.log "Target branch is not a release branch, skipping validation") - (js/Promise.resolve true)))) - -(defn process-pull-request - [{:keys [pr-url work-item-id target-branch]}] - (-> (check-valid-work-item work-item-id target-branch) - (.then (fn [valid?] - (if valid? - (link-pr {:work-item-id work-item-id - :pr-url pr-url}) - (js/console.log "Skipping PR link due to invalid work item")))) - (.catch (fn [error] - (js/console.error "Error processing pull request:" error))))) +(defn parse-body + [response] + (js->clj (js/JSON.parse (:body response)))) (def link-badge (str " ")) - (defn link-html +(defn link-html [{:keys [id pr-url target-branch repository-name title]}] (if (empty? title) (str link-badge target-branch ": " "" " (#" id ")") (str link-badge repository-name " on branch " target-branch ": " "" title " (#" id ")"))) + +(defn find-task + [url] + (let [pattern #"https://dev\.azure\.com/[^/]+/[^/]+/_workitems/edit/(\d+)" + matches (re-seq pattern url)] + (when (seq matches) + (some-> (first matches) + (second))))) ;; Extract the match group (ID) + +(defn link-pr + [{:keys [pr-url permalink] :as details}] + (let [work-item-id (find-task permalink)] + (.then + (find-task permalink) + (fn [{:strs [id]}] + (let [uri (str "https://dev.azure.com/" organization "/" project "/_apis/wit/workitems/" work-item-id "/comments?api-version=6.0")] + (-> (http/get uri {:headers (headers)}) + (.then (fn find-existing-link [response] + (reduce + (fn [ok comment] + (if (.includes (get comment "text") pr-url) + (reduced (js/Promise.reject :present)) + ok)) + (js/Promise.resolve) + (get (parse-body response) "data")))) + (.then (fn add-link-comment [& _] + (let [comment-text (link-html details) + params (clj->js {:text comment-text + :plainText false})] + (http/post uri {:headers (headers) + :body (js/JSON.stringify params)})))) + (.then #(js/console.log "PR link sent to task")) + (.catch #(if (= % :present) + (js/console.log "PR link already in comments") + (js/Promise.reject %)))))))))