Tag rules syntax¶
Tag rules follow the doublestar (aka globstar: **) matching pattern. Regex is unfortunately unsupported.
Patterns¶
doublestar supports the following special terms in the patterns:
| Special Terms | Meaning | Example pattern | Example matches | Example doesn't match | Reason |
|---|---|---|---|---|---|
* | matches any sequence of characters (excludes /) | env-*/app |
| env-prod/sub/app | Only matches the single directory level |
** | matches any sequence of characters, including / — but only when ** stands alone as an entire path segment (**/x, x/**, or ** by itself) | **/redis |
| lib/redis-proxy | Matches any path ending in exactly /redis |
** (embedded in a segment) | if ** is embedded inside a larger segment instead of standing alone (e.g. prefix-**, **suffix), it does not cross / — it silently behaves like * instead | patterntest-** | patterntest-abc | patterntest-a/sub | Common mistake: this looks like it should match nested repos under patterntest-a/..., but it never crosses / — use patterntest-*/** instead |
? | matches any single character (excludes /) | qa-team?/* | qa-team0qa-team9 | qa-team10/app | Forces a single digit/letter suffix |
[class] | matches any single character against a class of characters (See below) (excludes /) | see below | |||
{alt1,alt2,...} | matches a sequence of characters if one of the comma-separated alternatives matches | release-{beta,rc} |
| release-alpha | alpha is not an alternative |
Warning
** must be a standalone path segment. prefix-** or **suffix will not cross / — they behave exactly like *. This applies to every tag rule, including immutability rules, so a pattern like patterntest-** will silently match zero nested repositories instead of protecting them. If you want to match a prefix across nested repository paths, write it as prefix-*/** (or otherwise put ** on its own path segment).
Any character with a special meaning can be escaped with a backslash (\).
Character classes support the following:
| Class | Meaning | Example pattern | Example matches | Example doesn't match | Reason |
|---|---|---|---|---|---|
[abc] | matches any single character within the set | service-[ab] | service-aservice-b | service-c | c is not in Character class [ab] |
[a-z][0-9] | matches any single character in the range | build-[0-9] | build-1build-7 | build-a | a not in range |
[^class] | matches any single character which does not match the class | release-[^9]* | release-1.0 | release-9.0 | 9 is excluded from the class |
Example for common tag pattern: Semantic Versioning (SemVer):
This is the most common versioning strategy (e.g., v1.0.1, 1.5.2).
This pattern uses alt-matches with an empty alt option, matching "nothing":
- The pattern
{v,}matchesvor an empty string ("nothing") which means it can match strings which start withvor not. - The pattern
[0-9]{,[0-9],[0-9][0-9]}matches a single digit (always) and one of 3 alt options: empty, single digit, or two digits; this gives us a matching pattern between 0 to 999 - This limits us to to max version of
v999.999.999which should suffice for most usage. If not enough, just add another alt choice with more digits:[0-9]{,[0-9],[0-9][0-9],[0-9][0-9][0-9]}
| Goal | Pattern | Matches | Does Not Match |
|---|---|---|---|
Strict 3-part SemVer with optional v prefix | {v,}[0-9]{,[0-9],[0-9][0-9]}.[0-9]{,[0-9],[0-9][0-9]}.[0-9]{,[0-9],[0-9][0-9]} |
| v1v1.0latest |