Skip to content

Commit

Permalink
Update wrike-ist action to include Github links in Azure (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushgaud authored Sep 10, 2024
1 parent 0a6cdf0 commit 79e237b
Show file tree
Hide file tree
Showing 14 changed files with 32,274 additions and 6,260 deletions.
1 change: 1 addition & 0 deletions .github/workflows/develop.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
- name: wrike-ist
env:
WRIKE_TOKEN: ${{ secrets.WRIKE_TOKEN }}
AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }}
uses: ./
with:
opened: "In review"
1 change: 1 addition & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
- name: wrike-ist
env:
WRIKE_TOKEN: ${{ secrets.WRIKE_TOKEN }}
AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }}
uses: ./
with:
opened: "In review"
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- name: wrike-ist
env:
WRIKE_TOKEN: ${{ secrets.WRIKE_TOKEN }}
AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }}
uses: ./
with:
opened: "In review"
2,822 changes: 2,822 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "wrike-ist",
"version": "1.6.3",
"description": "GitHub Action for Wrike automation",
"version": "1.6.4",
"description": "GitHub Action for Wrike and Azure automation",
"main": "resources/main.js",
"scripts": {
"build": "shadow-cljs compile main",
Expand Down
33,503 changes: 28,757 additions & 4,746 deletions resources/index.js

Large diffs are not rendered by default.

1,002 changes: 523 additions & 479 deletions resources/main.js

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions src/wrike_ist/azure.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
(ns wrike-ist.azure
(:require [httpurr.client.node :as http]
[clojure.string :as str]))
(defn- azure-token []
(some-> js/process .-env .-AZURE_TOKEN .trim))

(defn- headers []
{:Authorization (str "Basic " (js/btoa (str ":" (azure-token))))
:Content-Type "application/json"})

(defn parse-body
[response]
(js->clj (js/JSON.parse (:body response))))

(defn link-html
[{:keys [id pr-url target-branch repository-name title]}]
(if (empty? title)
(str "Pull request for " target-branch ": " "<a href=\"" pr-url "\">" " (#" id ")</a>")
(str "Pull request for " repository-name " on branch " target-branch ": " "<a href=\"" pr-url "\">" title " (#" id ")</a>")))

(defn find-task
[url]
(let [pattern #"https://dev\.azure\.com/([^/]+)/([^/]+)/_workitems/edit/(\d+)"
matches (re-seq pattern url)]
(js/Promise.
(fn [resolve reject]
(if (seq matches)
(let [[_ organization project task-id] (first matches)]
(resolve {:organization organization
:project project
:task-id (js/parseInt task-id)}))
(reject (js/Error. "No task ID found")))))))

(defn link-pr
[{:keys [pr-url permalink] :as details}]
(.then
(find-task permalink)
(fn [{:keys [organization project task-id]}]
(js/console.log (str "link-pr: Found organization:" organization " project:" project " task-id:" task-id))
(js/console.log (str "headers:" (headers)))
(let [uri (str "https://dev.azure.com/" organization "/" project "/_apis/wit/workitems/" task-id "/comments?api-version=7.0-preview.3")]
;; (js/console.log (str "uri:" uri))
(-> (http/get uri {:headers (headers)})
(.then (fn find-existing-link [response]
;; (js/console.log (str "find-existing-link: response:" 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) "comments"))))
(.then (fn add-link-comment [& _]
(let [comment-text (link-html details)
params (clj->js {:text comment-text})]
(js/console.log (str "add-link-comment: params:" (js/JSON.stringify params)))
(-> (http/post uri {:headers (headers)
:body (js/JSON.stringify params)})
(.then (fn [response]
(js/console.log (str "add-link-comment: response:" response)))))
)))
(.then #(js/console.log "PR link sent to task"))
(.catch #(if (= % :present)
(js/console.log "PR link already in comments")
(js/Promise.reject %))))))))
45 changes: 28 additions & 17 deletions src/wrike_ist/core.cljs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
(ns wrike-ist.core
(:require ["@actions/core" :as core]
["@actions/github" :as github]
[wrike-ist.wrike :as wrike]))
[wrike-ist.wrike :as wrike]
[wrike-ist.azure :as azure]))

