Skip to content

Commit 7f254fb

Browse files
authored
Merge pull request #4 from nobre84/slack-environments
Add support for Environment Variables in Slack commands.
2 parents 530a5dd + 6be95b0 commit 7f254fb

File tree

4 files changed

+139
-29
lines changed

4 files changed

+139
-29
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ Other, optional parameters:
151151
**NOTE**: at least either `branch` or `workflow` have to be specified, and of course
152152
you can specify both if you want to. You're free to specify any number of optional parameters.
153153

154-
An example with all parameters included: `workflow: primary|b: master|tag: v1.0|commit:eee55509f16e7715bdb43308bb55e8736da4e21e|m: start my build!`
154+
You can also send environment variables that will be available in your workflow with the format: `env[KEY1]:value1|ENV[KEY2]:value2`
155+
156+
An example with all parameters included: `workflow: primary|b: master|tag: v1.0|commit:eee55509f16e7715bdb43308bb55e8736da4e21e|m: start my build!|ENV[DEVICE_NAME]:iPhone 6S|ENV[DEVICE_UDID]:82667b4079914d4aabed9c216620da5dedab630a`
155157

156158

157159
## How to compile & run the server

bitriseapi/bitriseapi.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@ import (
1212
"time"
1313
)
1414

15+
// EnvironmentItem ...
16+
type EnvironmentItem struct {
17+
Name string `json:"mapped_to,omitempty"`
18+
Value string `json:"value,omitempty"`
19+
IsExpand bool `json:"is_expand,omitempty"`
20+
}
21+
1522
// BuildParamsModel ...
1623
type BuildParamsModel struct {
17-
CommitHash string `json:"commit_hash,omitempty"`
18-
CommitMessage string `json:"commit_message,omitempty"`
19-
Branch string `json:"branch,omitempty"`
20-
Tag string `json:"tag,omitempty"`
21-
PullRequestID *int `json:"pull_request_id,omitempty"`
22-
WorkflowID string `json:"workflow_id,omitempty"`
24+
CommitHash string `json:"commit_hash,omitempty"`
25+
CommitMessage string `json:"commit_message,omitempty"`
26+
Branch string `json:"branch,omitempty"`
27+
Tag string `json:"tag,omitempty"`
28+
PullRequestID *int `json:"pull_request_id,omitempty"`
29+
WorkflowID string `json:"workflow_id,omitempty"`
30+
Environments []EnvironmentItem `json:"environments,omitempty"`
2331
}
2432

2533
// TriggerAPIParamsModel ...

service/hook/slack/slack.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@ func getInputTextFromFormRequest(r *http.Request) (string, error) {
5050
return text, nil
5151
}
5252

