• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

redhat-openshift-ecosystem / openshift-preflight / 18980802275

31 Oct 2025 05:48PM UTC coverage: 83.389% (-0.4%) from 83.766%
18980802275

Pull #1316

github

web-flow
Merge 12db9481a into 7edb889e2
Pull Request #1316: Add new flag to use non-zero exit code when checks fail

5 of 37 new or added lines in 3 files covered. (13.51%)

3 existing lines in 1 file now uncovered.

5005 of 6002 relevant lines covered (83.39%)

165.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.17
/internal/cli/cli.go
1
package cli
2

3
import (
4
        "bytes"
5
        "context"
6
        "errors"
7
        "fmt"
8
        "io"
9
        "os"
10
        "strings"
11

12
        "github.com/redhat-openshift-ecosystem/openshift-preflight/artifacts"
13
        "github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
14
        "github.com/redhat-openshift-ecosystem/openshift-preflight/internal/formatters"
15
        "github.com/redhat-openshift-ecosystem/openshift-preflight/internal/lib"
16
        "github.com/redhat-openshift-ecosystem/openshift-preflight/internal/log"
17

18
        "github.com/go-logr/logr"
19
)
20

21
type CheckConfig struct {
22
        IncludeJUnitResults bool
23
        SubmitResults       bool
24
}
25

26
type ChecksFailedError struct{}
27

NEW
28
func (e *ChecksFailedError) Error() string {
×
NEW
29
        return "one or more checks failed"
×
NEW
30
}
×
31

32
type ChecksErroredError struct{}
33

NEW
34
func (e *ChecksErroredError) Error() string {
×
NEW
35
        return "one or more checks encountered an error"
×
NEW
36
}
×
37

38
// RunPreflight executes checks, writes logs, results, and submits results if requested.
39
func RunPreflight(
40
        ctx context.Context,
41
        runChecks func(context.Context) (certification.Results, error),
42
        cfg CheckConfig,
43
        formatter formatters.ResponseFormatter,
44
        rw lib.ResultWriter,
45
        rs lib.ResultSubmitter,
46
) error {
6✔
47
        logger := logr.FromContextOrDiscard(ctx)
6✔
48

6✔
49
        // Configure artifact writing if not already configured. For CLI
6✔
50
        // executions, we default to writing to the filesystem.
6✔
51
        artifactsWriter := artifacts.WriterFromContext(ctx)
6✔
52
        var err error
6✔
53
        if artifactsWriter == nil {
7✔
54
                return errors.New("no artifact writer was configured")
1✔
55
        }
1✔
56
        // Fail early if we cannot write to the results path.
57
        resultsFilePath, err := artifactsWriter.WriteFile(ResultsFilenameWithExtension(formatter.FileExtension()), strings.NewReader(""))
5✔
58
        if err != nil {
5✔
59
                return err
×
60
        }
×
61

62
        resultsFile, err := rw.OpenFile(resultsFilePath)
5✔
63
        if err != nil {
5✔
64
                return err
×
65
        }
×
66

67
        defer resultsFile.Close()
5✔
68
        resultsOutputTarget := io.MultiWriter(os.Stdout, resultsFile)
5✔
69

5✔
70
        // Execute Checks.
5✔
71
        results, err := runChecks(ctx)
5✔
72
        if err != nil {
6✔
73
                return err
1✔
74
        }
1✔
75

76
        // Format and write the results.
77
        formattedResults, err := formatter.Format(ctx, results)
4✔
78
        if err != nil {
5✔
79
                return err
1✔
80
        }
1✔
81

82
        fmt.Fprintln(resultsOutputTarget, string(formattedResults))
3✔
83

3✔
84
        // Optionally write the JUnit results alongside the regular results.
3✔
85
        if cfg.IncludeJUnitResults {
4✔
86
                if err := writeJUnit(ctx, results); err != nil {
1✔
87
                        return err
×
88
                }
×
89
        }
90

91
        if cfg.SubmitResults {
5✔
92
                if err := rs.Submit(ctx); err != nil {
3✔
93
                        return err
1✔
94
                }
1✔
95
        }
96

97
        logger.Info(fmt.Sprintf("Preflight result: %s", convertPassedOverall(results.PassedOverall)))
2✔
98

2✔
99
        if len(results.Errors) > 0 {
2✔
NEW
100
                return &ChecksErroredError{}
×
NEW
101
        }
×
102

103
        if len(results.Failed) > 0 {
2✔
NEW
104
                return &ChecksFailedError{}
×
NEW
105
        }
×
106

107
        return nil
2✔
108
}
109

110
// writeJUnit will write JUnit results as an artifact using the ArtifactWriter configured
111
// in ctx.
112
func writeJUnit(ctx context.Context, results certification.Results) error {
2✔
113
        logger := logr.FromContextOrDiscard(ctx)
2✔
114

2✔
115
        junitformatter, err := formatters.NewByName("junitxml")
2✔
116
        if err != nil {
2✔
117
                return err
×
118
        }
×
119

120
        junitResults, err := junitformatter.Format(ctx, results)
2✔
121
        if err != nil {
2✔
122
                return err
×
123
        }
×
124

125
        if aw := artifacts.WriterFromContext(ctx); aw != nil {
4✔
126
                junitFilename, err := aw.WriteFile("results-junit.xml", bytes.NewReader((junitResults)))
2✔
127
                if err != nil {
2✔
128
                        return err
×
129
                }
×
130
                logger.V(log.TRC).Info("JUnitXML filename", "filename", junitFilename)
2✔
131
        }
132

133
        return nil
2✔
134
}
135

136
func convertPassedOverall(passedOverall bool) string {
4✔
137
        if passedOverall {
7✔
138
                return "PASSED"
3✔
139
        }
3✔
140

141
        return "FAILED"
1✔
142
}
143

144
func ResultsFilenameWithExtension(ext string) string {
5✔
145
        return strings.Join([]string{"results", ext}, ".")
5✔
146
}
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc