"Support regular expressions in rules:changes/exists"

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

  • Work on this issue
  • Close this issue

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 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:

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: !145679 (merged)
  2. Alternative: Use Gitlab::UntrustedRegexp which uses RE2 engine (no backtracking, immune to ReDoS)
    • Note: RE2 doesn't support lookaheads/lookbehinds, but sufficient for most glob-like patterns
Edited Feb 12, 2026 by 🤖 GitLab Bot 🤖
Assignee Loading
Time tracking Loading