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"
! exec pint -l warn --no-color ci --require-owner
! stdout .
cmp stderr ../stderr.txt
cmp bitbucket.got ../bitbucket.expected

-- 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"
}
parser {
  include    = [".+.yml"]
}
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 --
Bug: required annotation not set (alerts/annotation)
  ---> rules.yml:4-5 -> `syntax error` [+6 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `link` annotation is required.

Bug: required annotation not set (alerts/annotation)
  ---> rules.yml:4-5 -> `syntax error` [+4 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `summary` annotation is required.

Bug: required label not set (rule/label)
  ---> rules.yml:4-5 -> `syntax error` [+4 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `component` label is required.

Bug: required label not set (rule/label)
  ---> rules.yml:4-5 -> `syntax error` [+4 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `notify` label is required.

Bug: required label not set (rule/label)
  ---> rules.yml:4-5 -> `syntax error` [+4 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `priority` label is required.

Bug: missing owner (rule/owner)
  ---> rules.yml:4-5 -> `syntax error` [+8 duplicates]
5 |     expr: sum(foo) bar
              ^^^ `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.

Fatal: PromQL syntax error (promql/syntax)
  ---> rules.yml:5 -> `syntax error`
5 |     expr: sum(foo) bar
                       ^^^ unexpected identifier "bar"

Warning: always firing alert (alerts/comparison)
  ---> rules.yml:8 -> `missing required fields` [+3 duplicates]
8 |     expr: no_such_metric{job="fake"}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^ This query doesn't have any condition and so this alert will always fire if it matches anything.

Information: redundant field with default value (alerts/for)
  ---> rules.yml:21 -> `for_and_rate`
21 |     for: 0m
              ^^ `0m` is the default value of `for`, this line is unnecessary.

Bug: template uses non-existent label (alerts/template)
  ---> rules.yml:25-30 -> `template`
26 |     expr: sum(no_such_metric) by(foo) > 0
                                   ^^ Query is using aggregation with `by(foo)`, only labels included inside `by(...)` will be present on the results.
   | [...]
30 |       instance: 'sum on {{ $labels.instance }} is {{ $value }}'
                                       ^^^^^^^^^ Template is using `instance` label but the query results won't have this label.

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

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

Bug: required label is being removed via aggregation (promql/aggregate)
  ---> rules.yml:36 -> `regexp`
36 |     expr: sum(no_such_metric{job=~"fake"})
               ^^^ Query is using aggregation that removes all labels.
                   `job` label is required and should be preserved when aggregating all rules.

level=ERROR msg="Execution completed with error(s)" err="submitting reports: fatal error(s) reported"
-- bitbucket.expected --
DELETE /rest/insights/1.0/projects/prometheus/repos/rules/commits/.*/reports/pint
  Accept-Encoding: gzip
  Authorization: Bearer "12345"
  Content-Type: application/json

PUT /rest/insights/1.0/projects/prometheus/repos/rules/commits/.*/reports/pint
  Accept-Encoding: gzip
  Authorization: Bearer "12345"
  Content-Type: application/json
--- BODY ---
reporter: Prometheus rule linter
title: pint unknown
result: FAIL
details: |-
  pint is a Prometheus rule linter/validator.
  It will inspect all Prometheus recording and alerting rules for problems that could prevent these from working correctly.
  Checks can be either offline (static checks using only rule definition) or online (validate rule against live Prometheus server).
link: https://cloudflare.github.io/pint/
data:
  - value: 10
    title: Number of rules parsed
    type: NUMBER
  - value: 10
    title: Number of rules checked
    type: NUMBER
  - value: 46
    title: Number of problems found
    type: NUMBER
  - value: 98
    title: Number of offline checks
    type: NUMBER
  - value: 0
    title: Number of online checks
    type: NUMBER
  - value: 0
    title: Checks duration
    type: DURATION
--- END ---

GET /rest/api/1.0/projects/prometheus/repos/rules/commits/.*/pull-requests
  Accept-Encoding: gzip
  Authorization: Bearer "12345"
  Content-Type: application/json

DELETE /rest/insights/1.0/projects/prometheus/repos/rules/commits/.*/reports/pint
  Accept-Encoding: gzip
  Authorization: Bearer "12345"
  Content-Type: application/json

POST /rest/insights/1.0/projects/prometheus/repos/rules/commits/.*/reports/pint
  Accept-Encoding: gzip
  Authorization: Bearer "12345"
  Content-Type: application/json
--- BODY ---
annotations:
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 5
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 5
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 5
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 5
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 5
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 5
  - path: rules.yml
    message: "promql/syntax: PromQL syntax error"
    severity: HIGH
    type: BUG
    link: https://cloudflare.github.io/pint/checks/promql/syntax.html
    line: 5
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 8
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 8
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 8
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 8
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 8
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 8
  - path: rules.yml
    message: "alerts/comparison: always firing alert"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/alerts/comparison.html
    line: 8
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 11
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 17
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 17
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 23
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 23
  - path: rules.yml
    message: "alerts/comparison: always firing alert"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/alerts/comparison.html
    line: 20
  - path: rules.yml
    message: "alerts/for: redundant field with default value"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/alerts/for.html
    line: 21
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 30
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 30
  - path: rules.yml
    message: "alerts/template: template uses non-existent label"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/template.html
    line: 30
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 30
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 30
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 30
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 30
  - path: rules.yml
    message: "alerts/template: value used in labels"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/template.html
    line: 28
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 33
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 33
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 33
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 33
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 33
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 33
  - path: rules.yml
    message: "alerts/comparison: always firing alert"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/alerts/comparison.html
    line: 33
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 36
  - path: rules.yml
    message: "promql/regexp: redundant regexp"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/promql/regexp.html
    line: 36
  - path: rules.yml
    message: "promql/aggregate: required label is being removed via aggregation"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/promql/aggregate.html
    line: 36
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 39
  - path: rules.yml
    message: "alerts/annotation: required annotation not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/alerts/annotation.html
    line: 39
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 39
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 39
  - path: rules.yml
    message: "rule/label: required label not set"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/label.html
    line: 39
  - path: rules.yml
    message: "rule/owner: missing owner"
    severity: MEDIUM
    type: BUG
    link: https://cloudflare.github.io/pint/checks/rule/owner.html
    line: 39
  - path: rules.yml
    message: "alerts/comparison: always firing alert"
    severity: LOW
    type: CODE_SMELL
    link: https://cloudflare.github.io/pint/checks/alerts/comparison.html
    line: 39
--- END ---

