mirror of
https://github.com/openshift/openshift-docs.git
synced 2026-02-05 12:46:18 +01:00
135 lines
6.9 KiB
Bash
Executable File
135 lines
6.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# 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
|
|
# for GitHub review comment API. Also checks if a commment already exists before posting.
|
|
# To test locally, create a Github personal access token and export a $GITHUB_AUTH_TOKEN environmental variable to use the token
|
|
|
|
# Check if jq is installed
|
|
hash jq 2>/dev/null || { echo >&2 "Error: jq is not installed"; exit 1; }
|
|
|
|
# Set $PULL_NUMBER and $COMMIT_ID for local testing. Otherwise use variables passed by Prow
|
|
if [ $# -eq 0 ]; then
|
|
COMMIT_ID=$(git log -n 1 --pretty=format:"%H")
|
|
PULL_NUMBER=$(curl -s "https://api.github.com/search/issues?q=$COMMIT_ID" | jq '.items[0].number')
|
|
else
|
|
PULL_NUMBER=$1
|
|
COMMIT_ID=$2
|
|
fi
|
|
|
|
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')
|
|
|
|
function post_review_comment {
|
|
|
|
LINE_NUMBER=$3
|
|
BODY=$1
|
|
FILENAME=$2
|
|
echo "Sending review comment curl request..."
|
|
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"}'
|
|
|
|
}
|
|
|
|
function get_vale_errors {
|
|
echo "Getting the Vale errors and PR comments and filtering out existing comments..."
|
|
local vale_json="$1"
|
|
local pull_comments_json="$2"
|
|
|
|
# jq map and filter to retain only Vale alerts that don't already have a corresponding review comment on the PR
|
|
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)
|
|
|
|
export updated_vale_json
|
|
|
|
}
|
|
|
|
# Run vale with the custom template on updated files and determine if a review comment should be posted
|
|
for FILE in ${FILES};
|
|
do
|
|
# Check if Vale should use the modules config or the root config. Ensures correct rule enabling/disabling
|
|
if [[ $FILE == modules/* ]]; then
|
|
INI="modules/.vale.ini"
|
|
else
|
|
INI=".vale.ini"
|
|
fi
|
|
|
|
# Update conditional markup in place
|
|
sed -i 's/ifdef::.*/ifdef::temp-ifdef[]/; s/ifeval::.*/ifeval::["{temp-ifeval}" == "temp"]/; s/ifndef::.*/ifndef::temp-ifndef[]/; s/endif::.*/endif::[]/;' "$FILE"
|
|
|
|
# Parse for vale errors
|
|
vale_json=$(vale --minAlertLevel=error --output=.vale/templates/bot-comment-output.tmpl --config="$INI" "$FILE" | jq)
|
|
|
|
# Check if there are Vale errors before processing the file further.
|
|
if [[ "$vale_json" != "[]" ]]; then
|
|
echo "Vale errors found in the file..."
|
|
|
|
#Check if Vale review comments already exist in the PR
|
|
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)
|
|
|
|
# If there are existing comments in the response, compare with Vale errors, otherwise proceed with existing Vale errors
|
|
if [[ "$pull_comments_json" != "[]" ]]; then
|
|
get_vale_errors "$vale_json" "$pull_comments_json"
|
|
else
|
|
echo "No existing comments found..."
|
|
updated_vale_json="$vale_json"
|
|
fi
|
|
else
|
|
echo "No Vale errors found in the file, moving to next file..."
|
|
continue # move to next file
|
|
fi
|
|
|
|
# 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.
|
|
# We only want to check new/modified content, plus the GitHub API only accepts comments within the diff for the review comments endpoint.
|
|
if [[ "$updated_vale_json" == "[]" ]]; then
|
|
echo "All Vale alerts already have existing comments, moving to next file..."
|
|
continue # move to next file
|
|
else
|
|
echo "Checking if Vale alerts without existing comments are part of added or modified content..."
|
|
fi
|
|
|
|
# Iterate through $updated_vale_json and post a comment if required
|
|
jq -c '.[]' <<< "$updated_vale_json" | while IFS= read -r object; do
|
|
BODY=$(echo "$object" | jq -r '.body')
|
|
FILENAME=$(echo "$object" | jq -r '.path')
|
|
LINE_NUMBER=$(echo "$object" | jq -r '.line')
|
|
|
|
# Check the unified file diff for the alert and file
|
|
file_diff=$(git diff --unified=0 --stat --diff-filter=AM HEAD~1 HEAD "${FILENAME}" ':(exclude)_unused_topics/*')
|
|
|
|
# Iterate through each line to find the line diff info and check if the alert is in the diff
|
|
while read -r line; do
|
|
# Check if the line contains the hunk beginning with @@
|
|
if [[ $line =~ @@ ]]; then
|
|
|
|
# Valid:
|
|
# @@ -35 +31 @@
|
|
# @@ -35 +31,5 @@
|
|
|
|
# Check if there is a comma in the number pairing before @@
|
|
if [[ $line =~ \+.*\,.*\ @@ ]]; then
|
|
# 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.
|
|
added_lines=$(echo "$line" | grep -oP '\d+\s+@@' | grep -oP '\d+')
|
|
diff_start_line=$(echo "$line" | awk -F'+' '{print $2}' | awk -F',' '{print $1}')
|
|
else
|
|
# 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
|
|
added_lines=0
|
|
diff_start_line=$(echo "$line" | grep -oP '\+\d+\s+@@' | grep -oP '\d+')
|
|
fi
|
|
|
|
# If the last_number is 0, disregard the hunk and move to the next hunk as zero lines were modified (deletions only)
|
|
if [ "$diff_start_line" -eq 0 ]; then
|
|
continue
|
|
fi
|
|
|
|
# Check if the LINE_NUMBER falls within the range (diff_start_line) to (diff_start_line + added_lines)
|
|
if (( LINE_NUMBER >= diff_start_line && LINE_NUMBER <= diff_start_line + added_lines )); then
|
|
|
|
post_review_comment "$BODY" "$FILENAME" "$LINE_NUMBER"
|
|
|
|
break # Exit the loop since the alert is within the diff, move on to the next JSON object
|
|
else
|
|
echo "Vale error alert not part of the file's added/modified content..."
|
|
fi
|
|
fi
|
|
|
|
done <<< "$file_diff"
|
|
|
|
done
|
|
|
|
done |