"Support regular expressions in rules:changes/exists"
### Problem to solve Users need the ability to run a job **only** when at least one file was changed **outside** of specific paths. Currently, `rules:changes` and `rules:exists` use [glob patterns](https://ruby-doc.org/3.2.3/File.html#method-c-fnmatch) which don't support negation or full regular expression matching. **Common use cases:** - Skip build/test jobs when **only** documentation files (`.md`) are changed - In monorepos: skip project-specific jobs when changes are **only** in unrelated directories - Run full pipeline when both relevant code AND irrelevant files (docs, configs) change together ### Proposal Add support for regular expressions in `rules:changes` and `rules:exists`: ```yaml job1: script: - exit 0 rules: - changes: regexp: "^(?!docs/).*$" # Match files NOT in docs/ job2: script: - exit 0 rules: - exists: regexp: "^.*\\.rb$" # Match any .rb file ``` **How it works:** - Files are iterated and matched against the provided regular expression - If any file matches the regexp, the condition is satisfied - This enables negation patterns using regex negative lookahead ### Security Considerations To prevent ReDoS (Regular Expression Denial of Service) attacks from user-provided regexps: 1. Use Ruby 3.2+ `Regexp.timeout` feature: `Regexp.new(user_input_regexp, timeout: 1)` - MR merged: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145679 2. Alternative: Use [`Gitlab::UntrustedRegexp`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/untrusted_regexp.rb) which uses RE2 engine (no backtracking, immune to ReDoS) - Note: RE2 doesn't support lookaheads/lookbehinds, but sufficient for most glob-like patterns
issue