53-
func collectParamsFromPipeSeparatedText(text string) map[string]string {
53+
func collectParamsFromPipeSeparatedText(text string) (map[string]string, []bitriseapi.EnvironmentItem) {
54+
parseFunc := func(c rune) bool {
55+
return c == '[' || c == ']'
56+
}
57+
5458
collectedParams := map[string]string{}
59+
environmentParams := []bitriseapi.EnvironmentItem{}
5560

5661
splits := strings.Split(text, "|")
5762
for _, aItm := range splits {
@@ -67,10 +72,21 @@ func collectParamsFromPipeSeparatedText(text string) map[string]string {
6772
}
6873
key := strings.TrimSpace(itmSplits[0])
6974
value := strings.TrimSpace(strings.Join(itmSplits[1:], ":"))
70-
collectedParams[key] = value
75+
subKeys := strings.FieldsFunc(key, parseFunc)
76+
77+
if len(subKeys) == 2 {
78+
subKeyParent := strings.ToLower(strings.TrimSpace(subKeys[0]))
79+
subKey := strings.TrimSpace(subKeys[1])
80+
if subKeyParent == "env" {
81+
environmentParams = append(environmentParams, bitriseapi.EnvironmentItem{Name: subKey, Value: value, IsExpand: false})
82+
}
83+
} else if len(subKeys) == 1 {
84+
collectedParams[key] = value
85+
}
86+
7187
}
7288

73-
return collectedParams
89+
return collectedParams, environmentParams
7490
}
7591

7692
func chooseFirstNonEmptyString(strs ...string) string {
@@ -85,7 +101,7 @@ func chooseFirstNonEmptyString(strs ...string) string {
85101
func transformOutgoingWebhookMessage(slackText string) hookCommon.TransformResultModel {
86102
cleanedUpText := strings.TrimSpace(slackText)
87103

88-
collectedParams := collectParamsFromPipeSeparatedText(cleanedUpText)
104+
collectedParams, environments := collectParamsFromPipeSeparatedText(cleanedUpText)
89105
//
90106
branch := chooseFirstNonEmptyString(collectedParams["branch"], collectedParams["b"])
91107
workflowID := chooseFirstNonEmptyString(collectedParams["workflow"], collectedParams["w"])
@@ -109,6 +125,7 @@ func transformOutgoingWebhookMessage(slackText string) hookCommon.TransformResul
109125
CommitHash: commitHash,
110126
Tag: tag,
111127
WorkflowID: workflowID,
128+
Environments: environments,
112129
},
113130
},
114131
},

service/hook/slack/slack_test.go

Lines changed: 101 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,54 +102,88 @@ func Test_collectParamsFromPipeSeparatedText(t *testing.T) {
102102
"key: the value |",
103103
}
104104
for _, aText := range texts {
105-
collectedParams := collectParamsFromPipeSeparatedText(aText)
105+
collectedParams, environmentParams := collectParamsFromPipeSeparatedText(aText)
106106
require.Equal(t, map[string]string{"key": "the value"}, collectedParams)
107+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
107108
}
108109
}
109110

110111
t.Log("Single item, includes :")
111112
{
112-
collectedParams := collectParamsFromPipeSeparatedText("key: the:value")
113+
collectedParams, environmentParams := collectParamsFromPipeSeparatedText("key: the:value")
113114
require.Equal(t, map[string]string{"key": "the:value"}, collectedParams)
114-
collectedParams = collectParamsFromPipeSeparatedText("key: the :value")
115+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
116+
collectedParams, environmentParams = collectParamsFromPipeSeparatedText("key: the :value")
115117
require.Equal(t, map[string]string{"key": "the :value"}, collectedParams)
116-
collectedParams = collectParamsFromPipeSeparatedText("key: the : value")
118+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
119+
collectedParams, environmentParams = collectParamsFromPipeSeparatedText("key: the : value")
117120
require.Equal(t, map[string]string{"key": "the : value"}, collectedParams)
118-
collectedParams = collectParamsFromPipeSeparatedText("key: the : value")
121+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
122+
collectedParams, environmentParams = collectParamsFromPipeSeparatedText("key: the : value")
119123
require.Equal(t, map[string]string{"key": "the : value"}, collectedParams)
120-
collectedParams = collectParamsFromPipeSeparatedText("key : the : value")
124+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
125+
collectedParams, environmentParams = collectParamsFromPipeSeparatedText("key : the : value")
121126
require.Equal(t, map[string]string{"key": "the : value"}, collectedParams)
127+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
122128
}
123129

124130
t.Log("Multiple items")
125131
{
126-
collectedParams := collectParamsFromPipeSeparatedText("key1: value 1 | key2 : value 2")
132+
collectedParams, environmentParams := collectParamsFromPipeSeparatedText("key1: value 1 | key2 : value 2")
127133
require.Equal(t, map[string]string{
128134
"key1": "value 1",
129135
"key2": "value 2",
130136
},
131137
collectedParams)
138+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
132139
}
133140

