Skip to content

Expression Language

GitWire's expression language lets you write declarative rules in .gitwire.yml using a safe, sandboxed DSL. Inspired by gitStream's CM syntax but extended with pipe-style filters.

Syntax Overview

yaml
custom_rules:
  approve_safe:
    if: "files | all(extension('.css', '.md'))"
    run:
      - action: add-label
        args: { label: "safe-change" }

Operators

OperatorMeaningExample
andLogical ANDis.docs and is.small
orLogical ORis.formatting or is.tests
notLogical NOTnot is.draft
>, >=Greater thanchanges.added > 50
<, <=Less thanfiles | length < 5
==, !=Equalityauthor == 'alice'
+, -, *, /Arithmeticchanges.added + changes.deleted > 100

Pipe Syntax

The pipe operator (|) chains filter functions:

input | filter(arg1, arg2)

Multiple pipes chain left-to-right:

author | lower | contains('bot')

Built-in Filters

FilterInputReturnsExample
match(pattern...)stringbooleanauthor | match('*[bot]')
contains(substring)stringbooleantitle | contains('fix')
startsWith(prefix)stringbooleanbranch | startsWith('feature/')
endsWith(suffix)stringbooleanfile | endsWith('.test.js')
includes(value)arraybooleanlabels | includes('bug')
some(filter)arraybooleanfiles | some(match('src/**'))
all(filter)arraybooleanfiles | all(extension('.md'))
lengtharray/stringnumberfiles | length > 10
extension(ext...)stringbooleanfile | extension('.js', '.ts')
lowerstringstringauthor | lower
upperstringstringtitle | upper

Context Variables

Available in every rule evaluation:

VariableTypeDescription
authorstringPR/issue author login
branchstringBranch name (PRs only)
titlestringPR title or issue title
bodystringPR body or issue body
labelsstring[]Current labels
filesstring[]Changed file paths (PRs only)
changesLine change counts
repostringRepository full name
is_newbooleanTrue for newly opened items
is_draftbooleanTrue for draft PRs

Named Expressions

Define reusable expressions in the expressions section:

yaml
expressions:
  is:
    docs: "files | all(extension('.md', '.rst'))"
    formatting: "files | all(extension('.css', '.scss', '.less'))"
    tests: "files | all(match('**/*.test.*'))"
    safe: "is.docs or is.formatting or is.tests"
    security: "files | some(match('src/auth/**'), match('**/secrets*'))"

custom_rules:
  approve_safe:
    if: "is.safe"
    run:
      - action: approve

Released under the MIT License.