From b700739602ac8f976524a421759a09f9869e67d1 Mon Sep 17 00:00:00 2001 From: Anders Eknert Date: Wed, 22 Dec 2021 12:18:54 +0100 Subject: [PATCH] Check PR for mistakes in ecosystem page change Since both contributors and reviewers (i.e. me!) seem to easily miss the correct location of the logo for a new integration - add checks that will fail the PR when this happens. This is admittedly mostly for fun, but I figured it would be pretty cool to explore whether we could integrate Rego policies into our own build pipeline. There are definitely more things to explore using the GitHub API as a datasource for build pipeline policies, but this is at least a start. Signed-off-by: Anders Eknert --- .github/policy/files.rego | 46 +++++++++++++++++++++++++++++ .github/policy/files_test.rego | 44 +++++++++++++++++++++++++++ .github/workflows/pull-request.yaml | 21 +++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 .github/policy/files.rego create mode 100644 .github/policy/files_test.rego 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]' +