Skip to content

Commit 49b7a7c

Browse files
committed
feat(error-detection): add multiple pattern support
Add support for configuring multiple error detection regex patterns at both global (ConfigMap) and repository (CR) levels. This allows users to match different error formats from various linters and tools in a single pipeline. Global Configuration (ConfigMap): - Changed error-detection-simple-regexp to support arrays - Supports 3 formats: single pattern (backward compatible), multi-line YAML, and JSON array Repository CR: - Added ErrorDetectionSettings with patterns array and max_number_of_lines - Patterns are additive with global patterns - Per-repository max_number_of_lines override Jira: https://issues.redhat.com/browse/SRVKP-7237 Signed-off-by: Akshay Pant <[email protected]> Assisted-by: Cursor <[email protected]>
1 parent 2386222 commit 49b7a7c

File tree

10 files changed

+451
-58
lines changed

10 files changed

+451
-58
lines changed

config/300-repositories.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,34 @@ spec:
446446
- roles
447447
- secret_ref
448448
type: object
449+
error_detection:
450+
description: |-
451+
ErrorDetection configures error detection for this repository. Error detection scans
452+
container logs for error patterns and creates annotations (currently GitHub-only).
453+
The global error-detection-from-container-logs setting must be enabled for this to work.
454+
If not specified, uses only global error detection pattern.
455+
properties:
456+
max_number_of_lines:
457+
description: |-
458+
MaxNumberOfLines specifies how many lines to scan from the end of container logs
459+
when looking for errors. This overrides the global error-detection-max-number-of-lines setting.
460+
Higher values may increase memory usage. Use -1 for unlimited.
461+
If not specified, uses the global setting (default: 50).
462+
type: integer
463+
patterns:
464+
description: |-
465+
Patterns is an array of regular expressions used to detect errors in container logs.
466+
Each pattern must use named groups to capture: filename, line, and error.
467+
The column group is optional. Example pattern:
468+
^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)
469+
470+
Multiple patterns can be specified to match different error formats.
471+
Repository-specific patterns are tried first, followed by global patterns.
472+
If not specified or empty, only the global error-detection-simple-regexp patterns are used.
473+
items:
474+
type: string
475+
type: array
476+
type: object
449477
github:
450478
properties:
451479
comment_strategy:

config/302-pac-configmap.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,22 @@ data:
101101
# memory usage. Use -1 for unlimited lines.
102102
error-detection-max-number-of-lines: "50"
103103

104-
# The default regexp used when we use the simple error detection
104+
# The default regexp(s) used for simple error detection.
105+
# Supports multiple formats for backward compatibility:
106+
#
107+
# 1. Single pattern (backward compatible):
108+
# error-detection-simple-regexp: '^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)'
109+
#
110+
# 2. YAML list format (multiple patterns, one per line):
111+
# error-detection-simple-regexp: |-
112+
# ^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)
113+
# ^ERROR: (?P<filename>[^ ]+) line (?P<line>[0-9]+): (?P<error>.*)
114+
# ^\[(?P<filename>[^\]]+)\]:(?P<line>[0-9]+) - (?P<error>.*)
115+
#
116+
# 3. JSON array format:
117+
# error-detection-simple-regexp: '["^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)", "^ERROR:.*"]'
118+
#
119+
# Each pattern must include named groups: filename, line, and error (column is optional)
105120
error-detection-simple-regexp: |-
106121
^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)
107122