134141
t.Log("Multiple items - empty parts")
135142
{
136-
collectedParams := collectParamsFromPipeSeparatedText("|key1: value 1 | key2 : value 2|")
143+
collectedParams, environmentParams := collectParamsFromPipeSeparatedText("|key1: value 1 | key2 : value 2|")
137144
require.Equal(t, map[string]string{
138145
"key2": "value 2",
139146
"key1": "value 1",
140147
},
141148
collectedParams)
149+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
142150
}
143151

144152
t.Log("Multiple items - formatting test")
145153
{
146-
collectedParams := collectParamsFromPipeSeparatedText("|key1: value 1 | key2 : value 2 |key3:value 3")
154+
collectedParams, environmentParams := collectParamsFromPipeSeparatedText("|key1: value 1 | key2 : value 2 |key3:value 3")
147155
require.Equal(t, map[string]string{
148156
"key1": "value 1",
149157
"key3": "value 3",
150158
"key2": "value 2",
151159
},
152160
collectedParams)
161+
require.Equal(t, []bitriseapi.EnvironmentItem{}, environmentParams)
162+
}
163+
164+
t.Log("Nested items - parsing environments (only capture env)")
165+
{
166+
collectedParams, envParams := collectParamsFromPipeSeparatedText("key1: value1 |env[validNestedKey]: valueNested|ignoredKey[nestedKey1]: value 2 | ignoredKey [nestedKey2 ] : value 3 |key3:value 3")
167+
require.Equal(t, map[string]string{
168+
"key1": "value1",
169+
"key3": "value 3",
170+
},
171+
collectedParams)
172+
require.Equal(t, []bitriseapi.EnvironmentItem{
173+
bitriseapi.EnvironmentItem{Name: "validNestedKey", Value: "valueNested", IsExpand: false},
174+
},
175+
envParams)
176+
}
177+
178+
t.Log("Nested items - parsing environments (nested keys and keyed values, uppercase ENV support)")
179+
{
180+
collectedParams, envParams := collectParamsFromPipeSeparatedText("ENV[MY_KEY][something else]: my [value] here|ENV[MY_KEY]: my [value] here")
181+
require.Equal(t, map[string]string{},
182+
collectedParams)
183+
require.Equal(t, []bitriseapi.EnvironmentItem{
184+
bitriseapi.EnvironmentItem{Name: "MY_KEY", Value: "my [value] here", IsExpand: false},
185+
},
186+
envParams)
153187
}
154188
}
155189

