1+ const Diffable = require ( './diffable' )
2+
3+ module . exports = class Environments extends Diffable {
4+ constructor ( ...args ) {
5+ super ( ...args )
6+
7+ if ( this . entries ) {
8+ // Force all names to lowercase to avoid comparison issues.
9+ this . entries . forEach ( environment => {
10+ environment . name = environment . name . toLowerCase ( ) ;
11+ if ( environment . variables ) {
12+ environment . variables . forEach ( variable => {
13+ variable . name = variable . name . toLowerCase ( ) ;
14+ } ) ;
15+ }
16+ } )
17+ }
18+ }
19+
20+ async find ( ) {
21+ const { data : { environments } } = await this . github . request ( 'GET /repos/:org/:repo/environments' , {
22+ org : this . repo . owner ,
23+ repo : this . repo . repo
24+ } ) ;
25+
26+ let environments_mapped = [ ] ;
27+
28+ for ( let environment of environments ) {
29+ const mapped = {
30+ name : environment . name . toLowerCase ( ) ,
31+ repo : this . repo . repo ,
32+ wait_timer : ( environment . protection_rules . find ( rule => rule . type === 'wait_timer' ) || { wait_timer : 0 } ) . wait_timer ,
33+ prevent_self_review : ( environment . protection_rules . find ( rule => rule . type === 'required_reviewers' ) || { prevent_self_review : false } ) . prevent_self_review ,
34+ reviewers : ( environment . protection_rules . find ( rule => rule . type === 'required_reviewers' ) || { reviewers : [ ] } ) . reviewers . map ( reviewer => ( { id : reviewer . reviewer . id , type : reviewer . type } ) ) ,
35+ deployment_branch_policy : environment . deployment_branch_policy === null ? null : {
36+ protected_branches : ( environment . deployment_branch_policy || { protected_branches : false } ) . protected_branches ,
37+ custom_branch_policies : ( environment . deployment_branch_policy || { custom_branch_policies : false } ) . custom_branch_policies && ( await this . github . request ( 'GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies' , {
38+ org : this . repo . owner ,
39+ repo : this . repo . repo ,
40+ environment_name : environment . name
41+ } ) ) . data . branch_policies . map ( policy => ( {
42+ name : policy . name
43+ } ) )
44+ } ,
45+ variables : ( await this . github . request ( 'GET /repos/:org/:repo/environments/:environment_name/variables' , {
46+ org : this . repo . owner ,
47+ repo : this . repo . repo ,
48+ environment_name : environment . name
49+ } ) ) . data . variables . map ( variable => ( { name : variable . name . toLowerCase ( ) , value : variable . value } ) ) ,
50+ deployment_protection_rules : ( await this . github . request ( 'GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules' , {
51+ org : this . repo . owner ,
52+ repo : this . repo . repo ,
53+ environment_name : environment . name
54+ } ) ) . data . custom_deployment_protection_rules . map ( rule => ( {
55+ app_id : rule . app . id ,
56+ id : rule . id
57+ } ) )
58+ }
59+ environments_mapped . push ( mapped ) ;
60+ //console.log(mapped);
61+ }
62+
63+ return environments_mapped ;
64+ }
65+
66+ comparator ( existing , attrs ) {
67+ return existing . name === attrs . name
68+ }
69+
70+ getChanged ( existing , attrs ) {
71+ if ( ! attrs . wait_timer ) attrs . wait_timer = 0 ;
72+ if ( ! attrs . prevent_self_review ) attrs . prevent_self_review = false ;
73+ if ( ! attrs . reviewers ) attrs . reviewers = [ ] ;
74+ if ( ! attrs . deployment_branch_policy ) attrs . deployment_branch_policy = null ;
75+ if ( ! attrs . variables ) attrs . variables = [ ] ;
76+ if ( ! attrs . deployment_protection_rules ) attrs . deployment_protection_rules = [ ] ;
77+
78+ const wait_timer = existing . wait_timer !== attrs . wait_timer ;
79+ const prevent_self_review = existing . prevent_self_review !== attrs . prevent_self_review ;
80+ const reviewers = JSON . stringify ( existing . reviewers . sort ( ( x1 , x2 ) => x1 . id - x2 . id ) ) !== JSON . stringify ( attrs . reviewers . sort ( ( x1 , x2 ) => x1 . id - x2 . id ) ) ;
81+
82+ let existing_custom_branch_policies = existing . deployment_branch_policy === null ? null : existing . deployment_branch_policy . custom_branch_policies ;
83+ if ( typeof ( existing_custom_branch_policies ) === 'object' && existing_custom_branch_policies !== null ) {
84+ existing_custom_branch_policies = existing_custom_branch_policies . sort ( ) ;
85+ }
86+ let attrs_custom_branch_policies = attrs . deployment_branch_policy === null ? null : attrs . deployment_branch_policy . custom_branch_policies ;
87+ if ( typeof ( attrs_custom_branch_policies ) === 'object' && attrs_custom_branch_policies !== null ) {
88+ attrs_custom_branch_policies = attrs_custom_branch_policies . sort ( ) ;
89+ }
90+ let deployment_branch_policy ;
91+ if ( existing . deployment_branch_policy === attrs . deployment_branch_policy ) {
92+ deployment_branch_policy = false ;
93+ }
94+ else {
95+ deployment_branch_policy = (
96+ ( existing . deployment_branch_policy === null && attrs . deployment_branch_policy !== null ) ||
97+ ( existing . deployment_branch_policy !== null && attrs . deployment_branch_policy === null ) ||
98+ ( existing . deployment_branch_policy . protected_branches !== attrs . deployment_branch_policy . protected_branches ) ||
99+ ( JSON . stringify ( existing_custom_branch_policies ) !== JSON . stringify ( attrs_custom_branch_policies ) )
100+ ) ;
101+ }
102+
103+ const variables = JSON . stringify ( existing . variables . sort ( ( x1 , x2 ) => x1 . name - x2 . name ) ) !== JSON . stringify ( attrs . variables . sort ( ( x1 , x2 ) => x1 . name - x2 . name ) ) ;
104+ const deployment_protection_rules = JSON . stringify ( existing . deployment_protection_rules . map ( x => ( { app_id : x . app_id } ) ) . sort ( ( x1 , x2 ) => x1 . app_id - x2 . app_id ) ) !== JSON . stringify ( attrs . deployment_protection_rules . map ( x => ( { app_id : x . app_id } ) ) . sort ( ( x1 , x2 ) => x1 . app_id - x2 . app_id ) ) ;
105+
106+ return { wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules} ;
107+ }
108+
109+ changed ( existing , attrs ) {
110+ const { wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules} = this . getChanged ( existing , attrs ) ;
111+
112+ return wait_timer || prevent_self_review || reviewers || deployment_branch_policy || variables || deployment_protection_rules ;
113+ }
114+
115+ async update ( existing , attrs ) {
116+ const { wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules} = this . getChanged ( existing , attrs ) ;
117+
118+ if ( wait_timer || prevent_self_review || reviewers || deployment_branch_policy ) {
119+ await this . github . request ( `PUT /repos/:org/:repo/environments/:environment_name` , {
120+ org : this . repo . owner ,
121+ repo : this . repo . repo ,
122+ environment_name : attrs . name ,
123+ wait_timer : attrs . wait_timer ,
124+ prevent_self_review : attrs . prevent_self_review ,
125+ reviewers : attrs . reviewers ,
126+ deployment_branch_policy : attrs . deployment_branch_policy === null ? null : {
127+ protected_branches : attrs . deployment_branch_policy . protected_branches ,
128+ custom_branch_policies : ! ! attrs . deployment_branch_policy . custom_branch_policies
129+ }
130+ } )
131+ }
132+
133+ if ( deployment_branch_policy && attrs . deployment_branch_policy && attrs . deployment_branch_policy . custom_branch_policies ) {
134+ const existingPolicies = ( await this . github . request ( 'GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies' , {
135+ org : this . repo . owner ,
136+ repo : this . repo . repo ,
137+ environment_name : attrs . name
138+ } ) ) . data . branch_policies ;
139+
140+ for ( let policy of existingPolicies ) {
141+ await this . github . request ( 'DELETE /repos/:org/:repo/environments/:environment_name/deployment-branch-policies/:branch_policy_id' , {
142+ org : this . repo . owner ,
143+ repo : this . repo . repo ,
144+ environment_name : attrs . name ,
145+ branch_policy_id : policy . id
146+ } ) ;
147+ }
148+
149+ for ( let policy of attrs . deployment_branch_policy . custom_branch_policies ) {
150+ await this . github . request ( 'POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies' , {
151+ org : this . repo . owner ,
152+ repo : this . repo . repo ,
153+ environment_name : attrs . name ,
154+ name : policy
155+ } ) ;
156+ }
157+ }
158+
159+ if ( variables ) {
160+ let existingVariables = [ ...existing . variables ] ;
161+ for ( let variable of attrs . variables ) {
162+ const existingVariable = existingVariables . find ( ( _var ) => _var . name === variable . name ) ;
163+ if ( existingVariable ) {
164+ existingVariables = existingVariables . filter ( _var => _var . name !== variable . name ) ;
165+ if ( existingVariable . value !== variable . value ) {
166+ await this . github . request ( `PATCH /repos/:org/:repo/environments/:environment_name/variables/:variable_name` , {
167+ org : this . repo . owner ,
168+ repo : this . repo . repo ,
169+ environment_name : attrs . name ,
170+ variable_name : variable . name ,
171+ value : variable . value
172+ } ) ;
173+ }
174+ }
175+ else {
176+ await this . github . request ( `POST /repos/:org/:repo/environments/:environment_name/variables` , {
177+ org : this . repo . owner ,
178+ repo : this . repo . repo ,
179+ environment_name : attrs . name ,
180+ name : variable . name ,
181+ value : variable . value
182+ } ) ;
183+ }
184+ }
185+
186+ for ( let variable of existingVariables ) {
187+ await this . github . request ( 'DELETE /repos/:org/:repo/environments/:environment_name/variables/:variable_name' , {
188+ org : this . repo . owner ,
189+ repo : this . repo . repo ,
190+ environment_name : attrs . name ,
191+ variable_name : variable . name
192+ } ) ;
193+ }
194+ }
195+
196+ if ( deployment_protection_rules ) {
197+ let existingRules = [ ...existing . deployment_protection_rules ] ;
198+ for ( let rule of attrs . deployment_protection_rules ) {
199+ const existingRule = existingRules . find ( ( _rule ) => _rule . id === rule . id ) ;
200+
201+ if ( ! existingRule ) {
202+ await this . github . request ( `POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules` , {
203+ org : this . repo . owner ,
204+ repo : this . repo . repo ,
205+ environment_name : attrs . name ,
206+ integration_id : rule . app_id
207+ } ) ;
208+ }
209+ }
210+
211+ for ( let rule of existingRules ) {
212+ await this . github . request ( 'DELETE /repos/:org/:repo/environments/:environment_name/deployment_protection_rules/:rule_id' , {
213+ org : this . repo . owner ,
214+ repo : this . repo . repo ,
215+ environment_name : attrs . name ,
216+ rule_id : rule . id
217+ } ) ;
218+ }
219+ }
220+ }
221+
222+ async add ( attrs ) {
223+ await this . github . request ( `PUT /repos/:org/:repo/environments/:environment_name` , {
224+ org : this . repo . owner ,
225+ repo : this . repo . repo ,
226+ environment_name : attrs . name ,
227+ wait_timer : attrs . wait_timer ,
228+ prevent_self_review : attrs . prevent_self_review ,
229+ reviewers : attrs . reviewers ,
230+ deployment_branch_policy : attrs . deployment_branch_policy === null ? null : {
231+ protected_branches : attrs . deployment_branch_policy . protected_branches ,
232+ custom_branch_policies : ! ! attrs . deployment_branch_policy . custom_branch_policies
233+ }
234+ } ) ;
235+
236+ if ( attrs . deployment_branch_policy && attrs . deployment_branch_policy . custom_branch_policies ) {
237+ for ( let policy of attrs . deployment_branch_policy . custom_branch_policies ) {
238+ await this . github . request ( 'POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies' , {
239+ org : this . repo . owner ,
240+ repo : this . repo . repo ,
241+ environment_name : attrs . name ,
242+ name : policy . name
243+ } ) ;
244+ }
245+ }
246+
247+
248+ for ( let variable of attrs . variables ) {
249+ await this . github . request ( `POST /repos/:org/:repo/environments/:environment_name/variables` , {
250+ org : this . repo . owner ,
251+ repo : this . repo . repo ,
252+ environment_name : attrs . name ,
253+ name : variable . name ,
254+ value : variable . value
255+ } ) ;
256+ }
257+
258+ for ( let rule of attrs . deployment_protection_rules ) {
259+ await this . github . request ( `POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules` , {
260+ org : this . repo . owner ,
261+ repo : this . repo . repo ,
262+ environment_name : attrs . name ,
263+ integration_id : rule . app_id
264+ } ) ;
265+ }
266+ }
267+
268+ async remove ( existing ) {
269+ await this . github . request ( `DELETE /repos/:org/:repo/environments/:environment_name` , {
270+ org : this . repo . owner ,
271+ repo : this . repo . repo ,
272+ environment_name : existing . name
273+ } ) ;
274+ }
275+ }
0 commit comments