Skip to content

Commit

Permalink
Allow matching on rule state
Browse files Browse the repository at this point in the history
  • Loading branch information
prymitive committed Aug 23, 2024
1 parent ef91e8b commit f8b6ef6
Show file tree
Hide file tree
Showing 14 changed files with 1,385 additions and 747 deletions.
11 changes: 11 additions & 0 deletions cmd/pint/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func actionCI(c *cli.Context) error {
if err != nil {
return err
}
entries = filterNoopEntries(entries)

ctx := context.WithValue(context.Background(), config.CommandKey, config.CICommand)

Expand Down Expand Up @@ -342,3 +343,13 @@ func detectGithubActions(gh *config.GitHub) *config.GitHub {
}
return gh
}

func filterNoopEntries(src []discovery.Entry) (dst []discovery.Entry) {
for _, e := range src {
if e.State == discovery.Noop && e.PathError != nil {
continue
}
dst = append(dst, e)
}
return dst
}
1 change: 1 addition & 0 deletions cmd/pint/tests/0083_github_action.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ groups:

-- src/.pint.hcl --
repository {}

1 change: 1 addition & 0 deletions cmd/pint/tests/0184_ci_file_ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ cmp stderr ../stderr.txt
-- stderr.txt --
level=INFO msg="Loading configuration file" path=.pint.hcl
level=INFO msg="Finding all rules to check on current git branch" base=main
level=INFO msg="No rules found, skipping Prometheus discovery"
-- src/rules.yml --
# pint ignore/file
- record: rule1
Expand Down
45 changes: 45 additions & 0 deletions cmd/pint/tests/0185_state_empty.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
mkdir testrepo
cd testrepo
exec git init --initial-branch=main .

cp ../src/rules.yml rules.yml
cp ../src/.pint.hcl .
env GIT_AUTHOR_NAME=pint
env GIT_AUTHOR_EMAIL=pint@example.com
env GIT_COMMITTER_NAME=pint
env GIT_COMMITTER_EMAIL=pint@example.com
exec git add .
exec git commit -am 'import rules and config'

exec git checkout -b v2
exec touch .keep
exec git add .keep
exec git commit -am 'v2'

pint.ok --no-color ci
! stdout .
cmp stderr ../stderr.txt

-- stderr.txt --
level=INFO msg="Loading configuration file" path=.pint.hcl
level=INFO msg="Finding all rules to check on current git branch" base=main
-- src/rules.yml --
- record: rule1
expr: sum(foo) by(job)
- record: rule2
expr: sum(foo)

-- src/.pint.hcl --
ci {
baseBranch = "main"
}
parser {
relaxed = [".*"]
include = ["rules.yml"]
}
rule {
aggregate ".+" {
keep = [ "job" ]
severity = "bug"
}
}
54 changes: 54 additions & 0 deletions cmd/pint/tests/0186_ci_state_any.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
mkdir testrepo
cd testrepo
exec git init --initial-branch=main .

cp ../src/rules.yml rules.yml
cp ../src/.pint.hcl .
env GIT_AUTHOR_NAME=pint
env GIT_AUTHOR_EMAIL=pint@example.com
env GIT_COMMITTER_NAME=pint
env GIT_COMMITTER_EMAIL=pint@example.com
exec git add .
exec git commit -am 'import rules and config'

exec git checkout -b v2
exec touch .keep
exec git add .keep
exec git commit -am 'v2'

pint.error --no-color ci
! stdout .
cmp stderr ../stderr.txt

-- stderr.txt --
level=INFO msg="Loading configuration file" path=.pint.hcl
level=INFO msg="Finding all rules to check on current git branch" base=main
level=INFO msg="Problems found" Bug=1
rules.yml:4 Bug: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate)
4 | expr: sum(foo)

level=ERROR msg="Fatal error" err="problems found"
-- src/rules.yml --
- record: rule1
expr: sum(foo) by(job)
- record: rule2
expr: sum(foo)

-- src/.pint.hcl --
ci {
baseBranch = "main"
}
parser {
relaxed = [".*"]
include = ["rules.yml"]
}
rule {
match {
kind = "recording"
state = ["any"]
}
aggregate ".+" {
keep = [ "job" ]
severity = "bug"
}
}
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [promql/range_query](checks/promql/range_query.md) now allows to configure a custom maximum
duration for range queries - #1064.
- Added `--enabled` flag to the pint command. Passing this flag will only run selected check(s).
- Added `state` option to the rule `match` block. See [configuration](configuration.md) docs for details.

