Skip to content
This repository was archived by the owner on Jun 15, 2024. It is now read-only.

Commit 49e13d0

Browse files
committed
Implement fallback for builds without stored pipeline-structure, displaying warning in UI #131, #6
1 parent 2fc0ee9 commit 49e13d0

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

src/clj/lambdacd/internal/default_pipeline_state_persistence.clj

+4-2
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,14 @@
9898
(spit f (pr-str pipeline-structure))))
9999

100100
(defn- read-pipeline-structure-edn [f]
101-
{(build-number-from-path f) (edn/read-string (slurp f))})
101+
(let [build-number (build-number-from-path f)]
102+
(if (file-exists? f)
103+
{build-number (edn/read-string (slurp f))}
104+
{build-number :fallback})))
102105

103106
(defn read-pipeline-structures [home-dir]
104107
(->> (build-dirs home-dir)
105108
(map pipeline-structure-path)
106-
(filter file-exists?)
107109
(map read-pipeline-structure-edn)
108110
(into {})))
109111

src/clj/lambdacd/state/core.clj

+21-2
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,29 @@
6464
(get (get-step-results ctx build-number)
6565
step-id))
6666

67+
(defn- annotated-step [step]
68+
(let [annotate-children (fn [x]
69+
(if (:children x)
70+
(assoc x :children (map annotated-step (:children x)))
71+
x))]
72+
(-> step
73+
(assoc :pipeline-structure-fallback true)
74+
(annotate-children))))
75+
76+
(defn- annotated-fallback-structure [ctx]
77+
(let [current-structure (pipeline-structure/pipeline-display-representation (:pipeline-def ctx))]
78+
(map annotated-step current-structure)))
79+
80+
(defn- stored-structure-or-fallback [ctx build-number]
81+
(let [stored-structure (protocols/get-pipeline-structure (state-component ctx) build-number)]
82+
(if (= :fallback stored-structure)
83+
(annotated-fallback-structure ctx)
84+
stored-structure)))
85+
6786
(defn get-pipeline-structure
6887
"Returns a map describing the structure of the pipeline"
6988
[ctx build-number]
7089
(let [component (state-component ctx)]
7190
(if (satisfies? protocols/PipelineStructureSource component)
72-
(protocols/get-pipeline-structure component build-number)
73-
(pipeline-structure/pipeline-display-representation (:pipeline-def ctx)))))
91+
(stored-structure-or-fallback ctx build-number)
92+
(annotated-fallback-structure ctx))))

src/cljs/lambdacd/pipeline.cljs

+7-1
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,19 @@
189189
[:li [:a {:class (classes "pipeline__controls__control" (control-active-if @expand-active?)) :on-click #(re-frame/dispatch [::db/toggle-expand-active])} "Expand active"]]
190190
[:li [:a {:class (classes "pipeline__controls__control" (control-active-if @expand-failures?)) :on-click #(re-frame/dispatch [::db/toggle-expand-failures])} "Expand failures"]]])))
191191

192+
(defn old-pipeline-structure-warning [build-steps]
193+
(if (:pipeline-structure-fallback (first build-steps))
194+
[:ul {:class "pipeline__controls"}
195+
[:li {:class "pipeline__controls__control warning"} [:i {:class "fa fa-exclamation warning-icon"}] "This is an old build with no stored pipeline structure. Using current structure as a best guess. Display and retriggering might not work as expected."]]))
196+
192197
(defn pipeline-component []
193198
(let [build-state-atom (re-frame/subscribe [::db/pipeline-state])
194199
build-number-subscription (re-frame/subscribe [::db/build-number])]
195200
(fn []
196201
[:div {:class "pipeline" :key "build-pipeline"}
197202
[pipeline-controls]
203+
[old-pipeline-structure-warning @build-state-atom]
198204
[:ol {:class "pipeline__step-container pipeline__step-container--sequential"}
199205
(doall
200206
(for [step @build-state-atom]
201-
^{:key (:step-id step)} [build-step step @build-number-subscription]))]])))
207+
^{:key (:step-id step)} [build-step step @build-number-subscription]))]])))

src/less/app.less

+11-1
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,14 @@
4747
display: flex;
4848
justify-content: center;
4949
align-items: center;
50-
}
50+
}
51+
52+
.warning-icon {
53+
padding-top: 5px;
54+
padding-bottom: 5px;
55+
padding-right: 5px;
56+
}
57+
58+
.warning {
59+
color: @base-orange;
60+
}

test/clj/lambdacd/internal/default_pipeline_state_persistence_test.clj

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@
7474
(testing "that it will return an empty data if no state has been written yet"
7575
(let [home-dir (utils/create-temp-dir)]
7676
(is (= {} (read-pipeline-structures home-dir)))))
77-
(testing "that it ignores build directories with no pipeline structure (e.g. because they were created before this feature was available)"
77+
(testing "that it adds a fallback-marker for build directories with no pipeline structure (e.g. because they were created before this feature was available)"
7878
(let [home-dir (utils/create-temp-dir)]
7979
(.mkdirs (io/file home-dir "build-1"))
80-
(is (= {} (read-pipeline-structures home-dir))))))
80+
(is (= {1 :fallback} (read-pipeline-structures home-dir))))))
8181

8282
(defn- roundtrip-date-time [data]
8383
(dates->clj-times

test/clj/lambdacd/state/core_test.clj

+22-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,22 @@
1010
(def some-step-id [0])
1111
(def some-step-result {:foo :bat})
1212
(def some-structure {:some :structure})
13-
(def some-pipeline-def `(foo))
13+
14+
(defn ^{:display-type :container} foo [& _])
15+
(defn bar [& _])
16+
(def some-pipeline-def `((foo
17+
bar)))
18+
19+
(def some-pipeline-def-structure [{:name "foo"
20+
:type :container
21+
:has-dependencies false
22+
:pipeline-structure-fallback true
23+
:step-id `(1)
24+
:children [{:name "bar"
25+
:type :step
26+
:has-dependencies false
27+
:pipeline-structure-fallback true
28+
:step-id `(1 1)}]}])
1429

1530
(deftest consume-step-result-update-test
1631
(testing "that calls to a StepResultUpdateConsumer will just pass through"
@@ -85,8 +100,9 @@
85100
(is (received? component state-protocols/get-pipeline-structure [1]))))
86101
(testing "that we get the current pipeline structure if the component doesn't support PipelineStructures"
87102
(let [component (mock state-protocols/QueryStepResultsSource {:get-step-results {:some :step-results}})]
88-
(is (= [{:name "foo"
89-
:type :unknown
90-
:has-dependencies false
91-
:step-id `(1)}] (s/get-pipeline-structure (some-ctx-with :pipeline-state-component component
92-
:pipeline-def some-pipeline-def) 1))))))
103+
(is (= some-pipeline-def-structure (s/get-pipeline-structure (some-ctx-with :pipeline-state-component component
104+
:pipeline-def some-pipeline-def) 1)))))
105+
(testing "that we get the current pipeline structure if the component returns :fallback and annotate the structure accordingly"
106+
(let [component (mock state-protocols/PipelineStructureSource {:get-pipeline-structure :fallback})]
107+
(is (= some-pipeline-def-structure (s/get-pipeline-structure (some-ctx-with :pipeline-state-component component
108+
:pipeline-def some-pipeline-def) 1))))))

0 commit comments

Comments
 (0)