docs/content/docs/guide/repositorycrd.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,104 @@ spec:
185185
comment_strategy: "disable_all"
186186
```
187187

188+
## Error Detection
189+
190+
Error detection scans container logs for error patterns and creates inline
191+
annotations on Pull Requests. This feature is currently **only supported for
192+
GitHub Apps**.
193+
194+
By default, error detection uses the global pattern configured in the
195+
`pipelines-as-code` ConfigMap via the `error-detection-simple-regexp` setting.
196+
However, you can customize error detection patterns on a per-repository basis
197+
using the Repository CR.
198+
199+
### Configuring Error Detection Patterns
200+
201+
You can specify multiple regex patterns to detect different error formats in
202+
your repository:
203+
204+
```yaml
205+
apiVersion: "pipelinesascode.tekton.dev/v1alpha1"
206+
kind: Repository
207+
metadata:
208+
name: my-repo
209+
spec:
210+
url: "https://github.com/owner/repo"
211+
settings:
212+
error_detection:
213+
patterns:
214+
- "^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)"
215+
- "^ERROR: (?P<filename>[^ ]+) line (?P<line>[0-9]+): (?P<error>.*)"
216+
max_number_of_lines: 100
217+
```
218+
219+
**Pattern Requirements:**
220+
221+
Each pattern must use [named groups](https://www.regular-expressions.info/named.html) to capture:
222+
223+
- `filename`: The file path where the error occurred
224+
- `line`: The line number
225+
- `error`: The error message
226+
- `column`: (optional) The column number
227+
228+
**Configuration Options:**
229+
230+
- `patterns`: Array of regex patterns. Repository-specific patterns are tried
231+
first, followed by global patterns. If not specified or empty, only the
232+
global patterns are used. **Note:** Providing an empty array does not disable
233+
error detection; it falls back to using only the global patterns defined in
234+
the `pipelines-as-code` ConfigMap.
235+
- `max_number_of_lines`: Number of log lines to scan (overrides global
236+
setting). Default is 50. Use -1 for unlimited.
237+
238+
{{< hint info >}}
239+
**Global Override:** The global `error-detection-from-container-logs` setting
240+
must be enabled (default: `true`) for error detection to work. If disabled
241+
globally, repository-level settings cannot override it.
242+
{{< /hint >}}
243+
244+
### Examples
245+
246+
**Multiple error formats:**
247+
248+
```yaml
249+
spec:
250+
settings:
251+
error_detection:
252+
patterns:
253+
# Standard format (make, gcc, eslint, etc.)
254+
- "^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)"
255+
# Python traceback format
256+
- 'File "(?P<filename>[^"]+)", line (?P<line>[0-9]+).*\n.*(?P<error>.*)'
257+
# Custom CI format
258+
- "^\\[(?P<filename>[^\\]]+)\\]:(?P<line>[0-9]+) - (?P<error>.*)"
259+
max_number_of_lines: 200
260+
```
261+
262+
**Using only global patterns:**
263+
264+
If you want to use only the global patterns defined in the `pipelines-as-code`
265+
ConfigMap, simply omit the `error_detection` field or provide an empty
266+
`patterns` array:
267+
268+
```yaml
269+
spec:
270+
settings:
271+
error_detection:
272+
patterns: [] # Uses only global patterns
273+
max_number_of_lines: 100 # Can still override line count
274+
```
275+
276+
{{< hint info >}}
277+
**Pattern Priority:** When repository-specific patterns are defined, they are
278+
tried first for each log line. If no repository pattern matches, the global
279+
patterns are then tried. This allows you to add repository-specific patterns
280+
while still benefiting from the global patterns as a fallback.
281+
{{< /hint >}}
282+
283+
For more information about error detection and log snippets, see the
284+
[Status documentation]({{< relref "/docs/guide/statuses.md" >}}).
285+
188286
## Concurrency
189287

190288
`concurrency_limit` allows you to define the maximum number of PipelineRuns running at any time for a Repository.

docs/content/docs/guide/statuses.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ You can customize the regular expression used for detecting errors with the
8484
`error-detection-simple-regexp` setting. The regular expression uses [named
8585
groups](https://www.regular-expressions.info/named.html) to provide flexibility
8686
in specifying the matching criteria. The necessary groups for matching are
87-
filename, line, and error (the column group is not used). The default regular
88-
expression is defined in the configuration map.
87+
filename, line, and error (the column group is optional). The default regular
88+
expression is defined in the configuration map. Multiple patterns are supported
89+
using multi-line YAML or JSON array format, allowing you to detect errors from
90+
different tools with various output formats.
8991

9092
By default, Pipelines-as-Code searches for errors in only the last 50 lines of
9193
the container logs. However, you can increase this limit by setting the
@@ -94,6 +96,14 @@ system will search through all available lines for errors. Keep in mind that
9496
increasing this maximum number of lines may increase the memory usage of the
9597
watcher.
9698

99+
{{< hint info >}}
100+
**Repository-level configuration:** You can also configure error detection
101+
patterns on a per-repository basis using the Repository CR. This allows you to
102+
define multiple patterns and customize settings for individual repositories.
103+
See the [Repository CR documentation]({{< relref "/docs/guide/repositorycrd.md#error-detection" >}})
104+
for more details.
105+
{{< /hint >}}
106+
97107
![annotations](/images/github-annotation-error-failure-detection.png)
98108

99109
## Namespace Event stream

docs/content/docs/install/operator_installation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ spec:
4545
hub-url: 'https://artifacthub.io'
4646
hub-catalog-type: 'artifacthub'
4747
error-detection-max-number-of-lines: '50'
48+
# Single pattern example. For multiple patterns, use multi-line format (see settings docs)
4849
error-detection-simple-regexp: >-
4950
^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+):([
5051
]*)?(?P<error>.*)

docs/content/docs/install/settings.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,39 @@ A few settings are available to configure this feature:
291291
By default the error detection only support a simple output, the way GCC or
292292
Make will output error, which is supported by most linters and command line tools.
293293

294+
**Multiple Patterns Support:** You can now specify multiple regex patterns to
295+
match different error formats. The setting supports three formats:
296+
297+
1. **Single pattern** (backward compatible):
298+
299+
```yaml
300+
error-detection-simple-regexp: '^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)'
301+
```
302+
303+
2. **Multi-line YAML** (recommended for multiple patterns):
304+
305+
```yaml
306+
error-detection-simple-regexp: |-
307+
^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)
308+
^ERROR: (?P<filename>[^ ]+) line (?P<line>[0-9]+): (?P<error>.*)
309+
^\[(?P<filename>[^\]]+)\]:(?P<line>[0-9]+) - (?P<error>.*)
310+
```
311+
312+
3. **JSON array format**:
313+
314+
```yaml
315+
error-detection-simple-regexp: '["^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)", "^ERROR:.*"]'
316+
```
317+
318+
Each pattern will be tried in order until one matches. This allows you to detect
319+
errors from multiple tools with different output formats.
320+
321+
**Pattern Requirements:** Each pattern must use regexp named groups to capture:
322+
* `(?P<filename>...)` - The file path where the error occurred
323+
* `(?P<line>...)` - The line number
324+
* `(?P<error>...)` - The error message
325+
* `(?P<column>...)` - Column number (optional)
326+
294327
An example of an error that is supported is :
295328

296329
```console

