<freeStyleBuild _class='hudson.model.FreeStyleBuild'><action _class='hudson.model.CauseAction'><cause _class='com.cloudbees.jenkins.GitHubPushCause'><shortDescription>Started by GitHub push by ti-chi-bot[bot]</shortDescription></cause><cause _class='com.cloudbees.jenkins.GitHubPushCause'><shortDescription>Started by GitHub push by ti-chi-bot[bot]</shortDescription></cause></action><action></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>36888</buildableDurationMillis><buildableTimeMillis>36888</buildableTimeMillis><buildingDurationMillis>46617</buildingDurationMillis><executingTimeMillis>46617</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>8211</waitingDurationMillis><waitingTimeMillis>8211</waitingTimeMillis></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><originmain _class='hudson.plugins.git.util.Build'><buildNumber>1055</buildNumber><marked><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><branch><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><name>origin/main</name></branch></marked><revision><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><branch><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><name>origin/main</name></branch></revision></originmain></buildsByBranchName><lastBuiltRevision><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><branch><SHA1>f9dacd257266ea0b88227be9429b2d833b5b1b70</SHA1><name>origin/main</name></branch></lastBuiltRevision><remoteUrl>https://github.com/PingCAP-QE/ci.git</remoteUrl><scmName></scmName></action><action></action><action></action><action></action><action></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#1055</displayName><duration>46617</duration><estimatedDuration>86474</estimatedDuration><fullDisplayName>seed #1055</fullDisplayName><id>1055</id><inProgress>false</inProgress><keepLog>false</keepLog><number>1055</number><queueId>2137544</queueId><result>SUCCESS</result><timestamp>1760067427609</timestamp><url>https://do.pingcap.net/jenkins/view/all/job/seed/1055/</url><builtOn>default-l1z17</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>.gitignore</affectedPath><affectedPath>tools/error-log-review/README.md</affectedPath><affectedPath>tools/error-log-review/config.yaml.example</affectedPath><affectedPath>tools/error-log-review/config.go</affectedPath><affectedPath>configs/error-log-review/config.yaml</affectedPath><affectedPath>tools/error-log-review/matcher_test.go</affectedPath><affectedPath>tools/error-log-review/matcher.go</affectedPath><commitId>f9dacd257266ea0b88227be9429b2d833b5b1b70</commitId><timestamp>1760067378000</timestamp><author><absoluteUrl>https://do.pingcap.net/jenkins/user/noreply</absoluteUrl><fullName>noreply</fullName></author><authorEmail>noreply@github.com</authorEmail><comment>feat: Add exclusion patterns support to error-log-review CI tool (#3787)

## 🎯 Overview

This PR adds support for exclusion patterns in the error-log-review CI
tool, allowing test code and other non-production paths to be ignored by
specific rules or globally per repository.

## 🐛 Problem