(defn find-links
[text]
(not-empty (re-seq #"\bhttps://www\.wrike\.com/open\.htm\?id=\d+\b" text)))
(not-empty (re-seq #"\bhttps://www\.wrike\.com/open\.htm\?id=\d+\b|\bhttps://dev\.azure\.com/[^/]+/[^/]+/_workitems/edit/\d+\b" text)))

(defn extract-details
[pr-obj]
Expand All @@ -32,27 +33,37 @@
:repository-name repository-name})
links)))))

(defn find-link-type
[url]
(cond
(re-find #"\bhttps://www\.wrike\.com/open\.htm\?id=\d+\b" url) :wrike
(re-find #"\bhttps://dev\.azure\.com/[^/]+/[^/]+/_workitems/edit/\d+\b" url) :azure
:else :unknown))

(defn main
[]
(let [payload (.-payload (.-context github))]
(if-let [pr (.-pull_request payload)]
(loop [links (extract-details pr)]
(when-let [{:keys [state] :as details} (first links)]
(-> (case state
:draft
(wrike/link-pr details)

:open
(wrike/link-pr details)

:merged
(wrike/complete-task details (core/getInput "merged"))
(when-let [{:keys [state pr-url permalink] :as details} (first links)]
(let [link-type (find-link-type permalink)]
(-> (case state
:draft
(case link-type
:wrike (wrike/link-pr details)
:azure (azure/link-pr details)
:unknown (js/console.log (str "Unknown link type: " permalink))
(js/Promise.resolve))

:closed
(wrike/cancel-task details (core/getInput "closed"))
:open
(case link-type
:wrike (wrike/link-pr details)
:azure (azure/link-pr details)
:unknown (js/console.log (str "Unknown link type: " permalink))
(js/Promise.resolve))

;; else ignore
(js/Promise.resolve))
(.catch #(core/setFailed (.-message %))))
;; else ignore
(js/Promise.resolve))
(.catch #(core/setFailed (.-message %)))))
(recur (rest links))))
(js/console.log "No pull_request in payload"))))
42 changes: 12 additions & 30 deletions src/wrike_ist/wrike.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -114,48 +114,30 @@
(resolve true))))))

(defn link-pr
[{:keys [pr-url permalink target-branch] :as details}]
(let [check-valid-task-promise (check-valid-task permalink target-branch)]
(-> (find-task permalink)
(.then
(fn [{:strs [id]}]
(let [uri (str "https://www.wrike.com/api/v4/tasks/" id "/comments")]
(-> (http/get uri {:headers (headers)})
(.then
(fn find-existing-link [response]
[{:keys [pr-url permalink] :as details}]
(.then
(find-task permalink)
(fn [{:strs [id]}]
(let [uri (str "https://www.wrike.com/api/v4/tasks/" id "/comments")]
(-> (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 [& _]
(.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
(fn [_]
(.log js/console (str "link-pr: PR link sent to task"))
(js/Promise.resolve)))
(.catch
#(if (= % :present)
(.log js/console (str "link-pr: PR link already in comments"))
(js/Promise.resolve %)))))))
(.then
(fn [_]
(js/Promise.all [check-valid-task-promise
(.then check-valid-task-promise
(fn [result]
(.log js/console (str "check-valid-task-promise value: " result))))])))
(.catch
#(do
(.log js/console (str "link-pr: Rejected with reason: " %))
(js/Promise.reject %))))))

(.then #(js/console.log "PR link sent to task"))
(.catch #(if (= % :present)
(js/console.log "PR link already in comments")
(js/Promise.reject %))))))))


(defn folder-statuses
Expand Down
15 changes: 15 additions & 0 deletions test/wrike_ist/azure_test.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(ns wrike-ist.azure-test
(:require [cljs.test :refer-macros [deftest is testing]]
[wrike-ist.azure :refer [link-html]]))

(deftest link-html-test
(testing "No title"
(let [url "https://github.com/valerauko/wrike-ist/pull/9001"
data {:pr-url url}]
(is (= url (re-find (re-pattern url) (link-html data))))))
(testing "With title"
(let [url "https://github.com/valerauko/wrike-ist/pull/9001"
title "hoge"
data {:pr-url url :title title}]
(is (= url (re-find (re-pattern url) (link-html data))))
(is (= title (re-find (re-pattern title) (link-html data)))))))
60 changes: 28 additions & 32 deletions test/wrike_ist/core_test.cljs
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
(ns wrike-ist.core-test
(:require [cljs.test :refer-macros [deftest is testing]]
[wrike-ist.core :refer [extract-details
find-links]]))
find-links
find-link-type]]))

