Skip to content

Commit

Permalink
Add a ruletype for enforcing a file being present in a repo (#227)
Browse files Browse the repository at this point in the history
* Add a ruletype for enforcing a file being present in a repo

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Set it to alpha

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Update rule-types/common/enforce_file.yaml

Co-authored-by: Evan Anderson <[email protected]>

* Make content optional and remove debug comments

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add tests for enforce_file ruletype

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add .gitignore

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add apply_if_file option for skipping the rule in case a given file is missing

Signed-off-by: Radoslav Dimitrov <[email protected]>

---------

Signed-off-by: Radoslav Dimitrov <[email protected]>
Co-authored-by: Evan Anderson <[email protected]>
  • Loading branch information
rdimitrov and evankanderson authored Jan 9, 2025
1 parent 09b7e18 commit 35907b1
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
48 changes: 48 additions & 0 deletions rule-types/common/enforce_file.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
tests:
- name: "File should be present"
def:
file: README
content: ""
params: {}
expect: "pass"
git:
repo_base: file_present
- name: "File is missing"
def:
file: README
params: {}
expect: "fail"
git:
repo_base: file_missing
- name: "File present and matches content"
def:
file: README
content: "Test content"
params: {}
expect: "pass"
git:
repo_base: file_present
- name: "File present, but has different content"
def:
file: README
content: "Different content"
params: {}
expect: "fail"
git:
repo_base: file_present
- name: "File present, but has more content than expected"
def:
file: README
content: "Test"
params: { }
expect: "fail"
git:
repo_base: file_present
- name: "File present, but has less content than expected"
def:
file: README
content: "Test content with a subset"
params: { }
expect: "fail"
git:
repo_base: file_present
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test content
101 changes: 101 additions & 0 deletions rule-types/common/enforce_file.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
version: v1
release_phase: alpha
type: rule-type
name: enforce_file
display_name: Enforce a file in the repository
short_failure_message: File does not exist or does not match the expected content
severity:
value: medium
context: {}
description: |
Enforce the presence of a file and its content in the repository.
guidance: |
Ensures that the repository contains a specific file and its content.
This rule is useful for enforcing the presence of various files in the repository, such as LICENSE, README, CONTRIBUTING,
CODE_OF_CONDUCT, Dependabot configuration files and many more. It can also be used to enforce the presence of specific
content in the file so you know that the file is not just a placeholder.
def:
in_entity: repository
rule_schema:
type: object
properties:
file:
type: string
description: |
The file to enforce in the repository.
For example, LICENSE, README, CONTRIBUTING, .github/dependabot.yml, etc.
content:
type: string
description: |
The content to enforce in the file.
For example, the content of the LICENSE file.
default: ""
apply_if_file:
type: string
description: |
Optional. If specified, the rule will only be evaluated if the given file exists.
This is useful for rules that are only applicable to certain types of repositories.
default: ""
required:
- file
ingest:
type: git
git:
# The following code checks for the presence of a file and its content.
# If the content is not specified (content = ""), then only the presence of the file is checked.
# If apply_if_file is specified, the rule is only evaluated if that file exists.
eval:
type: rego
rego:
type: deny-by-default
def: |
package minder
import future.keywords.if
default allow := false
default skip := false
fileStr := trim_space(file.read(input.profile.file))
# Skip if apply_if_file is specified and the file doesn't exist
skip if {
input.profile.apply_if_file != ""
not file.exists(input.profile.apply_if_file)
}
allow if {
# Read the file and check if it contains the content
fileStr == trim_space(input.profile.content)
} else if {
# Check if the file exists and the content is left blank
file.exists(input.profile.file)
input.profile.content == ""
}
message := sprintf("Skipping rule because file %v does not exist", [input.profile.apply_if_file]) if {
input.profile.apply_if_file != ""
not file.exists(input.profile.apply_if_file)
} else := sprintf("File %v does not exist", [input.profile.file]) if {
not file.exists(input.profile.file)
} else := sprintf("File %v does not match the expected content %v", [input.profile.file, input.profile.content]) if {
fileStr != trim_space(input.profile.content)
}
remediate:
type: pull_request
pull_request:
title: "Ensure {{.Profile.file }} exists with the expected content"
body: |
This is a Minder automated pull request.
This pull request ensures that this repository contains the file {{.Profile.file}} with the expected content set by your organization.
contents:
- path: "{{.Profile.file}}"
action: replace
content: |
{{.Profile.content}}
# Defines the configuration for alerting on the rule
alert:
type: security_advisory
security_advisory: {}

0 comments on commit 35907b1

Please sign in to comment.