diff --git a/.github/policy/files.rego b/.github/policy/files.rego new file mode 100644 index 0000000000..5ab9a3cbab --- /dev/null +++ b/.github/policy/files.rego @@ -0,0 +1,46 @@ +# Expects policy input as provided by: +# https://api.github.com/repos/open-policy-agent/opa/pulls/${PR_ID}/files +# +# Note that the "filename" here refers to the full path of the file, like +# docs/website/data/integrations.yaml - since that's how it's named in the +# input we'll use the same convention here. + +package files + +import future.keywords.in + +filenames := [f | f := input[_].filename] + +changes := {filename: attributes | + c := input[_] + filename := c.filename + attributes := object.remove(c, ["filename"]) +} + +deny["Logo must be placed in docs/website/static/img/logos/integrations"] { + "docs/website/data/integrations.yaml" in filenames + + some filename in filenames + endswith(filename, ".png") + changes[filename].status == "added" + directory := substring(filename, 0, last_indexof(filename, "/")) + directory != "docs/website/static/img/logos/integrations" +} + +deny["Logo must be a .png file"] { + "docs/website/data/integrations.yaml" in filenames + + some filename in filenames + changes[filename].status == "added" + directory := substring(filename, 0, last_indexof(filename, "/")) + directory == "docs/website/static/img/logos/integrations" + not endswith(filename, ".png") +} + +last_indexof(string, search) = i { + all := [i | chars := split(string, ""); chars[i] == search] + count(all) > 0 + i := all[count(all) - 1] +} else = -1 { + true +} diff --git a/.github/policy/files_test.rego b/.github/policy/files_test.rego new file mode 100644 index 0000000000..266813fe3b --- /dev/null +++ b/.github/policy/files_test.rego @@ -0,0 +1,44 @@ +package files_test + +import data.files.deny + +test_deny_logo_if_added_in_wrong_directory { + expected := "Logo must be placed in docs/website/static/img/logos/integrations" + deny[expected] with input as [ + { + "filename": "docs/website/data/integrations.yaml", + "status": "modified", + }, + { + "filename": "docs/website/static/img/logos/example.png", + "status": "added", + }, + ] +} + +test_allow_logo_if_added_in_correct_directory { + count(deny) == 0 with input as [ + { + "filename": "docs/website/data/integrations.yaml", + "status": "modified", + }, + { + "filename": "docs/website/static/img/logos/integrations/example.png", + "status": "added", + }, + ] +} + +test_deny_logo_if_not_png_file { + expected := "Logo must be a .png file" + deny[expected] with input as [ + { + "filename": "docs/website/data/integrations.yaml", + "status": "modified", + }, + { + "filename": "docs/website/static/img/logos/integrations/example.jpg", + "status": "added", + }, + ] +} diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index c8921e4e49..868d129123 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -274,3 +274,24 @@ jobs: - name: Build run: make ci-go-ci-build-linux GOVERSION=${{ matrix.version }} timeout-minutes: 30 + + # Run PR metadata against Rego policies + rego-check-pr: + name: Rego PR checks + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download OPA + uses: infracost/setup-opa@v1 + + - name: Test policies + run: opa test .github/policy + + - name: Run policy checks on changed files + run: | + curl --silent --fail --header 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ + https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files \ + | opa eval --data .github/policy/files.rego --format values --stdin-input --fail-defined 'data.files.deny[message]' +