forked from
tangled.org/core
Monorepo for Tangled
1package workflow
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/stretchr/testify/assert"
8 "tangled.org/core/api/tangled"
9)
10
11var trigger = tangled.Pipeline_TriggerMetadata{
12 Kind: string(TriggerKindPush),
13 Push: &tangled.Pipeline_PushTriggerData{
14 Ref: "refs/heads/main",
15 OldSha: strings.Repeat("0", 40),
16 NewSha: strings.Repeat("f", 40),
17 },
18}
19
20var when = []Constraint{
21 {
22 Event: []string{"push"},
23 Branch: []string{"main"},
24 },
25}
26
27func TestCompileWorkflow_MatchingWorkflowWithSteps(t *testing.T) {
28 wf := Workflow{
29 Name: ".tangled/workflows/test.yml",
30 Engine: "nixery",
31 When: when,
32 CloneOpts: CloneOpts{}, // default true
33 }
34
35 c := Compiler{Trigger: trigger}
36 cp := c.Compile([]Workflow{wf})
37
38 assert.Len(t, cp.Workflows, 1)
39 assert.Equal(t, wf.Name, cp.Workflows[0].Name)
40 assert.False(t, cp.Workflows[0].Clone.Skip)
41 assert.False(t, c.Diagnostics.IsErr())
42}
43
44func TestCompileWorkflow_TriggerMismatch(t *testing.T) {
45 wf := Workflow{
46 Name: ".tangled/workflows/mismatch.yml",
47 Engine: "nixery",
48 When: []Constraint{
49 {
50 Event: []string{"push"},
51 Branch: []string{"master"}, // different branch
52 },
53 },
54 }
55
56 c := Compiler{Trigger: trigger}
57 cp := c.Compile([]Workflow{wf})
58
59 assert.Len(t, cp.Workflows, 0)
60 assert.Len(t, c.Diagnostics.Warnings, 1)
61 assert.Equal(t, WorkflowSkipped, c.Diagnostics.Warnings[0].Type)
62}
63
64func TestCompileWorkflow_CloneFalseWithShallowTrue(t *testing.T) {
65 wf := Workflow{
66 Name: ".tangled/workflows/clone_skip.yml",
67 Engine: "nixery",
68 When: when,
69 CloneOpts: CloneOpts{
70 Skip: true,
71 Depth: 1,
72 }, // false
73 }
74
75 c := Compiler{Trigger: trigger}
76 cp := c.Compile([]Workflow{wf})
77
78 assert.Len(t, cp.Workflows, 1)
79 assert.True(t, cp.Workflows[0].Clone.Skip)
80 assert.Len(t, c.Diagnostics.Warnings, 1)
81 assert.Equal(t, InvalidConfiguration, c.Diagnostics.Warnings[0].Type)
82}
83
84func TestCompileWorkflow_MissingEngine(t *testing.T) {
85 wf := Workflow{
86 Name: ".tangled/workflows/missing_engine.yml",
87 When: when,
88 Engine: "",
89 }
90
91 c := Compiler{Trigger: trigger}
92 cp := c.Compile([]Workflow{wf})
93
94 assert.Len(t, cp.Workflows, 0)
95 assert.Len(t, c.Diagnostics.Errors, 1)
96 assert.Equal(t, MissingEngine, c.Diagnostics.Errors[0].Error)
97}
98
99func TestCompileWorkflow_ChangedFilesMatchesPaths(t *testing.T) {
100 wf := Workflow{
101 Name: ".tangled/workflows/test.yml",
102 Engine: "nixery",
103 When: []Constraint{
104 {
105 Event: []string{"push"},
106 Branch: []string{"main"},
107 Paths: []string{"src/**"},
108 },
109 },
110 }
111
112 c := Compiler{
113 Trigger: trigger,
114 ChangedFiles: []string{"src/main.go", "src/util.go"},
115 }
116 cp := c.Compile([]Workflow{wf})
117
118 assert.Len(t, cp.Workflows, 1)
119 assert.Equal(t, wf.Name, cp.Workflows[0].Name)
120 assert.False(t, c.Diagnostics.IsErr())
121}
122
123func TestCompileWorkflow_ChangedFilesNoMatch(t *testing.T) {
124 wf := Workflow{
125 Name: ".tangled/workflows/test.yml",
126 Engine: "nixery",
127 When: []Constraint{
128 {
129 Event: []string{"push"},
130 Branch: []string{"main"},
131 Paths: []string{"src/**"},
132 },
133 },
134 }
135
136 c := Compiler{
137 Trigger: trigger,
138 ChangedFiles: []string{"docs/guide.md", "README.md"},
139 }
140 cp := c.Compile([]Workflow{wf})
141
142 assert.Len(t, cp.Workflows, 0)
143 assert.Len(t, c.Diagnostics.Warnings, 1)
144 assert.Equal(t, WorkflowSkipped, c.Diagnostics.Warnings[0].Type)
145}
146
147func TestCompileWorkflow_NoPaths_ChangedFilesIgnored(t *testing.T) {
148 wf := Workflow{
149 Name: ".tangled/workflows/test.yml",
150 Engine: "nixery",
151 When: when, // no Paths constraint
152 }
153
154 c := Compiler{
155 Trigger: trigger,
156 ChangedFiles: []string{"docs/guide.md"},
157 }
158 cp := c.Compile([]Workflow{wf})
159
160 assert.Len(t, cp.Workflows, 1)
161 assert.False(t, c.Diagnostics.IsErr())
162}
163
164func TestCompileWorkflow_MultipleBranchAndTag(t *testing.T) {
165 wf := Workflow{
166 Name: ".tangled/workflows/branch_and_tag.yml",
167 When: []Constraint{
168 {
169 Event: []string{"push"},
170 Branch: []string{"main", "develop"},
171 Tag: []string{"v*"},
172 },
173 },
174 Engine: "nixery",
175 }
176
177 tests := []struct {
178 name string
179 trigger tangled.Pipeline_TriggerMetadata
180 shouldMatch bool
181 expectedCount int
182 }{
183 {
184 name: "matches main branch",
185 trigger: tangled.Pipeline_TriggerMetadata{
186 Kind: string(TriggerKindPush),
187 Push: &tangled.Pipeline_PushTriggerData{
188 Ref: "refs/heads/main",
189 OldSha: strings.Repeat("0", 40),
190 NewSha: strings.Repeat("f", 40),
191 },
192 },
193 shouldMatch: true,
194 expectedCount: 1,
195 },
196 {
197 name: "matches develop branch",
198 trigger: tangled.Pipeline_TriggerMetadata{
199 Kind: string(TriggerKindPush),
200 Push: &tangled.Pipeline_PushTriggerData{
201 Ref: "refs/heads/develop",
202 OldSha: strings.Repeat("0", 40),
203 NewSha: strings.Repeat("f", 40),
204 },
205 },
206 shouldMatch: true,
207 expectedCount: 1,
208 },
209 {
210 name: "matches v* tag pattern",
211 trigger: tangled.Pipeline_TriggerMetadata{
212 Kind: string(TriggerKindPush),
213 Push: &tangled.Pipeline_PushTriggerData{
214 Ref: "refs/tags/v1.0.0",
215 OldSha: strings.Repeat("0", 40),
216 NewSha: strings.Repeat("f", 40),
217 },
218 },
219 shouldMatch: true,
220 expectedCount: 1,
221 },
222 {
223 name: "matches v* tag pattern with different version",
224 trigger: tangled.Pipeline_TriggerMetadata{
225 Kind: string(TriggerKindPush),
226 Push: &tangled.Pipeline_PushTriggerData{
227 Ref: "refs/tags/v2.5.3",
228 OldSha: strings.Repeat("0", 40),
229 NewSha: strings.Repeat("f", 40),
230 },
231 },
232 shouldMatch: true,
233 expectedCount: 1,
234 },
235 {
236 name: "does not match master branch",
237 trigger: tangled.Pipeline_TriggerMetadata{
238 Kind: string(TriggerKindPush),
239 Push: &tangled.Pipeline_PushTriggerData{
240 Ref: "refs/heads/master",
241 OldSha: strings.Repeat("0", 40),
242 NewSha: strings.Repeat("f", 40),
243 },
244 },
245 shouldMatch: false,
246 expectedCount: 0,
247 },
248 {
249 name: "does not match non-v tag",
250 trigger: tangled.Pipeline_TriggerMetadata{
251 Kind: string(TriggerKindPush),
252 Push: &tangled.Pipeline_PushTriggerData{
253 Ref: "refs/tags/release-1.0",
254 OldSha: strings.Repeat("0", 40),
255 NewSha: strings.Repeat("f", 40),
256 },
257 },
258 shouldMatch: false,
259 expectedCount: 0,
260 },
261 {
262 name: "does not match feature branch",
263 trigger: tangled.Pipeline_TriggerMetadata{
264 Kind: string(TriggerKindPush),
265 Push: &tangled.Pipeline_PushTriggerData{
266 Ref: "refs/heads/feature/new-feature",
267 OldSha: strings.Repeat("0", 40),
268 NewSha: strings.Repeat("f", 40),
269 },
270 },
271 shouldMatch: false,
272 expectedCount: 0,
273 },
274 }
275
276 for _, tt := range tests {
277 t.Run(tt.name, func(t *testing.T) {
278 c := Compiler{Trigger: tt.trigger}
279 cp := c.Compile([]Workflow{wf})
280
281 assert.Len(t, cp.Workflows, tt.expectedCount)
282 if tt.shouldMatch {
283 assert.Equal(t, wf.Name, cp.Workflows[0].Name)
284 }
285 })
286 }
287}