Skip to content

Commit 106551d

Browse files
authored
Merge pull request #76868 from aireilly/serverless-docs-main
Add Vale to serverless-docs-main
2 parents 0b338e7 + 2819590 commit 106551d

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

scripts/prow-vale-review.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/bin/bash
2+
# This runs Vale on updated files in last commit, checks if the Vale alerts are on new/modified lines, and if so, builds curl request
3+
# for GitHub review comment API. Also checks if a commment already exists before posting.
4+
# To test locally, create a Github personal access token and export a $GITHUB_AUTH_TOKEN environmental variable to use the token
5+
6+
# Check if jq is installed
7+
hash jq 2>/dev/null || { echo >&2 "Error: jq is not installed"; exit 1; }
8+
9+
# Set $PULL_NUMBER and $COMMIT_ID for local testing. Otherwise use variables passed by Prow
10+
if [ $# -eq 0 ]; then
11+
COMMIT_ID=$(git log -n 1 --pretty=format:"%H")
12+
PULL_NUMBER=$(curl -s "https://api.github.com/search/issues?q=$COMMIT_ID" | jq '.items[0].number')
13+
else
14+
PULL_NUMBER=$1
15+
COMMIT_ID=$2
16+
fi
17+
18+
FILES=$(git diff --name-only HEAD~1 HEAD --diff-filter=d "*.adoc" ':(exclude)_unused_topics/*' ':(exclude)rest_api/*' ':(exclude)microshift_rest_api/*' ':(exclude)modules/virt-runbook-*' ':(exclude)modules/oc-by-example-content.adoc' ':(exclude)modules/oc-adm-by-example-content.adoc' ':(exclude)monitoring/config-map-reference-for-the-cluster-monitoring-operator.adoc' ':(exclude)modules/microshift-oc-adm-by-example-content.adoc' ':(exclude)modules/microshift-oc-by-example-content.adoc')
19+
20+
function post_review_comment {
21+
22+
LINE_NUMBER=$3
23+
BODY=$1
24+
FILENAME=$2
25+
echo "Sending review comment curl request..."
26+
curl -L -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $GITHUB_AUTH_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/openshift/openshift-docs/pulls/$PULL_NUMBER/comments -d '{"body":"'"$BODY"'","commit_id":"'"$COMMIT_ID"'","path":"'"$FILENAME"'","line":'"$LINE_NUMBER"',"side":"RIGHT"}'
27+
28+
}
29+
30+
function get_vale_errors {
31+
echo "Getting the Vale errors and PR comments and filtering out existing comments..."
32+
local vale_json="$1"
33+
local pull_comments_json="$2"
34+
35+
# jq map and filter to retain only Vale alerts that don't already have a corresponding review comment on the PR
36+
updated_vale_json=$(jq -n --argjson vale "$vale_json" --argjson comments "$pull_comments_json" '$vale | map(select(. as $v | $comments | any(.path == $v.path and .line == $v.line and .body == $v.body) | not))' | jq)
37+
38+
export updated_vale_json
39+
40+
}
41+
42+
# Run vale with the custom template on updated files and determine if a review comment should be posted
43+
for FILE in ${FILES};
44+
do
45+
# Check if Vale should use the modules config or the root config. Ensures correct rule enabling/disabling
46+
if [[ $FILE == modules/* ]]; then
47+
INI="modules/.vale.ini"
48+
else
49+
INI=".vale.ini"
50+
fi
51+
52+
# Update conditional markup in place
53+
sed -i 's/ifdef::.*/ifdef::temp-ifdef[]/; s/ifeval::.*/ifeval::["{temp-ifeval}" == "temp"]/; s/ifndef::.*/ifndef::temp-ifndef[]/; s/endif::.*/endif::[]/;' "$FILE"
54+
55+
# Parse for vale errors
56+
vale_json=$(vale --minAlertLevel=error --output=.vale/templates/bot-comment-output.tmpl --config="$INI" "$FILE" | jq)
57+
58+
# Check if there are Vale errors before processing the file further.
59+
if [[ "$vale_json" != "[]" ]]; then
60+
echo "Vale errors found in the file..."
61+
62+
#Check if Vale review comments already exist in the PR
63+
pull_comments_json=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $GITHUB_AUTH_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/openshift/openshift-docs/pulls/$PULL_NUMBER/comments | jq)
64+
65+
# If there are existing comments in the response, compare with Vale errors, otherwise proceed with existing Vale errors
66+
if [[ "$pull_comments_json" != "[]" ]]; then
67+
get_vale_errors "$vale_json" "$pull_comments_json"
68+
else
69+
echo "No existing comments found..."
70+
updated_vale_json="$vale_json"
71+
fi
72+
else
73+
echo "No Vale errors found in the file, moving to next file..."
74+
continue # move to next file
75+
fi
76+
77+
# Following logic checks if the line number is a part of the git diff. If it's not part of the diff it will be discarded.
78+
# We only want to check new/modified content, plus the GitHub API only accepts comments within the diff for the review comments endpoint.
79+
if [[ "$updated_vale_json" == "[]" ]]; then
80+
echo "All Vale alerts already have existing comments, moving to next file..."
81+
continue # move to next file
82+
else
83+
echo "Checking if Vale alerts without existing comments are part of added or modified content..."
84+
fi
85+
86+
# Iterate through $updated_vale_json and post a comment if required
87+
jq -c '.[]' <<< "$updated_vale_json" | while IFS= read -r object; do
88+
BODY=$(echo "$object" | jq -r '.body')
89+
FILENAME=$(echo "$object" | jq -r '.path')
90+
LINE_NUMBER=$(echo "$object" | jq -r '.line')
91+
92+
# Check the unified file diff for the alert and file
93+
file_diff=$(git diff --unified=0 --stat --diff-filter=AM HEAD~1 HEAD "${FILENAME}" ':(exclude)_unused_topics/*')
94+
95+
# Iterate through each line to find the line diff info and check if the alert is in the diff
96+
while read -r line; do
97+
# Check if the line contains the hunk beginning with @@
98+
if [[ $line =~ @@ ]]; then
99+
100+
# Valid:
101+
# @@ -35 +31 @@
102+
# @@ -35 +31,5 @@
103+
104+
# Check if there is a comma in the number pairing before @@
105+
if [[ $line =~ \+.*\,.*\ @@ ]]; then
106+
# There are comma separated numbers before closing @@. Grab the number before the comma as the diff_start_line, after the comma is the added_lines.
107+
added_lines=$(echo "$line" | grep -oP '\d+\s+@@' | grep -oP '\d+')
108+
diff_start_line=$(echo "$line" | awk -F'+' '{print $2}' | awk -F',' '{print $1}')
109+
else
110+
# There are no comma seperated numbers. Consider the number after the plus as diff_start_line with no added lines - this means there's a modification on a single line
111+
added_lines=0
112+
diff_start_line=$(echo "$line" | grep -oP '\+\d+\s+@@' | grep -oP '\d+')
113+
fi
114+
115+
# If the last_number is 0, disregard the hunk and move to the next hunk as zero lines were modified (deletions only)
116+
if [ "$diff_start_line" -eq 0 ]; then
117+
continue
118+
fi
119+
120+
# Check if the LINE_NUMBER falls within the range (diff_start_line) to (diff_start_line + added_lines)
121+
if (( LINE_NUMBER >= diff_start_line && LINE_NUMBER <= diff_start_line + added_lines )); then
122+
123+
post_review_comment "$BODY" "$FILENAME" "$LINE_NUMBER"
124+
125+
break # Exit the loop since the alert is within the diff, move on to the next JSON object
126+
else
127+
echo "Vale error alert not part of the file's added/modified content..."
128+
fi
129+
fi
130+
131+
done <<< "$file_diff"
132+
133+
done
134+
135+
done

0 commit comments

Comments
 (0)