mirror of
https://github.com/konpa/devicon.git
synced 2025-08-14 02:24:04 +02:00
Build bot now build new SVGs in folder that were already built (#666)
* Refactor the pull request fetching code * Refactor build script to use past PRs * Added function to update icomoon json * new icon: matlab (line) (#640) * Add matlab-line * Fixed issues reported by check svg bot * optimisation for svg (#643) Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com> * Add better logging to icomoon_build Co-authored-by: Clemens Bastian <8781699+amacado@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com>
This commit is contained in:
94
.github/scripts/build_assets/api_handler.py
vendored
Normal file
94
.github/scripts/build_assets/api_handler.py
vendored
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
def get_merged_pull_reqs(token, page):
|
||||||
|
"""
|
||||||
|
Get the merged pull requests based on page. There are
|
||||||
|
100 results page. See https://docs.github.com/en/rest/reference/pulls
|
||||||
|
for more details on the parameters.
|
||||||
|
:param token, a GitHub API token.
|
||||||
|
:param page, the page number.
|
||||||
|
"""
|
||||||
|
queryPath = "https://api.github.com/repos/devicons/devicon/pulls"
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"token {token}"
|
||||||
|
}
|
||||||
|
params = {
|
||||||
|
"accept": "application/vnd.github.v3+json",
|
||||||
|
"state": "closed",
|
||||||
|
"per_page": 100,
|
||||||
|
"page": page
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"Querying the GitHub API for requests page #{page}")
|
||||||
|
response = requests.get(queryPath, headers=headers, params=params)
|
||||||
|
if not response:
|
||||||
|
print(f"Can't query the GitHub API. Status code is {response.status_code}. Message is {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
closed_pull_reqs = response.json()
|
||||||
|
return [merged_pull_req
|
||||||
|
for merged_pull_req in closed_pull_reqs
|
||||||
|
if merged_pull_req["merged_at"] is not None]
|
||||||
|
|
||||||
|
|
||||||
|
def is_feature_icon(pull_req_data):
|
||||||
|
"""
|
||||||
|
Check whether the pullData is a feature:icon PR.
|
||||||
|
:param pull_req_data - the data on a specific pull request from GitHub.
|
||||||
|
:return true if the pullData has a label named "feature:icon"
|
||||||
|
"""
|
||||||
|
for label in pull_req_data["labels"]:
|
||||||
|
if label["name"] == "feature:icon":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def find_all_authors(pull_req_data, token):
|
||||||
|
"""
|
||||||
|
Find all the authors of a PR based on its commits.
|
||||||
|
:param pull_req_data - the data on a specific pull request from GitHub.
|
||||||
|
:param token - a GitHub API token.
|
||||||
|
"""
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"token {token}"
|
||||||
|
}
|
||||||
|
response = requests.get(pull_req_data["commits_url"], headers=headers)
|
||||||
|
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["commit"]["author"]["name"])
|
||||||
|
return ", ".join(["@" + author for author in list(authors)])
|
||||||
|
|
||||||
|
|
||||||
|
def get_merged_pull_reqs_since_last_release(token):
|
||||||
|
"""
|
||||||
|
Get all the merged pull requests since the last release.
|
||||||
|
"""
|
||||||
|
stopPattern = r"^(r|R)elease v"
|
||||||
|
pull_reqs = []
|
||||||
|
found_last_release = False
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
print("Getting PRs since last release.")
|
||||||
|
while not found_last_release:
|
||||||
|
data = get_merged_pull_reqs(token, page)
|
||||||
|
# assume we don't encounter it during the loop
|
||||||
|
last_release_index = 101
|
||||||
|
|
||||||
|
for i in range(len(data)):
|
||||||
|
if re.search(stopPattern, data[i]["title"]):
|
||||||
|
found_last_release = True
|
||||||
|
last_release_index = i
|
||||||
|
break
|
||||||
|
pull_reqs.extend(data[:last_release_index])
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
# should contain all the PRs since last release
|
||||||
|
return pull_reqs
|
4
.github/scripts/build_assets/arg_getters.py
vendored
4
.github/scripts/build_assets/arg_getters.py
vendored
@@ -33,6 +33,10 @@ def get_selenium_runner_args(peek_mode=False):
|
|||||||
help="The download destination of the Icomoon files",
|
help="The download destination of the Icomoon files",
|
||||||
action=PathResolverAction)
|
action=PathResolverAction)
|
||||||
|
|
||||||
|
parser.add_argument("token",
|
||||||
|
help="The GitHub token to access the GitHub REST API.",
|
||||||
|
type=str)
|
||||||
|
|
||||||
if peek_mode:
|
if peek_mode:
|
||||||
parser.add_argument("--pr_title",
|
parser.add_argument("--pr_title",
|
||||||
help="The title of the PR that we are peeking at")
|
help="The title of the PR that we are peeking at")
|
||||||
|
20
.github/scripts/build_assets/util.py
vendored
20
.github/scripts/build_assets/util.py
vendored
@@ -1,4 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
from typing import List
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
@@ -42,3 +44,21 @@ def set_env_var(key: str, value: str, delimiter: str='~'):
|
|||||||
os.system(f'echo "{key}={value}" >> $GITHUB_ENV')
|
os.system(f'echo "{key}={value}" >> $GITHUB_ENV')
|
||||||
else:
|
else:
|
||||||
raise Exception("This function doesn't support this platform: " + platform.system())
|
raise Exception("This function doesn't support this platform: " + platform.system())
|
||||||
|
|
||||||
|
|
||||||
|
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 dictionary with the "name"
|
||||||
|
entry's value matching the name in the pr_title.
|
||||||
|
: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
|
||||||
|
icon = [icon for icon in icons if icon["name"] == icon_name][0]
|
||||||
|
return icon
|
||||||
|
except IndexError: # there are no match in the findall()
|
||||||
|
raise Exception("Couldn't find an icon matching the name in the PR title.")
|
||||||
|
88
.github/scripts/get_release_message.py
vendored
88
.github/scripts/get_release_message.py
vendored
@@ -1,74 +1,38 @@
|
|||||||
import requests
|
import requests
|
||||||
from build_assets import arg_getters
|
from build_assets import arg_getters, api_handler, util
|
||||||
import re
|
import re
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print("Please wait a few seconds...")
|
try:
|
||||||
args = arg_getters.get_release_message_args()
|
print("Please wait a few seconds...")
|
||||||
queryPath = "https://api.github.com/repos/devicons/devicon/pulls?accept=application/vnd.github.v3+json&state=closed&per_page=100"
|
args = arg_getters.get_release_message_args()
|
||||||
stopPattern = r"^(r|R)elease v"
|
|
||||||
headers = {
|
|
||||||
"Authorization": f"token {args.token}"
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(queryPath, headers=headers)
|
# fetch first page by default
|
||||||
if not response:
|
data = api_handler.get_merged_pull_reqs_since_last_release(args.token)
|
||||||
print(f"Can't query the GitHub API. Status code is {response.status_code}. Message is {response.text}")
|
newIcons = []
|
||||||
return
|
features = []
|
||||||
|
|
||||||
data = response.json()
|
print("Parsing through the pull requests")
|
||||||
newIcons = []
|
for pullData in data:
|
||||||
features = []
|
authors = api_handler.find_all_authors(pullData, args.token)
|
||||||
|
markdown = f"- [{pullData['title']}]({pullData['html_url']}) by {authors}."
|
||||||
|
|
||||||
for pullData in data:
|
if api_handler.is_feature_icon(pullData):
|
||||||
if re.search(stopPattern, pullData["title"]):
|
newIcons.append(markdown)
|
||||||
break
|
else:
|
||||||
|
features.append(markdown)
|
||||||
|
|
||||||
authors = findAllAuthors(pullData, headers)
|
print("Constructing message")
|
||||||
markdown = f"- [{pullData['title']}]({pullData['html_url']}) by {authors}."
|
thankYou = "A huge thanks to all our maintainers and contributors for making this release possible!"
|
||||||
|
iconTitle = f"**{len(newIcons)} New Icons**"
|
||||||
|
featureTitle = f"**{len(features)} New Features**"
|
||||||
|
finalString = "{0}\n\n {1}\n{2}\n\n {3}\n{4}".format(thankYou,
|
||||||
|
iconTitle, "\n".join(newIcons), featureTitle, "\n".join(features))
|
||||||
|
|
||||||
if isFeatureIcon(pullData):
|
print("--------------Here is the build message--------------\n", finalString)
|
||||||
newIcons.append(markdown)
|
print("Script finished")
|
||||||
else:
|
except Exception as e:
|
||||||
features.append(markdown)
|
util.exit_with_err(e)
|
||||||
|
|
||||||
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__":
|
if __name__ == "__main__":
|
||||||
|
112
.github/scripts/icomoon_build.py
vendored
112
.github/scripts/icomoon_build.py
vendored
@@ -1,36 +1,36 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
from selenium.common.exceptions import TimeoutException
|
from selenium.common.exceptions import TimeoutException
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
|
||||||
# pycharm complains that build_assets is an unresolved ref
|
# pycharm complains that build_assets is an unresolved ref
|
||||||
# don't worry about it, the script still runs
|
# don't worry about it, the script still runs
|
||||||
from build_assets.SeleniumRunner import SeleniumRunner
|
from build_assets.SeleniumRunner import SeleniumRunner
|
||||||
from build_assets import filehandler, arg_getters
|
from build_assets import filehandler, arg_getters, util, api_handler
|
||||||
from build_assets import util
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = arg_getters.get_selenium_runner_args()
|
"""
|
||||||
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)
|
Build the icons using Icomoon. Also optimize the svgs.
|
||||||
if len(new_icons) == 0:
|
"""
|
||||||
sys.exit("No files need to be uploaded. Ending script...")
|
|
||||||
|
|
||||||
# print list of new icons
|
|
||||||
print("List of new icons:", *new_icons, sep = "\n")
|
|
||||||
|
|
||||||
runner = None
|
runner = None
|
||||||
try:
|
try:
|
||||||
svgs = filehandler.get_svgs_paths(new_icons, args.icons_folder_path, icon_versions_only=False)
|
args = arg_getters.get_selenium_runner_args()
|
||||||
# optimizes the files
|
new_icons = get_icons_for_building(args.devicon_json_path, args.token)
|
||||||
# do in each batch in case the command
|
if len(new_icons) == 0:
|
||||||
# line complains there's too many characters
|
sys.exit("No files need to be uploaded. Ending script...")
|
||||||
start = 0
|
|
||||||
step = 10
|
print(f"There are {len(new_icons)} icons to be build. Here are they:", *new_icons, sep = "\n")
|
||||||
for i in range(start, len(svgs), step):
|
|
||||||
batch = svgs[i:i + step]
|
print("Begin optimizing files")
|
||||||
subprocess.run(["npm", "run", "optimize-svg", "--", f"--svgFiles={json.dumps(batch)}"], shell=True)
|
optimize_svgs(new_icons, args.icons_folder_path)
|
||||||
|
|
||||||
|
print("Updating the icomoon json")
|
||||||
|
update_icomoon_json(new_icons, args.icomoon_json_path)
|
||||||
|
|
||||||
icon_svgs = filehandler.get_svgs_paths(
|
icon_svgs = filehandler.get_svgs_paths(
|
||||||
new_icons, args.icons_folder_path, icon_versions_only=True)
|
new_icons, args.icons_folder_path, icon_versions_only=True)
|
||||||
@@ -50,7 +50,79 @@ def main():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
util.exit_with_err(e)
|
util.exit_with_err(e)
|
||||||
finally:
|
finally:
|
||||||
runner.close()
|
if runner is not None:
|
||||||
|
runner.close()
|
||||||
|
|
||||||
|
|
||||||
|
def get_icons_for_building(devicon_json_path: str, token: str):
|
||||||
|
"""
|
||||||
|
Get the icons for building.
|
||||||
|
:param devicon_json_path - the path to the `devicon.json`.
|
||||||
|
:param token - the token to access the GitHub API.
|
||||||
|
"""
|
||||||
|
all_icons = filehandler.get_json_file_content(devicon_json_path)
|
||||||
|
pull_reqs = api_handler.get_merged_pull_reqs_since_last_release(token)
|
||||||
|
new_icons = []
|
||||||
|
|
||||||
|
for pull_req in pull_reqs:
|
||||||
|
if api_handler.is_feature_icon(pull_req):
|
||||||
|
filtered_icon = util.find_object_added_in_this_pr(all_icons, pull_req["title"])
|
||||||
|
new_icons.append(filtered_icon)
|
||||||
|
return new_icons
|
||||||
|
|
||||||
|
|
||||||
|
def optimize_svgs(new_icons: List[str], icons_folder_path: str):
|
||||||
|
"""
|
||||||
|
Optimize the newly added svgs. This is done in batches
|
||||||
|
since the command line has a limit on characters allowed.
|
||||||
|
:param new_icons - the new icons that need to be optimized.
|
||||||
|
:param icons_folder_path - the path to the /icons folder.
|
||||||
|
"""
|
||||||
|
svgs = filehandler.get_svgs_paths(new_icons, icons_folder_path, icon_versions_only=False)
|
||||||
|
start = 0
|
||||||
|
step = 10
|
||||||
|
for i in range(start, len(svgs), step):
|
||||||
|
batch = svgs[i:i + step]
|
||||||
|
subprocess.run(["npm", "run", "optimize-svg", "--", f"--svgFiles={json.dumps(batch)}"], shell=True)
|
||||||
|
|
||||||
|
|
||||||
|
def update_icomoon_json(new_icons: List[str], icomoon_json_path: str):
|
||||||
|
"""
|
||||||
|
Update the `icomoon.json` if it contains any icons
|
||||||
|
that needed to be updated. This will remove the icons
|
||||||
|
from the `icomoon.json` so the build script will reupload
|
||||||
|
it later.
|
||||||
|
"""
|
||||||
|
icomoon_json = filehandler.get_json_file_content(icomoon_json_path)
|
||||||
|
cur_len = len(icomoon_json["icons"])
|
||||||
|
messages = []
|
||||||
|
|
||||||
|
wrapper_function = lambda icomoon_icon : find_icomoon_icon_not_in_new_icons(
|
||||||
|
icomoon_icon, new_icons, messages)
|
||||||
|
icons_to_keep = filter(wrapper_function, icomoon_json["icons"])
|
||||||
|
icomoon_json["icons"] = list(icons_to_keep)
|
||||||
|
|
||||||
|
new_len = len(icomoon_json["icons"])
|
||||||
|
print(f"Update completed. Removed {cur_len - new_len} icons:", *messages, sep='\n')
|
||||||
|
filehandler.write_to_file(icomoon_json_path, json.dumps(icomoon_json))
|
||||||
|
|
||||||
|
|
||||||
|
def find_icomoon_icon_not_in_new_icons(icomoon_icon: Dict, new_icons: List, messages: List):
|
||||||
|
"""
|
||||||
|
Find all the icomoon icons that are not listed in the new icons.
|
||||||
|
This also add logging for which icons were removed.
|
||||||
|
:param icomoon_icon - a dict object from the icomoon.json's `icons` attribute.
|
||||||
|
:param new_icons - a list of new icons. Each element is an object from the `devicon.json`.
|
||||||
|
:param messages - an empty list where the function can attach logging on which
|
||||||
|
icon were removed.
|
||||||
|
"""
|
||||||
|
for new_icon in new_icons:
|
||||||
|
pattern = re.compile(f"^{new_icon['name']}-")
|
||||||
|
if pattern.search(icomoon_icon["properties"]["name"]):
|
||||||
|
message = f"-'{icomoon_icon['properties']['name']}' cause it matches '{new_icon['name']}'"
|
||||||
|
messages.append(message)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
35
.github/scripts/icomoon_peek.py
vendored
35
.github/scripts/icomoon_peek.py
vendored
@@ -17,7 +17,8 @@ def main():
|
|||||||
new_icons = filehandler.get_json_file_content(args.devicon_json_path)
|
new_icons = filehandler.get_json_file_content(args.devicon_json_path)
|
||||||
|
|
||||||
# get only the icon object that has the name matching the pr title
|
# 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)
|
filtered_icon = util.find_object_added_in_this_pr(new_icons, args.pr_title)
|
||||||
|
check_devicon_object(filtered_icon)
|
||||||
print("Icon being checked:", filtered_icon, sep = "\n", end='\n\n')
|
print("Icon being checked:", filtered_icon, sep = "\n", end='\n\n')
|
||||||
|
|
||||||
runner = SeleniumRunner(args.download_path, args.geckodriver_path, args.headless)
|
runner = SeleniumRunner(args.download_path, args.geckodriver_path, args.headless)
|
||||||
@@ -35,39 +36,12 @@ def main():
|
|||||||
runner.close()
|
runner.close()
|
||||||
|
|
||||||
|
|
||||||
def find_object_added_in_this_pr(icons: List[dict], pr_title: str):
|
def check_devicon_object(icon: dict):
|
||||||
"""
|
|
||||||
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 dictionary with the "name"
|
|
||||||
entry's value matching the name in the pr_title.
|
|
||||||
: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
|
|
||||||
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()
|
|
||||||
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.
|
Check that the devicon object added is up to standard.
|
||||||
:return a string containing the error messages if any.
|
:return a string containing the error messages if any.
|
||||||
"""
|
"""
|
||||||
err_msgs = []
|
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:
|
try:
|
||||||
for tag in icon["tags"]:
|
for tag in icon["tags"]:
|
||||||
if type(tag) != str:
|
if type(tag) != str:
|
||||||
@@ -108,9 +82,10 @@ def check_devicon_object(icon: dict, icon_name: str):
|
|||||||
err_msgs.append("- missing key: 'aliases'.")
|
err_msgs.append("- missing key: 'aliases'.")
|
||||||
|
|
||||||
if len(err_msgs) > 0:
|
if len(err_msgs) > 0:
|
||||||
message = "Error found in 'devicon.json' for '{}' entry: \n{}".format(icon_name, "\n".join(err_msgs))
|
message = "Error found in 'devicon.json' for '{}' entry: \n{}".format(icon["name"], "\n".join(err_msgs))
|
||||||
raise ValueError(message)
|
raise ValueError(message)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
5
.github/workflows/build_icons.yml
vendored
5
.github/workflows/build_icons.yml
vendored
@@ -18,10 +18,13 @@ jobs:
|
|||||||
npm install
|
npm install
|
||||||
|
|
||||||
- name: Executing build and create fonts via icomoon
|
- name: Executing build and create fonts via icomoon
|
||||||
|
shell: cmd
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: >
|
run: >
|
||||||
python ./.github/scripts/icomoon_build.py
|
python ./.github/scripts/icomoon_build.py
|
||||||
./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json
|
./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe ./icomoon.json
|
||||||
./devicon.json ./icons ./ --headless
|
./devicon.json ./icons ./ %GITHUB_TOKEN% --headless
|
||||||
|
|
||||||
- name: Upload geckodriver.log for debugging purposes
|
- name: Upload geckodriver.log for debugging purposes
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
|
@@ -468,6 +468,6 @@ We are running a Discord server. You can go here to talk, discuss, and more with
|
|||||||
<li>Wait for review and approval of the pull request (you can perform a squash-merge)</li>
|
<li>Wait for review and approval of the pull request (you can perform a squash-merge)</li>
|
||||||
<li>Once merged create a pull request with BASE <code>master</code> and HEAD <code>development</code>. Copy the description of the earlier pull request.</li>
|
<li>Once merged create a pull request with BASE <code>master</code> and HEAD <code>development</code>. Copy the description of the earlier pull request.</li>
|
||||||
<li>Since it was already approved in the 'development' stage a maintainer is allowed to merge it (<b>DON'T</b> perform a squash-merge).</li>
|
<li>Since it was already approved in the 'development' stage a maintainer is allowed to merge it (<b>DON'T</b> perform a squash-merge).</li>
|
||||||
<li>Create a <a href="https://github.com/devicons/devicon/releases/new">new release</a> using v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i> as tag and release title. Use the earlier created description as description of the release.</li>
|
<li>Create a <a href="https://github.com/devicons/devicon/releases/new">new release</a> using the format "<b>Release v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i></b>" as tag and release title. Use the earlier created description as description of the release.</li>
|
||||||
<li>Publishing the release will trigger the <a href="/.github/workflows/npm_publish.yml">npm_publish.yml</a> workflow which will execute a <code>npm publish</code> leading to a updated <a href="https://www.npmjs.com/package/devicon">npm package</a> (v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i>).</li>
|
<li>Publishing the release will trigger the <a href="/.github/workflows/npm_publish.yml">npm_publish.yml</a> workflow which will execute a <code>npm publish</code> leading to a updated <a href="https://www.npmjs.com/package/devicon">npm package</a> (v<i>MAJOR</i>.<i>MINOR</i>.<i>PATCH</i>).</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
Reference in New Issue
Block a user