(deftest links-test
(testing "No link in text"
(is (= nil (find-links ""))))
(testing "One link in text"
(let [url "https://www.wrike.com/open.htm?id=1"]
(let [url "https://dev.azure.com/organization/project/_workitems/edit/1"]
(is (= (list url) (find-links (str "a\n" url "\nb"))))))
(testing "Multiple links in text"
(let [url-1 "https://www.wrike.com/open.htm?id=1"
(let [url-1 "https://dev.azure.com/organization/project/_workitems/edit/1"
url-2 "https://www.wrike.com/open.htm?id=2"]
(is (= (list url-1 url-2) (find-links (str url-1 "\nfoo: " url-2 "\n"))))))
(testing "No separator around the link"
;; anything \b matches will do
(let [url "https://www.wrike.com/open.htm?id=1"]
(let [url "https://dev.azure.com/organization/project/_workitems/edit/1"]
(is (= nil (find-links (str "1" url))))
(is (= nil (find-links (str url "b"))))
(is (= nil (find-links (str "1" url "b")))))))

(deftest find-link-type-test
(testing "Extract link from payload"
(testing "Multiple links"
(let [url-1 "https://dev.azure.com/organization/project/_workitems/edit/1"
url-2 "https://www.wrike.com/open.htm?id=2"
payload (clj->js {:body (str "a\n" url-1 "\nb " url-2)
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(loop [links (extract-details payload)]
(when-let [{:keys [permalink]} (first links)]
(let [link-type (find-link-type permalink)]
(is (= link-type :azure))))
(when-let [{:keys [permalink]} (second links)]
(let [link-type (find-link-type permalink)]
(is (= link-type :wrike)))))))))


(deftest extract-details-test
(testing "No .body in payload"
(let [payload (clj->js {})]
Expand All @@ -29,13 +47,13 @@
(is (= nil (extract-details payload)))))
(testing "Extract link from payload"
(testing "One link"
(let [url "https://www.wrike.com/open.htm?id=1"
(let [url "https://dev.azure.com/organization/project/_workitems/edit/1"
payload (clj->js {:body (str "a\n" url "\nb")
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= url (:permalink (first (extract-details payload)))))))
(testing "Multiple links"
(let [url-1 "https://www.wrike.com/open.htm?id=1"
(let [url-1 "https://dev.azure.com/organization/project/_workitems/edit/1"
url-2 "https://www.wrike.com/open.htm?id=2"
payload (clj->js {:body (str "a\n" url-1 "\nb " url-2)
:base (clj->js {:ref "feature-branch"})
Expand All @@ -44,48 +62,26 @@
(is (= url-2 (:permalink (second (extract-details payload))))))))
(testing "Extract pull request URL from payload"
(let [url "https://github.com/valerauko/wrike-ist/pull/9001"
payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
payload (clj->js {:body "https://dev.azure.com/organization/project/_workitems/edit/1"
:html_url url
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= url (:pr-url (first (extract-details payload)))))))
(testing "Extract pull request title from payload"
(let [title "hoge"
payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
payload (clj->js {:body "https://dev.azure.com/organization/project/_workitems/edit/1"
:title title
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= title (:title (first (extract-details payload)))))))
(testing "Translating pull request state"
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
:merged true
:state "closed"
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :merged (:state (first (extract-details payload))))))
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
:merged true
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :merged (:state (first (extract-details payload))))))
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
:merged false
:state "closed"
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :closed (:state (first (extract-details payload))))))
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
:state "closed"
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :closed (:state (first (extract-details payload))))))
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
(let [payload (clj->js {:body "https://dev.azure.com/organization/project/_workitems/edit/1"
:merged false
:state "open"
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :open (:state (first (extract-details payload))))))
(let [payload (clj->js {:body "https://www.wrike.com/open.htm?id=1"
(let [payload (clj->js {:body "https://dev.azure.com/organization/project/_workitems/edit/1"
:base (clj->js {:ref "feature-branch"})
:head (clj->js {:repo (clj->js {:name "your-repo-name"})})})]
(is (= :open (:state (first (extract-details payload))))))))
Loading

0 comments on commit 79e237b

Please sign in to comment.