pkg/apis/pipelinesascode/v1alpha1/types.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ type Settings struct {
164164
// AIAnalysis contains AI/LLM analysis configuration for automated CI/CD pipeline analysis.
165165
// +optional
166166
AIAnalysis *AIAnalysisConfig `json:"ai,omitempty"`
167+
168+
// ErrorDetection configures error detection for this repository. Error detection scans
169+
// container logs for error patterns and creates annotations (currently GitHub-only).
170+
// The global error-detection-from-container-logs setting must be enabled for this to work.
171+
// If not specified, uses only global error detection pattern.
172+
// +optional
173+
ErrorDetection *ErrorDetectionSettings `json:"error_detection,omitempty"`
167174
}
168175

169176
type GitlabSettings struct {
@@ -184,6 +191,28 @@ type GithubSettings struct {
184191
CommentStrategy string `json:"comment_strategy,omitempty"`
185192
}
186193

194+
// ErrorDetectionSettings configures how errors are detected from container logs and
195+
// exposed as annotations on Pull Requests. Currently only supported for GitHub Apps.
196+
type ErrorDetectionSettings struct {
197+
// Patterns is an array of regular expressions used to detect errors in container logs.
198+
// Each pattern must use named groups to capture: filename, line, and error.
199+
// The column group is optional. Example pattern:
200+
// ^(?P<filename>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+)?([ ]*)?(?P<error>.*)
201+
//
202+
// Multiple patterns can be specified to match different error formats.
203+
// Repository-specific patterns are tried first, followed by global patterns.
204+
// If not specified or empty, only the global error-detection-simple-regexp patterns are used.
205+
// +optional
206+
Patterns []string `json:"patterns,omitempty"`
207+
208+
// MaxNumberOfLines specifies how many lines to scan from the end of container logs
209+
// when looking for errors. This overrides the global error-detection-max-number-of-lines setting.
210+
// Higher values may increase memory usage. Use -1 for unlimited.
211+
// If not specified, uses the global setting (default: 50).
212+
// +optional
213+
MaxNumberOfLines *int `json:"max_number_of_lines,omitempty"`
214+
}
215+
187216
func (s *Settings) Merge(newSettings *Settings) {
188217
if newSettings.PipelineRunProvenance != "" && s.PipelineRunProvenance == "" {
189218
s.PipelineRunProvenance = newSettings.PipelineRunProvenance
@@ -197,6 +226,9 @@ func (s *Settings) Merge(newSettings *Settings) {
197226
if newSettings.AIAnalysis != nil && s.AIAnalysis == nil {
198227
s.AIAnalysis = newSettings.AIAnalysis
199228
}
229+
if newSettings.ErrorDetection != nil && s.ErrorDetection == nil {
230+
s.ErrorDetection = newSettings.ErrorDetection
231+
}
200232
}
201233

202234
type Policy struct {

0 commit comments

Comments
 (0)