The error-log-review CI was flagging log statements in test files,
creating noise and false positives. For example, in [this PR
run](https://prow.tidb.net/view/gs/prow-tidb-logs/pr-logs/pull/pingcap_ticdc/2337/pull-error-log-review/1976460951846653952):

```
tests/integration_tests/ddl_wait/test.go [string_literals]: log.Fatalf("insert value failed:, host:%s, port:%s, k:%d, i:%d, val:%d, num:%d, err: %+v", host, port, k, i, val, num, err)
tests/integration_tests/ddl_wait/test.go [variables_and_functions]: log.Fatalf("insert value failed:, host:%s, port:%s, k:%d, i:%d, val:%d, num:%d, err: %+v", host, port, k, i, val, num, err)
```

Test code often uses different logging patterns and doesn't require the
same scrutiny as production code.

## ✨ Solution

Implemented a two-level exclusion system using glob patterns:

### 1. Pattern-Specific Excludes
Apply exclusions to individual patterns only:

```yaml
patterns:
  - name: "string_literals"
    regex: '...'
    excludes:
      - "tests/**"           # Exclude all files under tests/
      - "*_test.go"          # Exclude all Go test files
      - "examples/**"        # Exclude examples directory
```

### 2. Repository-Level Excludes
Apply exclusions to all patterns in a repository:

```yaml
repositories:
  - name: "owner/repo"
    excludes:
      - "vendor/**"
      - "third_party/**"
    patterns:
      - name: "..."
```

### Glob Pattern Support
- `*` - matches any sequence of characters in a filename (e.g.,
`*_test.go`)
- `**` - matches directories recursively (e.g., `tests/**` matches all
files under tests/ and subdirectories)
- `?` - matches any single character

## 📝 Changes

### Code Changes
- **`config.go`**: Added `Excludes []string` field to both `Pattern` and
`Repository` structs
- **`config.go`**: Implemented `matchesAnyPattern()` function for glob
pattern matching
- **`matcher.go`**: Updated `CheckPRDiff()` to check exclusions before
applying pattern matching

### Configuration
- **`configs/error-log-review/config.yaml`**: Added `excludes:
["tests/**"]` to `pingcap/ticdc` patterns to fix the reported issue
- **`config.yaml.example`**: Added comprehensive documentation and
examples

### Documentation
- **`README.md`**: Added "Exclusion Patterns" section with detailed
examples and glob syntax reference

### Testing
- **`matcher_test.go`**: Created comprehensive test suite with:
  - `TestMatchesAnyPattern` - Tests glob pattern matching (8 test cases)
  - `TestCheckPRDiffWithExclusions` - Tests end-to-end exclusion logic
  - `TestTiCDCExclusionScenario` - Tests the specific issue scenario
  - All tests passing ✅

## 🔍 Example Usage

```yaml
repositories:
  - name: "pingcap/ticdc"
    patterns:
      - name: "string_literals"
        description: "Pattern for string literals"
        regex: '...'
        excludes:
          - "tests/**"      # Now test files won't trigger this rule
    approvers:
      - "flowbehappy"
```

## ✅ Verification

- All tests pass (3 test suites, 10 test cases)
- Build succeeds
- Code formatted with `go fmt`
- No `go vet` issues
- Configuration validated with YAML parser

## 🎉 Impact

- **Immediate**: Fixes the false positives for `pingcap/ticdc` test
files
- **Future**: Any repository can now configure exclusions without code
changes
- **Flexible**: Supports both global and pattern-specific exclusions
- **Backward Compatible**: Existing configurations continue to work
unchanged

Fixes #[issue_number]

&lt;!-- START COPILOT CODING AGENT SUFFIX --&gt;



&lt;details&gt;

&lt;summary&gt;Original prompt&lt;/summary&gt;

&gt; 
&gt; ----
&gt; 
&gt; *This section details on the original issue you should resolve*
&gt; 
&gt; &lt;issue_title&gt;Support exclusion patterns in pull-error-log-review CI
(exclude test code)&lt;/issue_title&gt;
&gt; &lt;issue_description&gt;## 🪧 Summary
&gt; Add support for exclusion patterns in the error-log review CI job
(pull-error-log-review) so test code and other non-production paths can
be ignored by specific rules.
&gt; 
&gt; ## 🙋 Problem
&gt; Currently, the job flags issues in test files, which creates noise and
false positives. Example from a recent run:
&gt; - tests/integration_tests/ddl_wait/test.go [string_literals]:
log.Fatalf("insert value failed:, host:%s, port:%s, k:%d, i:%d, val:%d,
num:%d, err: %+v", host, port, k, i, val, num, err)
&gt; - tests/integration_tests/ddl_wait/test.go [variables_and_functions]:
log.Fatalf("insert value failed:, host:%s, port:%s, k:%d, i:%d, val:%d,
num:%d, err: %+v", host, port, k, i, val, num, err)
&gt; 
&gt; ## Example CI run
&gt;
https://prow.tidb.net/view/gs/prow-tidb-logs/pr-logs/pull/pingcap_ticdc/2337/pull-error-log-review/1976460951846653952
&gt; 
&gt; ## 📄 Proposal
&gt; - Add configurable exclusion patterns (e.g., glob paths) so we can
exclude directories like tests/** by default, or on a per-repo basis.
&gt; - Consider supporting both:
&gt;   - Global excludes (apply to all rules), and
&gt; - Rule-specific excludes (e.g., exclude tests/** only for
string_literals and variables_and_functions).
&gt; - Allow repo-level configuration (e.g., a YAML config) to declare
excludes without changing CI code for each repo.
&gt; 
&gt; ## 🧐 Acceptance criteria
&gt; - The job supports path-based exclude patterns.
&gt; - Can define global and rule-specific excludes.
&gt; - Document how to configure excludes for a repository.
&gt; - Test files such as tests/integration_tests/** are not flagged by the
above rules once configured.
&gt; &lt;/issue_description&gt;
&gt; 
&gt; ## Comments on the Issue (you are @copilot in this section)
&gt; 
&gt; &lt;comments&gt;
&gt; &lt;comment_new&gt;&lt;author&gt;@wuhuizuo&lt;/author&gt;&lt;body&gt;
&gt; /assign @lybcodes &lt;/body&gt;&lt;/comment_new&gt;
&gt; &lt;comment_new&gt;&lt;author&gt;@wuhuizuo&lt;/author&gt;&lt;body&gt;
&gt; The CI tool information:
&gt; - code path: tools/error-log-review
&gt; - config path:
configs/error-log-review/config.yaml&lt;/body&gt;&lt;/comment_new&gt;
&gt; &lt;/comments&gt;
&gt; 


&lt;/details&gt;

Fixes PingCAP-QE/ci#3786

&lt;!-- START COPILOT CODING AGENT TIPS --&gt;
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] &lt;198982749+Copilot@users.noreply.github.com&gt;
Co-authored-by: wuhuizuo &lt;2574558+wuhuizuo@users.noreply.github.com&gt;
Co-authored-by: pre-commit-ci[bot] &lt;66853113+pre-commit-ci[bot]@users.noreply.github.com&gt;
</comment><date>2025-10-10 03:36:18 +0000</date><id>f9dacd257266ea0b88227be9429b2d833b5b1b70</id><msg>feat: Add exclusion patterns support to error-log-review CI tool (#3787)</msg><path><editType>edit</editType><file>.gitignore</file></path><path><editType>edit</editType><file>tools/error-log-review/README.md</file></path><path><editType>edit</editType><file>configs/error-log-review/config.yaml</file></path><path><editType>edit</editType><file>tools/error-log-review/config.yaml.example</file></path><path><editType>add</editType><file>tools/error-log-review/matcher_test.go</file></path><path><editType>edit</editType><file>tools/error-log-review/config.go</file></path><path><editType>edit</editType><file>tools/error-log-review/matcher.go</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://do.pingcap.net/jenkins/user/noreply</absoluteUrl><fullName>noreply</fullName></culprit></freeStyleBuild>