http response bitbucket /rest/insights/1.0/projects/prometheus/repos/rules/commits/.*/reports/pint 200 OK
http response bitbucket /rest/api/1.0/projects/prometheus/repos/rules/commits/.*/pull-requests 200 {}
http start bitbucket 127.0.0.1:6076

mkdir testrepo
cd testrepo
exec git init --initial-branch=main .

cp ../src/v1.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
cp ../src/v2.yml rules.yml
exec git commit -am 'v2'

env BITBUCKET_AUTH_TOKEN="12345"
pint.error -l warn --no-color ci --require-owner
! stdout .
cmp stderr ../stderr.txt

-- src/v1.yml --
groups:
- name: mygroup
  rules:
  - record: rule1
    expr: sum(foo) by(job)
-- src/v2.yml --
groups:
- name: mygroup
  rules:
  - alert: syntax error
    expr: sum(foo) bar

  - alert: missing required fields
    expr: no_such_metric{job="fake"}

  - record: vector_matching
    expr: up{job="prometheus"} / prometheus_build_info{job="prometheus"}

  - alert: count
    expr: up{job="prometheus"} == 0
    for: 2m
    labels:
      notify: blackhole

  - alert: for_and_rate
    expr: rate(no_such_metric[10s])
    for: 0m
    labels:
      notify: blackhole

  - alert: template
    expr: sum(no_such_metric) by(foo) > 0
    labels:
      value: '{{ $value }}'
    annotations:
      instance: 'sum on {{ $labels.instance }} is {{ $value }}'

  - alert: fragile
    expr: errors / sum(requests) without(rack)

  - record: regexp
    expr: sum(no_such_metric{job=~"fake"})

  - alert: dups
    expr: errors / sum(requests) without(rack)
    #expr: errors / sum(requests) without(rack)
    #alert: dups
-- src/.pint.hcl --
ci {
  baseBranch = "main"
}
repository {
  bitbucket {
    uri        = "http://127.0.0.1:6076"
    timeout    = "10s"
    project    = "prometheus"
    repository = "rules"
  }
}
rule {
  match {
    kind = "recording"
  }
  aggregate ".+" {
    severity = "bug"
    keep     = ["job"]
  }
}
rule {
  match {
    kind = "alerting"
  }
  annotation "link" {
    severity = "bug"
    value    = "http://runbooks.example.com/(.+)"
    required = true
  }
}
rule {
  match {
    kind = "alerting"
  }
  ignore {
    kind = "alerting"
    label "notify" {
      value = "blackhole"
    }
  }
  annotation "summary" {
    severity = "bug"
    required = true
  }
  annotation "dashboard" {
    severity = "bug"
    value    = "https://grafana.example.com/(.+)"
  }
  label "priority" {
    severity = "bug"
    value    = "(1|2|3|4|5)"
    required = true
  }
  label "notify" {
    severity = "bug"
    required = true
  }
  label "component" {
    severity = "bug"
    required = true
  }
}

-- stderr.txt --
rules.yml:4-5 Bug: `link` annotation is required. (alerts/annotation)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:4-5 Bug: `summary` annotation is required. (alerts/annotation)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:4-5 Bug: `component` label is required. (rule/label)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:4-5 Bug: `notify` label is required. (rule/label)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:4-5 Bug: `priority` label is required. (rule/label)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 4 |   - alert: syntax error
 5 |     expr: sum(foo) bar

rules.yml:5 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected identifier "bar". (promql/syntax)
 5 |     expr: sum(foo) bar

rules.yml:7-8 Bug: `link` annotation is required. (alerts/annotation)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:7-8 Bug: `summary` annotation is required. (alerts/annotation)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:7-8 Bug: `component` label is required. (rule/label)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:7-8 Bug: `notify` label is required. (rule/label)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:7-8 Bug: `priority` label is required. (rule/label)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:7-8 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 7 |   - alert: missing required fields
 8 |     expr: no_such_metric{job="fake"}

rules.yml:8 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison)
 8 |     expr: no_such_metric{job="fake"}

rules.yml:10-11 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 10 |   - record: vector_matching
 11 |     expr: up{job="prometheus"} / prometheus_build_info{job="prometheus"}

