Skip to content

Commit

Permalink
Merge pull request #5 from gaurav-nelson/auto-comments
Browse files Browse the repository at this point in the history
Auto comments
  • Loading branch information
gaurav-nelson authored Aug 22, 2019
2 parents 9b7a2fc + 9eb2cb9 commit 9b9cd51
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/main.workflow
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ workflow "Lint with vale on PR" {

action "vale-lint-PR" {
uses = "./"
secrets = ["GITHUB_TOKEN"]
secrets = ["GH_COMMENT_TOKEN"]
}
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ jobs:
- name: vale-lint-PR
uses: ./
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_COMMENT_TOKEN: ${{ secrets.GH_COMMENT_TOKEN }}
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM jdkato/vale
RUN apk add --no-cache bash git
RUN apk add --no-cache bash git jq python3 curl && pip3 install requests
LABEL "com.github.actions.name"="vale-lint"
LABEL "com.github.actions.description"="Vale - linter for prose "
LABEL "com.github.actions.icon"="check-circle"
Expand All @@ -8,5 +8,7 @@ LABEL "repository"="https://github.com/gaurav-nelson/github-action-vale-lint.git
LABEL "homepage"="https://github.com/gaurav-nelson/github-action-vale-lint"
LABEL "maintainer"="Gaurav Nelson"
ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY /post_message.py /post_message.py
RUN chmod u+x /entrypoint.sh && \
chmod u+x /post_message.py
ENTRYPOINT ["/entrypoint.sh"]
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,29 @@ The `github-action-vale-lint` checks all modified text (including markup) files
## Prerequisite
You must have [Vale configuration file](https://errata-ai.github.io/vale/config/) `.vale.ini` in your repository.

## Workflow action
## Workflow file
Sample workflow file `pull_request.yml`:

![Lint with Vale on PR](https://raw.githubusercontent.com/gaurav-nelson/github-action-vale-lint/master/images/lint-with-vale-on-pr.png)

```
workflow "Lint with vale on PR" {
on = "pull_request"
resolves = ["vale-lint-PR"]
}
action "vale-lint-PR" {
uses = "./"
}
on: pull_request
name: Lint with vale on PR
jobs:
vale-lint-PR:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: vale-lint-PR
uses: ./
env:
GH_COMMENT_TOKEN: ${{ secrets.GH_COMMENT_TOKEN }}
```

## Add Vale errors as comments on PR

In your repository:
1. Go to **Settings** > **Secrets**, and slect **Add a new secret**.
1. Enter **GH_COMMENT_TOKEN** for **Name**, and enter your secret token as
**Value**.
1. Select **Add secret**.
108 changes: 102 additions & 6 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,80 @@
touch output.txt
touch ignored.txt

MASTER_HASH=$(git rev-parse origin/master)
NC='\033[0m' # No Color
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'

MASTER_HASH=$(git rev-parse origin/master)
EXTENSION_ARRAY=(.md .adoc .rst .txt)

# ---- For PR comments START ----

## set variables
API_VERSION=v3
BASE=https://api.github.com
AUTH_HEADER="Authorization: token ${GH_COMMENT_TOKEN}"
HEADER="Accept: application/vnd.github.${API_VERSION}+json;"
## required for Checks API https://developer.github.com/v3/checks/runs/
HEADER="${HEADER}; application/vnd.github.antiope-preview+json"

## URLs
REPO_URL="${BASE}/repos/${GITHUB_REPOSITORY}"

check_events_json() {
echo -e "${YELLOW}==== CHECKING EVENTS FILE ====${NC}"
if [[ ! -f "${GITHUB_EVENT_PATH}" ]]; then
echo -e "${RED}Cannot find Github events file at ${GITHUB_EVENT_PATH}${NC}";
exit 1;
fi
echo -e "${GREEN}Found ${GITHUB_EVENT_PATH}${NC}";
}

## Delete previous comments containing errors
clean_up() {
echo -e "${YELLOW}==== CHECKING PREVIOUS FAILED COMMENTS ====${NC}"
COMMENTS_URL="${REPO_URL}/issues/${NUMBER}/comments"
# Store comments id, url, and body
COMMENT_ID_TO_DELETE=$(curl "${COMMENTS_URL}" | jq '.[] | {id: .id, body: .body}' | jq -r '. | select(.body|test(":red_circle: Vale lint errors:.")) | .id')

if [ -z "$COMMENT_ID_TO_DELETE" ]
then
echo -e "${GREEN}No previous failed comment.${NC}"
else
echo -e "${GREEN}Deleting old comment ID: $COMMENT_ID_TO_DELETE${NC}"
curl -sSL -H "${AUTH_HEADER}" -H "${HEADER}" -X DELETE "${REPO_URL}/issues/comments/${COMMENT_ID_TO_DELETE}"
fi
}

## Function to post comments to the PR
post_message() {
ERROR_FILE="output.txt"
NO_ERROR="0 errors, 0 warnings and 0 suggestions"
if grep -qF "$NO_ERROR" output.txt
then
# if found
clean_up
else
# if not found
# Comment with Python
echo -e "${YELLOW}==== ADDING FAIL COMMENT ====${NC}"
export AUTH_HEADER HEADER COMMENTS_URL API_VERSION GH_COMMENT_TOKEN ERROR_FILE
python3 post_message.py
fi

}

## Function to run if there are errors and a GH_COMMENT_TOKEN exists
main () {
check_events_json;
NUMBER=$(jq --raw-output .number "${GITHUB_EVENT_PATH}");
clean_up;
post_message;
}
# ---- For PR comments END ----

containsElement () {
local e match="$1"
shift
Expand All @@ -19,22 +89,48 @@ mapfile -t FILE_ARRAY < <( git diff --name-only "$MASTER_HASH" )
for i in "${FILE_ARRAY[@]}"
do
if ( containsElement "${i: -3}" "${EXTENSION_ARRAY[@]}" ) || ( containsElement "${i: -4}" "${EXTENSION_ARRAY[@]}" ) || ( containsElement "${i: -5}" "${EXTENSION_ARRAY[@]}" ) ; then
../../vale "${i}" >> output.txt
/vale "${i}" >> output.txt
else
echo "${i}" >> ignored.txt
fi
done

if [ -s output.txt ] ; then
echo "=========================> ERRORS <========================="
echo -e "${YELLOW}=========================> ERRORS <========================="
cat output.txt
echo "============================================================"
echo -e "============================================================${NC}"
if [ -s ignored.txt ] ; then
echo ""
echo "----> IGNORED FILES <----"
echo -e "${YELLOW}----> IGNORED FILES <----${NC}"
cat ignored.txt
echo -e "${YELLOW}-------------------------${NC}"
echo ""
fi
if [[ -z "${GH_COMMENT_TOKEN}" ]]; then
echo -e "${BLUE}NOTE: If you want to add these errors as a comment on the original pull request, add a GH_COMMENT_TOKEN as an environment variable.${NC}"
echo -e "${BLUE}To add a new Secret, go to Repository Settings > Secrets > Add a new secret${NC}"
else
NO_ERROR="0 errors, 0 warnings and 0 suggestions"
if grep -qF "$NO_ERROR" output.txt
then
check_events_json;
NUMBER=$(jq --raw-output .number "${GITHUB_EVENT_PATH}");
clean_up;
exit 0
else
main;
fi
fi
exit 113
else
echo "All good!"
if [[ -z "${GH_COMMENT_TOKEN}" ]]; then
echo -e "${BLUE}NOTE: If you want to add these errors as a comment on the original pull request, add a GH_COMMENT_TOKEN as an environment variable.${NC}"
echo -e "${BLUE}To add a new Secret, go to Repository Settings > Secrets > Add a new secret${NC}"
echo -e "${GREEN}All good!${NC}"
else
check_events_json;
NUMBER=$(jq --raw-output .number "${GITHUB_EVENT_PATH}");
clean_up;
echo -e "${GREEN}All good!${NC}"
fi
fi
55 changes: 55 additions & 0 deletions post_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python

import requests
import json
import sys
import os

# Get all variables from environment

params = dict()

requireds = ['ERROR_FILE',
'COMMENTS_URL',
'AUTH_HEADER',
'HEADER',
'API_VERSION',
'GH_COMMENT_TOKEN']

for required in requireds:

value = os.environ.get(required)
if required == None:
print('Missing environment variable %s' %required)
sys.exit(1)

params[required] = value


infile = params['ERROR_FILE']

if not os.path.exists(infile):
print('Does not exist: %s' %infile)
sys.exit(1)


with open(infile, 'r') as filey:
all_errors = filey.read()

print(all_errors)

# Prepare request
accept = "application/vnd.github.%s+json;application/vnd.github.antiope-preview+json" % params['API_VERSION']
headers = {"Authorization": "token %s" % params['GH_COMMENT_TOKEN'],
"Accept": accept,
"Content-Type": "application/json; charset=utf-8" }

all_errors = ":red_circle: Vale lint errors: \n```\n" + all_errors + "```"
data = {"body": all_errors }
print(data)
print(json.dumps(data).encode('utf-8'))
response = requests.post(params['COMMENTS_URL'],
data = json.dumps(data).encode('utf-8'),
headers = headers)
print(response.json())
print(response.status_code)

0 comments on commit 9b9cd51

Please sign in to comment.