Skip to content

Commit 50e7e36

Browse files
committed
Support steps[*].force: steps.<key>.force: for running step forcefully
1 parent b0c0192 commit 50e7e36

File tree

7 files changed

+70
-4
lines changed

7 files changed

+70
-4
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,19 @@ The step marked `defer` behaves as follows.
733733
- If there are multiple steps marked with `defer`, they are run in LIFO order.
734734
- Also, the included steps are added to run sequence of the parent runbook's deferred steps.
735735

736+
### `steps[*].force:` `steps.<key>.force:`
737+
738+
Force step to run.
739+
740+
```yaml
741+
steps:
742+
[...]
743+
-
744+
force: true
745+
dump: previous.res.body
746+
[...]
747+
```
748+
736749
## Variables to be stored
737750

738751
runn can use variables and functions when running step.

force.go

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package runn
2+
3+
const forceSectionKey = "force"

force_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package runn
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
func TestForceRun(t *testing.T) {
9+
tests := []struct {
10+
book string
11+
}{
12+
{"testdata/book/force.yml"},
13+
{"testdata/book/force_step.yml"},
14+
}
15+
for _, tt := range tests {
16+
t.Run(tt.book, func(t *testing.T) {
17+
ctx := context.Background()
18+
o, err := New(Book(tt.book))
19+
if err != nil {
20+
t.Fatal(err)
21+
}
22+
if err := o.Run(ctx); err == nil {
23+
t.Fatal("expected error")
24+
}
25+
for _, sr := range o.Result().StepResults {
26+
if sr.Skipped {
27+
t.Errorf("got %v, want %v", sr.Skipped, false)
28+
}
29+
}
30+
})
31+
}
32+
}

operator.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,14 @@ func (op *operator) appendStep(idx int, key string, s map[string]any) error {
706706
}
707707
delete(s, deferSectionKey)
708708
}
709+
// force section
710+
if v, ok := s[forceSectionKey]; ok {
711+
st.force, ok = v.(bool)
712+
if !ok {
713+
return fmt.Errorf("invalid force: %v", v)
714+
}
715+
delete(s, forceSectionKey)
716+
}
709717
// loop section
710718
if v, ok := s[loopSectionKey]; ok {
711719
r, err := newLoop(v)
@@ -1222,7 +1230,7 @@ func (op *operator) runInternal(ctx context.Context) (rerr error) {
12221230
op.record(s.idx, nil)
12231231
continue
12241232
}
1225-
if failed && !force {
1233+
if failed && !force && !s.force {
12261234
s.setResult(errStepSkipped)
12271235
op.recordNotRun(s.idx)
12281236
if err := op.recordResult(s.idx, resultSkipped); err != nil {

step.go

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type step struct {
1212
desc string
1313
ifCond string
1414
deferred bool // deferred step runs after all other steps like defer in Go
15+
force bool // forceed run per step
1516
loop *Loop
1617
// loopIndex - Index of the loop is dynamically recorded at runtime
1718
loopIndex *int

testdata/book/force.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ desc: Always force run
22
force: true
33
steps:
44
-
5-
test: 'true'
5+
test: true
66
-
7-
test: 'false'
7+
test: false
88
-
9-
test: 'true'
9+
test: true

testdata/book/force_step.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
desc: Forced run per step
2+
steps:
3+
-
4+
test: true
5+
-
6+
test: false
7+
-
8+
test: true
9+
force: true

0 commit comments

Comments
 (0)