Skip to content

Commit

Permalink
Script upgrades and updated CONTRIBUTING.md and README.md (#576)
Browse files Browse the repository at this point in the history
* Updated README and CONTRIBUTING

* Added check for devicon object when peeking

* Added PR template

* Added a script to create release messages

* Updated CONTRIBUTING about new script

* Update .github/PULL_REQUEST_TEMPLATE/new_icon.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/scripts/build_assets/arg_getters.py

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/workflows/get_release_message.yml

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update gulpfile.js

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Added a way for peek bot to comment error

* Update CONTRIBUTING.md

Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com>

* Update .github/scripts/get_release_message.py

Co-authored-by: Malte Jürgens <maltejur@web.de>

* Update .github/scripts/get_release_message.py

Co-authored-by: Malte Jürgens <maltejur@web.de>

* Update .github/PULL_REQUEST_TEMPLATE/new_feature.md

Co-authored-by: David Leal <halfpacho@gmail.com>

* Clean up and updated CONTRIBUTING

* Updated CONTRIBUTING

* Add set up steps for release message workflow

* Refactored peek workflow

* Added requests library

* Reformat devicon object error messages

Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com>
Co-authored-by: Malte Jürgens <maltejur@web.de>
  • Loading branch information
4 people committed Apr 29, 2021
1 parent be0f017 commit 41790e6
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 82 deletions.
9 changes: 9 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/new_feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## This PR adds...

*List your features here and their reasons for creation.*

## Notes

*List anything note-worthy here (potential issues, this needs merge to `master` before working, etc....).*

*Don't forget to link any issues that this PR will solved.*
9 changes: 9 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/new_icon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**Double check these details before you open a PR**

- [] PR does not match another non-stale PR currently opened
- [] PR name matches the format *new icon: <i>Icon name</i> (<i>versions separated by comma</i>)* as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#overview)
- [] Your icons are put in a folder as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#organizational-guidelines)
- [] SVG matches the standards laid out [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#svgStandards)
- [] A new object is added in the `devicon.json` file as seen [here](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#-updating-the-deviconjson-)

Refer to the [`CONTRIBUTING.md`](https://github.com/devicons/devicon/blob/develop/CONTRIBUTING.md#contributing-to-devicon) for more details.
37 changes: 0 additions & 37 deletions .github/drafts/check_devicon_object.py

This file was deleted.

13 changes: 12 additions & 1 deletion .github/scripts/build_assets/arg_getters.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,15 @@ def get_check_svgs_monthly_args():
parser.add_argument("icons_folder_path",
help="The path to the icons folder",
action=PathResolverAction)
return parser.parse_args()
return parser.parse_args()


def get_release_message_args():
"""
Get the commandline arguments for get_release_message.py.
"""
parser = ArgumentParser(description="Create a text containing the icons and features added since last release.")
parser.add_argument("token",
help="The GitHub token to access the GitHub REST API.",
type=str)
return parser.parse_args()
75 changes: 75 additions & 0 deletions .github/scripts/get_release_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import requests
from build_assets import arg_getters
import re

def main():
print("Please wait a few seconds...")
args = arg_getters.get_release_message_args()
queryPath = "https://api.github.com/repos/devicons/devicon/pulls?accept=application/vnd.github.v3+json&state=closed&per_page=100"
stopPattern = r"^(r|R)elease v"
headers = {
"Authorization": f"token {args.token}"
}

response = requests.get(queryPath, headers=headers)
if not response:
print(f"Can't query the GitHub API. Status code is {response.status_code}. Message is {response.text}")
return

data = response.json()
newIcons = []
features = []

for pullData in data:
if re.search(stopPattern, pullData["title"]):
break

authors = findAllAuthors(pullData, headers)
markdown = f"- [{pullData['title']}]({pullData['html_url']}) by {authors}."

if isFeatureIcon(pullData):
newIcons.append(markdown)
else:
features.append(markdown)

thankYou = "A huge thanks to all our maintainers and contributors for making this release possible!"
iconTitle = "**{} New Icons**\n".format(len(newIcons))
featureTitle = "**{} New Features**\n".format(len(features))
finalString = "{0}\n\n {1}{2}\n\n {3}{4}".format(thankYou,
iconTitle, "\n".join(newIcons), featureTitle, "\n".join(features))

print("--------------Here is the build message--------------\n", finalString)


"""
Check whether the pullData is a feature:icon PR.
:param pullData
:return true if the pullData has a label named "feature:icon"
"""
def isFeatureIcon(pullData):
for label in pullData["labels"]:
if label["name"] == "feature:icon":
return True
return False


"""
Find all the authors of a PR based on its commits.
:param pullData - the data of a pull request.
"""
def findAllAuthors(pullData, authHeader):
response = requests.get(pullData["commits_url"], headers=authHeader)
if not response:
print(f"Can't query the GitHub API. Status code is {response.status_code}")
print("Response is: ", response.text)
return

commits = response.json()
authors = set() # want unique authors only
for commit in commits:
authors.add("@" + commit["author"]["login"])
return ", ".join(list(authors))


if __name__ == "__main__":
main()
103 changes: 76 additions & 27 deletions .github/scripts/icomoon_peek.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import re
import sys
from selenium.common.exceptions import TimeoutException
import xml.etree.ElementTree as et

# pycharm complains that build_assets is an unresolved ref
# don't worry about it, the script still runs
Expand All @@ -12,36 +11,28 @@


def main():
args = arg_getters.get_selenium_runner_args(True)
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)

# get only the icon object that has the name matching the pr title
filtered_icons = find_object_added_in_this_pr(new_icons, args.pr_title)

if len(new_icons) == 0:
sys.exit("No files need to be uploaded. Ending script...")
runner = None
try:
args = arg_getters.get_selenium_runner_args(True)
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)

if len(filtered_icons) == 0:
message = "No icons found matching the icon name in the PR's title.\n" \
"Ensure that a new icon entry is added in the devicon.json and the PR title matches the convention here: \n" \
"https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#overview\n" \
"Ending script...\n"
sys.exit(message)
if len(new_icons) == 0:
raise Exception("No files need to be uploaded. Ending script...")

# print list of new icons
print("List of new icons:", *new_icons, sep = "\n")
print("Icons being uploaded:", *filtered_icons, sep = "\n", end='\n\n')
# get only the icon object that has the name matching the pr title
filtered_icon = find_object_added_in_this_pr(new_icons, args.pr_title)
print("Icon being checked:", filtered_icon, sep = "\n", end='\n\n')

runner = None
try:
runner = SeleniumRunner(args.download_path, args.geckodriver_path, args.headless)
svgs = filehandler.get_svgs_paths(filtered_icons, args.icons_folder_path, True)
svgs = filehandler.get_svgs_paths([filtered_icon], args.icons_folder_path, True)
screenshot_folder = filehandler.create_screenshot_folder("./")
runner.upload_svgs(svgs, screenshot_folder)
print("Task completed.")
except TimeoutException as e:
util.exit_with_err("Selenium Time Out Error: \n" + str(e))

# no errors, do this so upload-artifact won't fail
filehandler.write_to_file("./err_messages.txt", "0")
except Exception as e:
filehandler.write_to_file("./err_messages.txt", str(e))
util.exit_with_err(e)
finally:
runner.close()
Expand All @@ -52,19 +43,77 @@ def find_object_added_in_this_pr(icons: List[dict], pr_title: str):
Find the icon name from the PR title.
:param icons, a list of the font objects found in the devicon.json.
:pr_title, the title of the PR that this workflow was called on.
:return a list containing the dictionary with the "name"
:return a dictionary with the "name"
entry's value matching the name in the pr_title.
If none can be found, return an empty list.
:raise If no object can be found, raise an Exception.
"""
try:
pattern = re.compile(r"(?<=^new icon: )\w+ (?=\(.+\))", re.I)
icon_name = pattern.findall(pr_title)[0].lower().strip() # should only have one match
return [icon for icon in icons if icon["name"] == icon_name]
icon = [icon for icon in icons if icon["name"] == icon_name][0]
check_devicon_object(icon, icon_name)
return icon
except IndexError: # there are no match in the findall()
return []
raise Exception("Couldn't find an icon matching the name in the PR title.")
except ValueError as e:
raise Exception(str(e))


def check_devicon_object(icon: dict, icon_name: str):
"""
Check that the devicon object added is up to standard.
:return a string containing the error messages if any.
"""
err_msgs = []
try:
if icon["name"] != icon_name:
err_msgs.append("- 'name' value is not: " + icon_name)
except KeyError:
err_msgs.append("- missing key: 'name'.")

try:
for tag in icon["tags"]:
if type(tag) != str:
raise TypeError()
except TypeError:
err_msgs.append("- 'tags' must be an array of strings, not: " + str(icon["tags"]))
except KeyError:
err_msgs.append("- missing key: 'tags'.")

try:
if type(icon["versions"]) != dict:
err_msgs.append("- 'versions' must be an object.")
except KeyError:
err_msgs.append("- missing key: 'versions'.")

try:
if type(icon["versions"]["svg"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("- must contain at least 1 svg version in a list.")
except KeyError:
err_msgs.append("- missing key: 'svg' in 'versions'.")

try:
if type(icon["versions"]["font"]) != list or len(icon["versions"]["svg"]) == 0:
err_msgs.append("- must contain at least 1 font version in a list.")
except KeyError:
err_msgs.append("- missing key: 'font' in 'versions'.")

try:
if type(icon["color"]) != str or "#" not in icon["color"]:
err_msgs.append("- 'color' must be a string in the format '#abcdef'")
except KeyError:
err_msgs.append("- missing key: 'color'.")

try:
if type(icon["aliases"]) != list:
err_msgs.append("- 'aliases' must be an array.")
except KeyError:
err_msgs.append("- missing key: 'aliases'.")

if len(err_msgs) > 0:
message = "Error found in 'devicon.json' for '{}' entry: \n{}".format(icon_name, "\n".join(err_msgs))
raise ValueError(message)
return ""

if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion .github/scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
selenium==3.141.0
selenium==3.141.0
requests==2.25.1
23 changes: 23 additions & 0 deletions .github/workflows/get_release_message.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Get Release Message
on: workflow_dispatch
jobs:
build:
name: Get Fonts From Icomoon
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2

- name: Setup Python v3.8
uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./.github/scripts/requirements.txt
- name: Run the get_release_message.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python ./.github/scripts/get_release_message.py $GITHUB_TOKEN
7 changes: 7 additions & 0 deletions .github/workflows/peek_icons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ jobs:
./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json
./devicon.json ./icons ./ --headless --pr_title "%PR_TITLE%"
- name: Upload the err messages (created by icomoon_peek.py)
uses: actions/upload-artifact@v2
if: always()
with:
name: err_messages
path: ./err_messages.txt

- name: Upload screenshots for comments
uses: actions/upload-artifact@v2
if: success()
Expand Down
20 changes: 16 additions & 4 deletions .github/workflows/post_peek_screenshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ jobs:
with:
path: ./pr_num/pr_num.txt

- name: Read the err message file
if: success()
id: err_message_reader
uses: juliangruber/read-file-action@v1.0.0
with:
path: ./err_messages/err_messages.txt


- name: Upload screenshot of the newly made icons gotten from the artifacts
id: icons_overview_img_step
if: env.PEEK_STATUS == 'success' && success()
Expand Down Expand Up @@ -87,20 +95,24 @@ jobs:
MESSAGE: |
Hi there,
I'm Devicons' Peek Bot and it seems we've ran into a problem (sorry!).
I'm Devicons' Peek Bot and it seems we've ran into a problem.
```
{0}
```
Please double check and fix the possible issues below:
Make sure that:
- Your svgs are named and added correctly to the /icons folder as seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#orgGuidelines).
- Your icon information has been added to the `devicon.json` as seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#updateDevicon)
- Your PR title follows the format seen [here](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#overview)
I will retry once everything is fixed. If I still fail (sorry!) or there are other erros, the maintainers will investigate.
I will retry once everything is fixed. If I still fail or there are other error, the maintainers will investigate.
Best of luck,
Peek Bot :relaxed:
with:
type: create
issue_number: ${{ steps.pr_num_reader.outputs.content }}
token: ${{ secrets.GITHUB_TOKEN }}
body: ${{ env.MESSAGE }}
body: ${{ format(env.MESSAGE, steps.err_message_reader.outputs.content) }}

0 comments on commit 41790e6

Please sign in to comment.