Single character regular expressions do not work
Summary
After the change to pattern detection in 12.0+ via gitlab-foss!27925 (merged) any pattern with a single character match in it will fail to work:
At least two characters are required now to allow GitLab to considered the regular expression valid.
Steps to reproduce
Place the following in CI linter / Pipeline editor:
job:
script: echo something
except:
variables:
- $VARIABLE_NAME =~ /a/
An error is observed from the linter, indicating it does not understand the expression:
This GitLab CI configuration is invalid: jobs:end-to-end:except variables invalid expression syntax.
What is the current bug behavior?
Single character regex patterns are unrecognized, and do not pass GitLab's syntax test.
What is the expected correct behavior?
Single character regex patterns are valid should work.
Output of checks
This bug happens on GitLab.com
Possible fixes
As a workaround, the regex just needs to be re-defined in a way that includes at least two characters. For example, it could be checked for with an alternate form:
$VARIABLE_NAME =~ /.*a.*/
$VARIABLE_NAME =~ /a+/
The issue is in the regex used to identify regex patterns: https://gitlab.com/gitlab-org/gitlab/blob/7f33b5844b73ceb2bb43a043fc7b20c247ca3afb/lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb#L11
^\/([^\/]|\\/)+[^\\]\/[ismU]*
The capture group with a +
in the linked regex above looks for at least one character:
([^\/]|\\/)+
But then a negated character set is looked for as the second necessary match after the capture group ends:
[^\\]
This adds up to two minimum characters required.
When only one character exists within /…/
, the regex to detect a pattern does not match anything, and treats the syntax invalid as an eventual result:
irb(main):016:0> ::Gitlab::Ci::Pipeline::Expression::Lexer.new('$VARIABLE_NAME =~ /a/').tokens
Traceback (most recent call last):
7: from (irb):16
6: from lib/gitlab/ci/pipeline/expression/lexer.rb:39:in `tokens'
5: from lib/gitlab/utils/strong_memoize.rb:30:in `strong_memoize'
4: from lib/gitlab/ci/pipeline/expression/lexer.rb:39:in `block in tokens'
3: from lib/gitlab/ci/pipeline/expression/lexer.rb:51:in `tokenize'
2: from lib/gitlab/ci/pipeline/expression/lexer.rb:51:in `times'
1: from lib/gitlab/ci/pipeline/expression/lexer.rb:63:in `block in tokenize'
Gitlab::Ci::Pipeline::Expression::Lexer::SyntaxError (Unknown lexeme found!)