### Fixed

Expand Down
69 changes: 51 additions & 18 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ nav_order: 2
{: .no_toc .text-delta }

1. TOC
{:toc}
{:toc}

## Environment variables

Expand Down Expand Up @@ -80,10 +80,10 @@ parser {

```yaml
groups:
- name: example
rules:
- record: ...
expr: ...
- name: example
rules:
- record: ...
expr: ...
```
If you're using pint to lint rules that are embedded inside a different structure
Expand Down Expand Up @@ -519,9 +519,10 @@ Syntax:
```js
rule {
match {
path = "(.+)"
name = "(.+)"
kind = "alerting|recording"
path = "(.+)"
state = [ "any|added|modified|renamed|unmodified", ... ]
name = "(.+)"
kind = "alerting|recording"
command = "ci|lint|watch"
annotation "(.*)" {
value = "(.*)"
Expand All @@ -534,9 +535,10 @@ rule {
match { ... }
match { ... }
ignore {
path = "(.+)"
name = "(.+)"
kind = "alerting|recording"
path = "(.+)"
state = [ "any|added|modified|renamed|unmodified", ... ]
name = "(.+)"
kind = "alerting|recording"
command = "ci|lint|watch"
annotation "(.*)" {
value = "(.*)"
Expand All @@ -555,10 +557,19 @@ rule {
}
```

- `match:path` - only files matching this pattern will be checked by this rule
- `match:path` - only files matching this pattern will be checked by this rule.
- `match:state` - only match rules based on their state. Default value for `state` depends on the
pint command that is being run, for `pint ci` the default value is `["added", "modified", "renamed"]`,
for any other command the default value is `["any"]`.
Possible values:
- `any` - match rule in any state
- `added` - a rule is being added in a git commit, a rule can only be in this state when running `pint ci` on a pull request.
- `modified` - a rule is being modified in a git commit, a rule can only be in this state when running `pint ci` on a pull request.
- `renamed` - a rule is being modified in a git commit, a rule can only be in this state when running `pint ci` on a pull request.
- `unmodified` - a rule is not being modified in a git commit when running `pint ci` or other pint command was run that doesn't try to detect which rules were modified.
- `match:name` - only rules with names (`record` for recording rules and `alert` for alerting
rules) matching this pattern will be checked rule
- `match:kind` - optional rule type filter, only rule of this type will be checked
rules) matching this pattern will be checked rule.
- `match:kind` - optional rule type filter, only rule of this type will be checked.
- `match:command` - optional command type filter, this allows to include or ignore rules
based on the command pint is run with `pint ci`, `pint lint` or `pint watch`.
- `match:annotation` - optional annotation filter, only alert rules with at least one
Expand All @@ -581,6 +592,8 @@ be matched / ignored.

Examples:

Check applied only to severity="critical" and severity="warning" alerts in "ci" or "lint" command is run:

```js
rule {
match {
Expand All @@ -593,10 +606,12 @@ rule {
ignore {
command = "watch"
}
[ check applied only to severity="critical" and severity="warning" alerts in "ci" or "lint" command is run ]
check { ... }
}
```

Check applied unless "watch" or "lint" command is run:

```js
rule {
ignore {
Expand All @@ -605,24 +620,42 @@ rule {
ignore {
command = "lint"
}
[ check applied unless "watch" or "lint" command is run ]
check { ... }
}
```

Check applied only to alerting rules with "for" field value that is >= 5m:

```js
rule {
match {
for = ">= 5m"
}
[ check applied only to alerting rules with "for" field value that is >= 5m ]
check { ... }
}
```

Check applied only to alerting rules with "keep_firing_for" field value that is > 15m:

```js
rule {
match {
keep_firing_for = "> 15m"
}
[ check applied only to alerting rules with "keep_firing_for" field value that is > 15m ]
check { ... }
}
```

Check that is run on all rules, including unmodified files, when running `pint ci`:

```js
rule {
match {
state = ["any"]
}
ignore {
command = "ci"
}
check { ... }
}
```
Loading

0 comments on commit f8b6ef6

Please sign in to comment.