forked from masterpointio/github-action-opa-rego-test
-
Notifications
You must be signed in to change notification settings - Fork 0
/
action.yml
146 lines (134 loc) · 6.38 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
name: "OPA Rego Test and Coverage Report"
description: "Run OPA tests and generate coverage report for PRs. Test your OPA Rego policies!"
author: Masterpoint
branding:
icon: "zap"
color: "blue"
inputs:
path:
description: "Path to the directory containing OPA Rego files to test. Default to root directory."
required: false
default: "."
test_file_postfix:
description: 'The postfix to use for test files. E.g. notification.rego <> notification_test.rego. Default is "_test".'
required: false
default: "_test"
write_pr_comment:
description: "Flag to write an user friendly PR comment of the test results. Default of true."
required: false
default: true
pr_comment_title:
description: "Title of the PR comment of the test results."
required: false
default: "🧪 OPA Rego Policy Test Results"
pr_comment_mode:
description: Mode that will be used to update comment. Options of upsert (update in place) or recreate.
default: "upsert"
run_coverage_report:
description: "Flag to run OPA coverage tests and write to the PR. The `write_pr_comment` must be enabled for the coverage report to be written. Default of true."
required: false
default: true
report_untested_files:
description: "Check & report in the PR comments of the Rego files that do not have any corresponding test files. For best conventions, append the postfix `_test` (or what you set as the `test_file_postfix` input) for your test file. E.g. `notification.rego` <> `notification_test.rego`"
required: false
default: false
opa_version:
description: "Version of OPA CLI to use. Default is 0.67.1."
required: false
default: "0.67.1"
indicate_source_message:
description: Flag to comment the origins watermark (this repository) of the GitHub Action in the PR comment. Default of true.
required: false
default: true
outputs:
parsed_results:
description: The parsed results after processing the tests and/or coverage report.
value: ${{ steps.parse-results.outputs.parsed_results }}
tests_failed:
description: A `true` or `false` flag indicating if any of the tests failed or not.
value: ${{ steps.parse-results.outputs.tests_failed }}
runs:
using: "composite"
steps:
- name: Setup OPA
uses: open-policy-agent/setup-opa@v2
with:
version: ${{ inputs.opa_version }}
- name: Run OPA Tests and Coverage
id: opa-test-coverage
shell: bash
run: |
BASE_DIRECTORY_PATH="${{ inputs.path }}"
tests=$(find "$BASE_DIRECTORY_PATH" -type f -name "*${{ inputs.test_file_postfix }}.rego")
test_output=""
coverage_output=""
for test in $tests; do
echo "Running test and coverage: $test"
base_name=$(basename "$test" "${{ inputs.test_file_postfix }}.rego")
test_dir=$(dirname "$test")
impl_file=$(find "$test_dir" "$test_dir/.." -maxdepth 1 -type f -name "${base_name}.rego" | head -n1)
mock_file=$(find "$test_dir" "$test_dir/.." -maxdepth 1 -type f -name "${base_name}.mock.json" | head -n1)
if [ -n "$impl_file" ]; then
echo "Found implementation file: $impl_file"
test_result=$(opa test -v "$test" "$impl_file" "$mock_file" || true)
coverage_result=$(opa test --coverage "$test" "$impl_file" "$mock_file" || true)
test_output+="$test_result"$'\n\n'
coverage_output+="$coverage_result"$'\n\n'
else
echo "Error: Implementation file not found for test: $test"
error_message="Error: Implementation file not found for test: $test"$'\n\n'
test_output+="$error_message"
coverage_output+="$error_message"
fi
done
echo "$test_output"
echo "$coverage_output"
echo "test_result<<EOF" >> $GITHUB_OUTPUT
echo "$test_output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "coverage_result<<EOF" >> $GITHUB_OUTPUT
echo "$coverage_output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Find Rego files without tests
if: inputs.report_untested_files == 'true'
id: find-no-test
shell: bash
run: |
main_dir="${{ inputs.path }}"
echo "Searching for untested Rego files in: $main_dir"
no_test_files=$(find "$main_dir" -type f -name "*.rego" ! -name "*${{ inputs.test_file_postfix }}.rego" | while read file; do
base_name=$(basename "$file" .rego)
# Search for a corresponding test file anywhere in the project
test_file=$(find "$main_dir" -type f -name "${base_name}${{ inputs.test_file_postfix }}.rego")
if [ -z "$test_file" ]; then
echo "$file"
fi
done)
echo "no_test_files<<EOF" >> $GITHUB_OUTPUT
echo "$no_test_files" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "Search complete, found the following Rego files without tests: $no_test_files"
# Parse and format the test results which will be consumed by the following step to comment on the PR.
- name: "Parse & Format Results from Tests"
id: parse-results
run: node ${{ github.action_path }}/dist/index.js
shell: bash
env:
test_result: ${{ steps.opa-test-coverage.outputs.test_result }}
coverage_result: ${{ steps.opa-test-coverage.outputs.coverage_result }}
report_untested_files: ${{ inputs.report_untested_files }}
no_test_files: ${{ steps.find-no-test.outputs.no_test_files }}
pr_comment_title: ${{ inputs.pr_comment_title }}
run_coverage_report: ${{ inputs.run_coverage_report }}
indicate_source_message: ${{ inputs.indicate_source_message }}
# Create (or update in-place) a PR comment of the test result output
- name: Comment on PR
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
# If `write_pr_comment` enabled, regardless of if test is success or fail, write the results of the failure.
# Even if input is bool, it has to be treated as string bc of GH's behavior (https://github.com/actions/runner/issues/1483)
if: inputs.write_pr_comment == 'true' && (success() || failure())
with:
message: |
${{ steps.parse-results.outputs.parsed_results }}
comment_tag: opa-test-results
mode: ${{ inputs.pr_comment_mode }}