@@ -164,7 +198,8 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
164198
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
165199
{
166200
BuildParams: bitriseapi.BuildParamsModel{
167-
Branch: "master",
201+
Branch: "master",
202+
Environments: []bitriseapi.EnvironmentItem{},
168203
},
169204
},
170205
}, hookTransformResult.TriggerAPIParams)
@@ -180,7 +215,8 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
180215
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
181216
{
182217
BuildParams: bitriseapi.BuildParamsModel{
183-
Branch: "master",
218+
Branch: "master",
219+
Environments: []bitriseapi.EnvironmentItem{},
184220
},
185221
},
186222
}, hookTransformResult.TriggerAPIParams)
@@ -196,7 +232,8 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
196232
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
197233
{
198234
BuildParams: bitriseapi.BuildParamsModel{
199-
Branch: "master",
235+
Branch: "master",
236+
Environments: []bitriseapi.EnvironmentItem{},
200237
},
201238
},
202239
}, hookTransformResult.TriggerAPIParams)
@@ -214,6 +251,7 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
214251
BuildParams: bitriseapi.BuildParamsModel{
215252
Branch: "master",
216253
CommitMessage: "this is the Commit Message param",
254+
Environments: []bitriseapi.EnvironmentItem{},
217255
},
218256
},
219257
}, hookTransformResult.TriggerAPIParams)
@@ -229,8 +267,9 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
229267
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
230268
{
231269
BuildParams: bitriseapi.BuildParamsModel{
232-
Branch: "master",
233-
CommitHash: "cmtHash123",
270+
Branch: "master",
271+
CommitHash: "cmtHash123",
272+
Environments: []bitriseapi.EnvironmentItem{},
234273
},
235274
},
236275
}, hookTransformResult.TriggerAPIParams)
@@ -246,8 +285,9 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
246285
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
247286
{
248287
BuildParams: bitriseapi.BuildParamsModel{
249-
Branch: "develop",
250-
Tag: "v1.0",
288+
Branch: "develop",
289+
Tag: "v1.0",
290+
Environments: []bitriseapi.EnvironmentItem{},
251291
},
252292
},
253293
}, hookTransformResult.TriggerAPIParams)
@@ -263,7 +303,47 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
263303
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
264304
{
265305
BuildParams: bitriseapi.BuildParamsModel{
266-
WorkflowID: "my-wf1",
306+
WorkflowID: "my-wf1",
307+
Environments: []bitriseapi.EnvironmentItem{},
308+
},
309+
},
310+
}, hookTransformResult.TriggerAPIParams)
311+
}
312+
313+
t.Log("Single environment parameter")
314+
{
315+
slackText := "branch: develop | env[DEVICE_NAME]: Rafael's iPhone"
316+
317+
hookTransformResult := transformOutgoingWebhookMessage(slackText)
318+
require.NoError(t, hookTransformResult.Error)
319+
require.False(t, hookTransformResult.ShouldSkip)
320+
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
321+
{
322+
BuildParams: bitriseapi.BuildParamsModel{
323+
Branch: "develop",
324+
Environments: []bitriseapi.EnvironmentItem{
325+
bitriseapi.EnvironmentItem{Name: "DEVICE_NAME", Value: "Rafael's iPhone", IsExpand: false},
326+
},
327+
},
328+
},
329+
}, hookTransformResult.TriggerAPIParams)
330+
}
331+
332+
t.Log("Multiple environment parameters, interleaved and spaced keys")
333+
{
334+
slackText := " | env[ DEVICE_NAME]: Rafael's iPhone|branch: develop |env[DEVICE_UDID ]:xxxxyyyyyzzzz"
335+
336+
hookTransformResult := transformOutgoingWebhookMessage(slackText)
337+
require.NoError(t, hookTransformResult.Error)
338+
require.False(t, hookTransformResult.ShouldSkip)
339+
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
340+
{
341+
BuildParams: bitriseapi.BuildParamsModel{
342+
Branch: "develop",
343+
Environments: []bitriseapi.EnvironmentItem{
344+
bitriseapi.EnvironmentItem{Name: "DEVICE_NAME", Value: "Rafael's iPhone", IsExpand: false},
345+
bitriseapi.EnvironmentItem{Name: "DEVICE_UDID", Value: "xxxxyyyyyzzzz", IsExpand: false},
346+
},
267347
},
268348
},
269349
}, hookTransformResult.TriggerAPIParams)
@@ -284,6 +364,7 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
284364
CommitHash: "cmtHash321",
285365
CommitMessage: "this is:my message",
286366
WorkflowID: "primary-wf",
367+
Environments: []bitriseapi.EnvironmentItem{},
287368
},
288369
},
289370
}, hookTransformResult.TriggerAPIParams)
@@ -304,6 +385,7 @@ func Test_transformOutgoingWebhookMessage(t *testing.T) {
304385
CommitHash: "cmtHash321",
305386
CommitMessage: "this is:my message",
306387
WorkflowID: "primary-wf",
388+
Environments: []bitriseapi.EnvironmentItem{},
307389
},
308390
},
309391
}, hookTransformResult.TriggerAPIParams)
@@ -341,7 +423,8 @@ func Test_HookProvider_TransformRequest(t *testing.T) {
341423
require.Equal(t, []bitriseapi.TriggerAPIParamsModel{
342424
{
343425
BuildParams: bitriseapi.BuildParamsModel{
344-
Branch: "master",
426+
Branch: "master",
427+
Environments: []bitriseapi.EnvironmentItem{},
345428
},
346429
},
347430
}, hookTransformResult.TriggerAPIParams)

0 commit comments

Comments
 (0)