rules.yml:13-17 Bug: `link` annotation is required. (alerts/annotation)
 13 |   - alert: count
 14 |     expr: up{job="prometheus"} == 0
 15 |     for: 2m
 16 |     labels:
 17 |       notify: blackhole

rules.yml:13-17 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 13 |   - alert: count
 14 |     expr: up{job="prometheus"} == 0
 15 |     for: 2m
 16 |     labels:
 17 |       notify: blackhole

rules.yml:19-23 Bug: `link` annotation is required. (alerts/annotation)
 19 |   - alert: for_and_rate
 20 |     expr: rate(no_such_metric[10s])
 21 |     for: 0m
 22 |     labels:
 23 |       notify: blackhole

rules.yml:19-23 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 19 |   - alert: for_and_rate
 20 |     expr: rate(no_such_metric[10s])
 21 |     for: 0m
 22 |     labels:
 23 |       notify: blackhole

rules.yml:20 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison)
 20 |     expr: rate(no_such_metric[10s])

rules.yml:21 Information: `0m` is the default value of `for`, consider removing this redundant line. (alerts/for)
 21 |     for: 0m

rules.yml:25-30 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 25 |   - alert: template
 26 |     expr: sum(no_such_metric) by(foo) > 0
 27 |     labels:
 28 |       value: '{{ $value }}'
 29 |     annotations:
 30 |       instance: 'sum on {{ $labels.instance }} is {{ $value }}'

rules.yml:27-28 Bug: `component` label is required. (rule/label)
 27 |     labels:
 28 |       value: '{{ $value }}'

rules.yml:27-28 Bug: `notify` label is required. (rule/label)
 27 |     labels:
 28 |       value: '{{ $value }}'

rules.yml:27-28 Bug: `priority` label is required. (rule/label)
 27 |     labels:
 28 |       value: '{{ $value }}'

rules.yml:28 Bug: Using `$value` in labels will generate a new alert on every value change, move it to annotations. (alerts/template)
 28 |       value: '{{ $value }}'

rules.yml:29-30 Bug: `link` annotation is required. (alerts/annotation)
 29 |     annotations:
 30 |       instance: 'sum on {{ $labels.instance }} is {{ $value }}'

rules.yml:29-30 Bug: `summary` annotation is required. (alerts/annotation)
 29 |     annotations:
 30 |       instance: 'sum on {{ $labels.instance }} is {{ $value }}'

rules.yml:30 Bug: Template is using `instance` label but the query removes it. (alerts/template)
 30 |       instance: 'sum on {{ $labels.instance }} is {{ $value }}'

rules.yml:32-33 Bug: `link` annotation is required. (alerts/annotation)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:32-33 Bug: `summary` annotation is required. (alerts/annotation)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:32-33 Bug: `component` label is required. (rule/label)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:32-33 Bug: `notify` label is required. (rule/label)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:32-33 Bug: `priority` label is required. (rule/label)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:32-33 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 32 |   - alert: fragile
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:33 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison)
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:33 Warning: Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels. (promql/fragile)
 33 |     expr: errors / sum(requests) without(rack)

rules.yml:35-36 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 35 |   - record: regexp
 36 |     expr: sum(no_such_metric{job=~"fake"})

rules.yml:36 Bug: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate)
 36 |     expr: sum(no_such_metric{job=~"fake"})

rules.yml:36 Bug: Unnecessary regexp match on static string `job=~"fake"`, use `job="fake"` instead. (promql/regexp)
 36 |     expr: sum(no_such_metric{job=~"fake"})

rules.yml:38-39 Bug: `link` annotation is required. (alerts/annotation)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:38-39 Bug: `summary` annotation is required. (alerts/annotation)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:38-39 Bug: `component` label is required. (rule/label)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:38-39 Bug: `notify` label is required. (rule/label)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:38-39 Bug: `priority` label is required. (rule/label)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:38-39 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner)
 38 |   - alert: dups
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:39 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison)
 39 |     expr: errors / sum(requests) without(rack)

rules.yml:39 Warning: Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels. (promql/fragile)
 39 |     expr: errors / sum(requests) without(rack)

level=ERROR msg="Fatal error" err="submitting reports: fatal error(s) reported"
