From 7dd4654fca9ed3a4bd5ddf98d8e1bf09f02463b6 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 13:33:04 +0100 Subject: [PATCH 01/28] Add new action which retrieves new forum posts from forum.stackstorm.com. --- actions/lib/community.py | 11 +++++++ actions/lib/forum_posts.py | 37 ++++++++++++++++++++++++ actions/workflows/build-and-message.yaml | 4 +-- config.schema.yaml | 5 ++++ requirements.txt | 1 + 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 actions/lib/forum_posts.py diff --git a/actions/lib/community.py b/actions/lib/community.py index 102dfeb..1073c6d 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -6,6 +6,8 @@ from github import Github from jinja2 import Template +from lib.forum_posts import get_forum_posts + def _iterate_repos(user, func, **kwargs): new_items = [] @@ -48,6 +50,7 @@ def _get_new_issues(user, delta): def build_text( token, + forum_feed_url, body=None, user='StackStorm-Exchange', delta=timedelta(days=1, minutes=10) @@ -71,14 +74,22 @@ def build_text( "repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ " "issue.user.html_url }}|{{ issue.user.name }}>{% endfor %}{% endif %}" ) + + # 1. Retrieve Github stats for Github organization github = Github(token) exchange = github.get_user(user) pulls = _get_new_prs(exchange, delta=delta) issues = _get_new_issues(exchange, delta=delta) + # 2. Retrieve forum posts from forum.stackstorm.com + forum_posts = get_forum_posts(feed_url=forum_feed_url, + delta=delta) + return template.render( new_issue_count=len(issues), new_pull_count=len(pulls), pulls=pulls, issues=issues, + new_forum_post_count=len(forum_posts), + forum_posts=forum_posts, ) diff --git a/actions/lib/forum_posts.py b/actions/lib/forum_posts.py new file mode 100644 index 0000000..7e7cdf2 --- /dev/null +++ b/actions/lib/forum_posts.py @@ -0,0 +1,37 @@ +import time + +from datetime import datetime +from datetime import timedelta + +import six +import feedparser + +__all__ = [ + 'get_forum_posts' +] + + +def get_forum_posts(feed_url, delta=timedelta(days=1, minutes=10)): + """ + Retrieve forum posts which are been created between now - delta. + """ + feed = feedparser.parse('https://forum.stackstorm.com/latest.rss') + + filter_date = (datetime.utcnow() - delta) + + result = [] + for item in feed['items']: + published_parsed = item.get('published_parsed', None) + + if published_parsed: + published_dt = datetime.fromtimestamp(time.mktime(published_parsed)) + else: + published_dt = None + + if published_dt and (published_dt > filter_date): + item['published_dt'] = published_dt + result.append(item) + + # Items are sorted in the oldest to newest order + result = sorted(result, key=lambda x: x['published_dt']) + return result diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index c471553..48cc5ca 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -14,10 +14,10 @@ tasks: input: body: <% ctx(body) %> user: <% ctx(user) %> - delta: <% ctx(delta) %> + delta: <% ctx(delta) %> next: - when: <% succeeded() %> - do: + do: - sendMessage publish: - message: <% result().result.body %> diff --git a/config.schema.yaml b/config.schema.yaml index bf9d1fb..50c943c 100644 --- a/config.schema.yaml +++ b/config.schema.yaml @@ -4,3 +4,8 @@ token: type: "string" secret: true required: true +forum_rss_feed_url: + description: "URL to the forum RSS feed." + type: "string" + default: "https://forum.stackstorm.com/latest.rss" + required: true diff --git a/requirements.txt b/requirements.txt index a0e999b..199c758 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ PyGithub==1.43.4 Jinja2==2.10 +feedparser==5.2.1 From 8c3a41d71838e93dab4647d851c878f07b8b6a84 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 13:47:20 +0100 Subject: [PATCH 02/28] Update st2 rule to include forum posts. --- actions/lib/community.py | 3 +-- rules/st2.yaml | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/actions/lib/community.py b/actions/lib/community.py index 1073c6d..f5324bf 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -82,8 +82,7 @@ def build_text( issues = _get_new_issues(exchange, delta=delta) # 2. Retrieve forum posts from forum.stackstorm.com - forum_posts = get_forum_posts(feed_url=forum_feed_url, - delta=delta) + forum_posts = get_forum_posts(feed_url=forum_feed_url, delta=delta) return template.render( new_issue_count=len(issues), diff --git a/rules/st2.yaml b/rules/st2.yaml index 0e956fe..09b828d 100644 --- a/rules/st2.yaml +++ b/rules/st2.yaml @@ -30,3 +30,7 @@ action: [% endif %][% if issues %]*Issues:* [% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> [% endfor %][% endif %] + + [% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]*) new post(s) + [% for post in forum_posts %]• <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] + [% endfor %][% endif %] From 3c24fdca2b6a045f759c9ac736f5d5fe22d22a34 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 13:48:26 +0100 Subject: [PATCH 03/28] Use value from config. --- actions/build_text.py | 6 +++++- config.schema.yaml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/actions/build_text.py b/actions/build_text.py index 3c3517d..f973c98 100644 --- a/actions/build_text.py +++ b/actions/build_text.py @@ -6,12 +6,14 @@ from lib import community + class BuildText(Action): """Community Update Action """ def __init__(self, config): super(BuildText, self).__init__(config) self._token = config.get('token') + self._forum_feed_url = config.get('forum_feed_url') def run(self, body=None, user=None, delta=None): """Build and return rendered text @@ -23,9 +25,11 @@ def run(self, body=None, user=None, delta=None): seconds=delta.get('seconds', 0) ) + # TODO: Combine 2 rules and only retrieve forum posts once, not once per rule return { 'body': community.build_text( - self._token, + token=self._token, + forum_feed_url=self._forum_feed_url, body=body, user=user, delta=time_delta diff --git a/config.schema.yaml b/config.schema.yaml index 50c943c..3e63097 100644 --- a/config.schema.yaml +++ b/config.schema.yaml @@ -4,7 +4,7 @@ token: type: "string" secret: true required: true -forum_rss_feed_url: +forum_feed_url: description: "URL to the forum RSS feed." type: "string" default: "https://forum.stackstorm.com/latest.rss" From efbd9b50015c271d047ce26b27901bc3a3cf8717 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 13:53:39 +0100 Subject: [PATCH 04/28] Read default message template from file. --- actions/lib/community.py | 26 +++++++++++++------------- etc/message_template.j2 | 10 ++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 etc/message_template.j2 diff --git a/actions/lib/community.py b/actions/lib/community.py index f5324bf..084a1c3 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -1,6 +1,9 @@ #!/usr/bin/env python """Daily update from Github """ + +import os + from datetime import datetime, timedelta from github import Github @@ -8,6 +11,9 @@ from lib.forum_posts import get_forum_posts +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +DEFAULT_TEMPLATE_PATH = os.path.join(BASE_DIR, '../../etc/message_template.j2') + def _iterate_repos(user, func, **kwargs): new_items = [] @@ -61,19 +67,13 @@ def build_text( if body: body = body.replace('[', '{') body = body.replace(']', '}') - template = Template(body) if body is not None else Template( - "Good morning, @oncall. Here's your community update. Yesterday there " - "were **{{ new_issue_count }}** new issue(s), and " - "**{{ new_pull_count }}** new pull request(s).\n" - "{% if pulls %}\n*Pull Requests*\n" - "{% for pull in pulls %}* <{{ pull.base.repo.html_url }}|{{ pull.base." - "repo.name }}>: <{{ pull.html_url }}|{{ pull.title }}> by <{{ pull.use" - "r.html_url }}|{{ pull.user.name }}>\n" - "{% endfor %}{% endif %}{% if issues %}\n*Issues:*\n" - "{% for issue in issues %}* <{{ issue.repository.html_url }}|{{ issue." - "repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ " - "issue.user.html_url }}|{{ issue.user.name }}>{% endfor %}{% endif %}" - ) + + if not body: + # Read default template from file + with open(DEFAULT_TEMPLATE_PATH, 'r') as fp: + body = fp.read() + + template = Template(body) # 1. Retrieve Github stats for Github organization github = Github(token) diff --git a/etc/message_template.j2 b/etc/message_template.j2 new file mode 100644 index 0000000..843f9b3 --- /dev/null +++ b/etc/message_template.j2 @@ -0,0 +1,10 @@ +[% if pulls %]*Pull Requests* +[% for pull in pulls %]• <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> +[% endfor %] +[% endif %][% if issues %]*Issues:* +[% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> +[% endfor %][% endif %] + +[% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]*) new post(s) +[% for post in forum_posts %]• <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] +[% endfor %][% endif %] From c0a9f40374a8b844d1b9c7dab96435e9788f6206 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 13:57:17 +0100 Subject: [PATCH 05/28] body is not required since we use a default value inside an action. --- actions/build-and-message.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/build-and-message.yaml b/actions/build-and-message.yaml index ca08fc7..453e697 100644 --- a/actions/build-and-message.yaml +++ b/actions/build-and-message.yaml @@ -11,7 +11,7 @@ parameters: required: true body: type: string - required: true + required: false user: type: string required: true From 6f99867408a75c6b8d52a1ecb77def30b853a5da Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 14:02:07 +0100 Subject: [PATCH 06/28] Fix unicode issue. --- etc/message_template.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 843f9b3..1500129 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,10 +1,10 @@ [% if pulls %]*Pull Requests* -[% for pull in pulls %]• <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> +[% for pull in pulls %]* <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> [% endfor %] [% endif %][% if issues %]*Issues:* -[% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> +[% for issue in issues %]* <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> [% endfor %][% endif %] [% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]*) new post(s) -[% for post in forum_posts %]• <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] +[% for post in forum_posts %]* <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] [% endfor %][% endif %] From 82fd7dadfbba4a445a31182da5ea0e363d4d893a Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 14:03:05 +0100 Subject: [PATCH 07/28] Fix syntax. --- etc/message_template.j2 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 1500129..c114a82 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,10 +1,10 @@ -[% if pulls %]*Pull Requests* -[% for pull in pulls %]* <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> -[% endfor %] -[% endif %][% if issues %]*Issues:* -[% for issue in issues %]* <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> -[% endfor %][% endif %] +{% if pulls %}*Pull Requests* +{% for pull in pulls %}* <{{ pull.base.repo.html_url }}|{{ pull.base.repo.name }}>: <{{ pull.html_url }}|{{ pull.title }}> by <{{ pull.user.html_url }}|{{ pull.user.name }}> +{% endfor %} +{% endif %}{% if issues %}*Issues:* +{% for issue in issues %}* <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.name }}> +{% endfor %}{% endif %} -[% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]*) new post(s) -[% for post in forum_posts %]* <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] -[% endfor %][% endif %] +{% if forum_posts %}*Forum Posts* (*{{ new_forum_post_count }}*) new post(s) +{% for post in forum_posts %}* <{{ post.link }}|{{ post.title }}> by {{ post.author }} +{% endfor %}{% endif %} From 71ba893ef08418b601ff1e58689fb3b34de79e90 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 14:03:53 +0100 Subject: [PATCH 08/28] Fix syntax. --- etc/message_template.j2 | 2 +- rules/st2.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index c114a82..15d3d8a 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -5,6 +5,6 @@ {% for issue in issues %}* <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.name }}> {% endfor %}{% endif %} -{% if forum_posts %}*Forum Posts* (*{{ new_forum_post_count }}*) new post(s) +{% if forum_posts %}*Forum Posts* (*{{ new_forum_post_count }}* new post(s)) {% for post in forum_posts %}* <{{ post.link }}|{{ post.title }}> by {{ post.author }} {% endfor %}{% endif %} diff --git a/rules/st2.yaml b/rules/st2.yaml index 09b828d..89e1f5e 100644 --- a/rules/st2.yaml +++ b/rules/st2.yaml @@ -31,6 +31,6 @@ action: [% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> [% endfor %][% endif %] - [% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]*) new post(s) + [% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]* new post(s)) [% for post in forum_posts %]• <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] [% endfor %][% endif %] From 55e2b525c52d0cf54c07dd6f8b1c4ab9ee90b1b9 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 16:41:19 +0100 Subject: [PATCH 09/28] Update action and workflow so we have a single action which retrieves data from multiple sources and renders it as a Slack message. Also update Github issue and pr retrieval code so it's also more efficient (we only retrieve issues once, filtering is performed server side, etc). --- actions/build-and-message.yaml | 9 +- actions/build-text.yaml | 20 ++-- actions/build_text.py | 10 +- actions/lib/community.py | 127 +++++++++++------------ actions/workflows/build-and-message.yaml | 3 +- etc/message_template.j2 | 36 +++++-- rules/exchange.yaml | 32 ------ rules/st2.yaml | 19 +--- 8 files changed, 119 insertions(+), 137 deletions(-) delete mode 100644 rules/exchange.yaml diff --git a/actions/build-and-message.yaml b/actions/build-and-message.yaml index 453e697..e51ae9a 100644 --- a/actions/build-and-message.yaml +++ b/actions/build-and-message.yaml @@ -9,11 +9,10 @@ parameters: channel: type: string required: true - body: - type: string - required: false - user: - type: string + github_users: + type: array + items: + type: "string" required: true delta: type: object diff --git a/actions/build-text.yaml b/actions/build-text.yaml index 004e0b6..82a1769 100644 --- a/actions/build-text.yaml +++ b/actions/build-text.yaml @@ -1,20 +1,28 @@ --- name: build-text pack: st2community -description: Render given text with information about PRs and Issues. +description: Retrive various daily summary (new issues and PRs in all the repos, new forum posts, ec.). runner_type: python-script entry_point: build_text.py enabled: true parameters: - body: - type: string - required: true - user: - type: string + github_users: + description: "Github users / organizations to retrieve recent issues and pull requests for." + type: array + items: + type: "string" + default: + - "StackStorm" + - "StackStorm-Exchange" required: true delta: + description: "Time period to retrieve summary for." type: object required: true default: days: 1 minutes: 10 + template_path: + description: "Path to the Jinja template file for the Slack message (relative to the pack directory)." + type: "string" + default: "etc/message_template.j2" diff --git a/actions/build_text.py b/actions/build_text.py index f973c98..b1f2fe9 100644 --- a/actions/build_text.py +++ b/actions/build_text.py @@ -1,13 +1,19 @@ #!/usr/bin/env python -"""Community Update Action """ +Community Update Action +""" + from datetime import timedelta from st2common.runners.base_action import Action from lib import community +__all__ = [ + 'BuildTextAction' +] + -class BuildText(Action): +class BuildTextAction(Action): """Community Update Action """ def __init__(self, config): diff --git a/actions/lib/community.py b/actions/lib/community.py index 084a1c3..327082d 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -1,94 +1,89 @@ -#!/usr/bin/env python -"""Daily update from Github -""" - import os -from datetime import datetime, timedelta +from datetime import datetime +from datetime import timedelta from github import Github -from jinja2 import Template +from jinja2 import Environment from lib.forum_posts import get_forum_posts BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -DEFAULT_TEMPLATE_PATH = os.path.join(BASE_DIR, '../../etc/message_template.j2') - - -def _iterate_repos(user, func, **kwargs): - new_items = [] - for repo in user.get_repos(): - new_items += func(repo, **kwargs) - - return new_items -def _filter_by_date(items, date_attribute, delta): - filter_date = datetime.utcnow() - delta - filtered_items = [] - - for item in items: - if getattr(item, date_attribute) > filter_date: - filtered_items.append(item) +def get_issues_and_prs_for_repo(repo, delta): + """ + Retrieve new issues and PRs for the provided user and time period. + """ + result = { + 'issues': [], + 'prs': [] + } - return filtered_items + since_dt = (datetime.now() - delta) + issues = list(repo.get_issues(since=since_dt)) + for issue in issues: + if issue.pull_request: + result['prs'].append(issue) + else: + result['issues'].append(issue) -def _filter_prs(repo, delta=timedelta(days=1, minutes=10)): - return _filter_by_date(repo.get_pulls(), 'created_at', delta) + return result -def _get_new_prs(user, delta): - return _iterate_repos(user, _filter_prs, delta=delta) +def build_text(token, forum_feed_url, template_path, github_users=None, + delta=timedelta(days=1, minutes=10)): + """ + Retrieve the following information for a given time period and return slack + text to be sent: + * Github issues and pull requests for the provided users + * Forum posts + """ + github_users = github_users or [] -def _filter_issues(repo, delta=timedelta(days=1, minutes=10)): - issues = _filter_by_date(repo.get_issues(), 'created_at', delta) - for index, issue in enumerate(issues): - if issue.pull_request: - issues.pop(index) - return issues + template_path = os.path.join(BASE_DIR, '../../', template_path) + template_path = os.path.abspath(template_path) + with open(template_path, 'r') as fp: + template_data = fp.read() -def _get_new_issues(user, delta): - return _iterate_repos(user, _filter_issues, delta=delta) + template_context = { + 'github': {}, + 'forum_posts': [] + } + # 1. Retrieve Github stats for the provided Github users / organizations + github = Github(token) -def build_text( - token, - forum_feed_url, - body=None, - user='StackStorm-Exchange', - delta=timedelta(days=1, minutes=10) -): - """build_text processes the new issues and PRs for a given time period and - returns slack message text to be sent. - """ - if body: - body = body.replace('[', '{') - body = body.replace(']', '}') + for user in github_users: + github_user = github.get_user(user) - if not body: - # Read default template from file - with open(DEFAULT_TEMPLATE_PATH, 'r') as fp: - body = fp.read() + # Iterate over all the repos + # TODO - this is slow, use whitelist / blacklist? + user_issues = [] + user_prs = [] - template = Template(body) + for repo in [github_user.get_repo('st2')]: + #for repo in github_user.get_repos(): + result = get_issues_and_prs_for_repo(repo=repo, delta=delta) + user_issues.extend(result['issues']) + user_prs.extend(result['prs']) - # 1. Retrieve Github stats for Github organization - github = Github(token) - exchange = github.get_user(user) - pulls = _get_new_prs(exchange, delta=delta) - issues = _get_new_issues(exchange, delta=delta) + # NOTE: Jinja doesn't support referencing dict keys with "-" in them + username = user.replace('-', '_').lower() + template_context['github'][username] = { + 'user': user, + 'issues': user_issues, + 'pulls': user_prs + } # 2. Retrieve forum posts from forum.stackstorm.com forum_posts = get_forum_posts(feed_url=forum_feed_url, delta=delta) + template_context['forum_posts'] = forum_posts - return template.render( - new_issue_count=len(issues), - new_pull_count=len(pulls), - pulls=pulls, - issues=issues, - new_forum_post_count=len(forum_posts), - forum_posts=forum_posts, - ) + # Add all information to the template context and render the template + env = Environment(trim_blocks=True, lstrip_blocks=True) + rendered = env.from_string(template_data).render(template_context) + return rendered diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index 48cc5ca..34e4fed 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -12,8 +12,7 @@ tasks: buildMessage: action: st2community.build-text input: - body: <% ctx(body) %> - user: <% ctx(user) %> + github_users: <% ctx(github_users) %> delta: <% ctx(delta) %> next: - when: <% succeeded() %> diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 15d3d8a..33ca0ad 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,10 +1,28 @@ -{% if pulls %}*Pull Requests* -{% for pull in pulls %}* <{{ pull.base.repo.html_url }}|{{ pull.base.repo.name }}>: <{{ pull.html_url }}|{{ pull.title }}> by <{{ pull.user.html_url }}|{{ pull.user.name }}> -{% endfor %} -{% endif %}{% if issues %}*Issues:* -{% for issue in issues %}* <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.name }}> -{% endfor %}{% endif %} +Good morning, team. Here's what happened yesterday at StackStorm. -{% if forum_posts %}*Forum Posts* (*{{ new_forum_post_count }}* new post(s)) -{% for post in forum_posts %}* <{{ post.link }}|{{ post.title }}> by {{ post.author }} -{% endfor %}{% endif %} +*Pull Requests* (StackStorm organization) +{% if github.stackstorm.pulls %} + {% for issue in github.stackstorm.pulls -%} + * <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} + +*Issues:* (StackStorm organization) +{% if github.stackstorm.issues %} + {% for issue in github.stackstorm.issues -%} + * <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} + +*Forum Posts* (*{{ forum_posts|length }}* new post(s)) +{% if forum_posts %} + {% for post in forum_posts -%} + * <{{ post.link }}|{{ post.title }}> by {{ post.author }} + {% endfor %} +{% else %} +None. +{% endif %} diff --git a/rules/exchange.yaml b/rules/exchange.yaml deleted file mode 100644 index 10197c4..0000000 --- a/rules/exchange.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: "community_update" -pack: "st2community" -description: "Daily publish previous 24 hours statistics." -enabled: true - -trigger: - type: "core.st2.CronTimer" - parameters: - timezone: "UTC" - day_of_week: '*' - hour: 17 - minute: 30 - second: 0 - -action: - ref: "st2community.build-and-message" - parameters: - user: "StackStorm-Exchange" - channel: "#support" - delta: - days: 1 - minutes: 10 - body: | - Good morning, @oncall. Here's your community update. Yesterday there were *[[ new_issue_count ]]* new issue(s), and *[[ new_pull_count ]]* new pull request(s). - - [% if pulls %]*Pull Requests* - [% for pull in pulls %]• <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> - [% endfor %] - [% endif %][% if issues %]*Issues:* - [% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> - [% endfor %][% endif %] diff --git a/rules/st2.yaml b/rules/st2.yaml index 89e1f5e..388aff9 100644 --- a/rules/st2.yaml +++ b/rules/st2.yaml @@ -1,7 +1,7 @@ --- name: "stackstorm_update" pack: "st2community" -description: "Daily publish previous 24 hours statistics." +description: "Gather and publish various statistics for previous 24 hours." enabled: true trigger: @@ -16,21 +16,10 @@ trigger: action: ref: "st2community.build-and-message" parameters: - user: "StackStorm" + github_users: + - "StackStorm" + - "StackStorm-Exchange" channel: "#stackstorm" delta: days: 1 minutes: 10 - body: | - Good morning, team. Here's what happened yesterday at ST2. There were *[[ new_issue_count ]]* new issue(s), and *[[ new_pull_count ]]* new pull request(s). - - [% if pulls %]*Pull Requests* - [% for pull in pulls %]• <[[ pull.base.repo.html_url ]]|[[ pull.base.repo.name ]]>: <[[ pull.html_url ]]|[[ pull.title ]]> by <[[ pull.user.html_url ]]|[[ pull.user.name ]]> - [% endfor %] - [% endif %][% if issues %]*Issues:* - [% for issue in issues %]• <[[ issue.repository.html_url ]]|[[ issue.repository.name ]]>: <[[ issue.html_url ]]|[[ issue.title ]]> by <[[ issue.user.html_url ]]|[[ issue.user.name ]]> - [% endfor %][% endif %] - - [% if forum_posts %]*Forum Posts* (*[[ new_forum_post_count ]]* new post(s)) - [% for post in forum_posts %]• <[[ post.link ]]|[[ post.title ]]> by [[ post.author ]] - [% endfor %][% endif %] From e893f89196314d44ee29969121d1d7f3ab2639de Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 16:49:34 +0100 Subject: [PATCH 10/28] Fix syntax error. --- actions/build-text.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/actions/build-text.yaml b/actions/build-text.yaml index 82a1769..637546b 100644 --- a/actions/build-text.yaml +++ b/actions/build-text.yaml @@ -22,7 +22,7 @@ parameters: default: days: 1 minutes: 10 - template_path: - description: "Path to the Jinja template file for the Slack message (relative to the pack directory)." - type: "string" - default: "etc/message_template.j2" + template_path: + description: "Path to the Jinja template file for the Slack message (relative to the pack directory)." + type: "string" + default: "etc/message_template.j2" From 78ad180813e7deee506391f22c04245425548c04 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 16:50:06 +0100 Subject: [PATCH 11/28] Remove debug code. --- actions/lib/community.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/actions/lib/community.py b/actions/lib/community.py index 327082d..c04a70e 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -65,8 +65,7 @@ def build_text(token, forum_feed_url, template_path, github_users=None, user_issues = [] user_prs = [] - for repo in [github_user.get_repo('st2')]: - #for repo in github_user.get_repos(): + for repo in github_user.get_repos(): result = get_issues_and_prs_for_repo(repo=repo, delta=delta) user_issues.extend(result['issues']) user_prs.extend(result['prs']) From 2ee87ef5f4c25c176d15eccd607720e8e9f75a71 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 16:51:52 +0100 Subject: [PATCH 12/28] Fix workflow, change rule name. --- actions/workflows/build-and-message.yaml | 3 +-- rules/{st2.yaml => post_daily_summary_to_slack.yaml} | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename rules/{st2.yaml => post_daily_summary_to_slack.yaml} (100%) diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index 34e4fed..5bc454f 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -3,9 +3,8 @@ version: 1.0 description: Send update to given channel. input: + - github_users - channel - - body - - user - delta tasks: diff --git a/rules/st2.yaml b/rules/post_daily_summary_to_slack.yaml similarity index 100% rename from rules/st2.yaml rename to rules/post_daily_summary_to_slack.yaml From 9c0c05845e1be6525deea703fdb4bd01ff5544d2 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 16:54:54 +0100 Subject: [PATCH 13/28] Update affected code, add some logging. --- actions/build_text.py | 15 ++++++++------- actions/lib/community.py | 6 +++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/actions/build_text.py b/actions/build_text.py index b1f2fe9..45a883c 100644 --- a/actions/build_text.py +++ b/actions/build_text.py @@ -17,12 +17,13 @@ class BuildTextAction(Action): """Community Update Action """ def __init__(self, config): - super(BuildText, self).__init__(config) + super(BuildTextAction, self).__init__(config) self._token = config.get('token') self._forum_feed_url = config.get('forum_feed_url') - def run(self, body=None, user=None, delta=None): - """Build and return rendered text + def run(self, github_users, template_path, delta): + """ + Build and return rendered text """ time_delta = timedelta( days=delta.get('days', 0), @@ -31,13 +32,13 @@ def run(self, body=None, user=None, delta=None): seconds=delta.get('seconds', 0) ) - # TODO: Combine 2 rules and only retrieve forum posts once, not once per rule return { 'body': community.build_text( + logger=self.logger, token=self._token, forum_feed_url=self._forum_feed_url, - body=body, - user=user, - delta=time_delta + github_users=github_users, + delta=time_delta, + template_path=template_path, ) } diff --git a/actions/lib/community.py b/actions/lib/community.py index c04a70e..e5f6cba 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -32,7 +32,7 @@ def get_issues_and_prs_for_repo(repo, delta): return result -def build_text(token, forum_feed_url, template_path, github_users=None, +def build_text(logger, token, forum_feed_url, template_path, github_users=None, delta=timedelta(days=1, minutes=10)): """ Retrieve the following information for a given time period and return slack @@ -58,6 +58,8 @@ def build_text(token, forum_feed_url, template_path, github_users=None, github = Github(token) for user in github_users: + logger.debug('Retrieving Github issues and prs for user %s' % (user)) + github_user = github.get_user(user) # Iterate over all the repos @@ -79,6 +81,8 @@ def build_text(token, forum_feed_url, template_path, github_users=None, } # 2. Retrieve forum posts from forum.stackstorm.com + logger.debug('Retrieving forum posts') + forum_posts = get_forum_posts(feed_url=forum_feed_url, delta=delta) template_context['forum_posts'] = forum_posts From 18a69b1aa3a2f76969aa58b2e470210066e42476 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 17:09:23 +0100 Subject: [PATCH 14/28] Use unicode bullet, also include stats for StackStorm-Exchange org. --- etc/message_template.j2 | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 33ca0ad..96fa8d9 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,27 +1,50 @@ Good morning, team. Here's what happened yesterday at StackStorm. -*Pull Requests* (StackStorm organization) +**StackStorm Github Organization** + +*Pull Requests* ({{ github.stackstorm.pulls|length}} new pull request(s)): {% if github.stackstorm.pulls %} {% for issue in github.stackstorm.pulls -%} - * <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> {% endfor %} {% else %} None. {% endif %} -*Issues:* (StackStorm organization) +*Issues* ({{ github.stackstorm.issues|length}} new issue(s)): {% if github.stackstorm.issues %} {% for issue in github.stackstorm.issues -%} - * <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} + +**StackStorm-Exchange Organization** + +*Pull Requests* ({{ github.stackstorm_exchange.pulls|length}} new pull request(s)): +{% if github.stackstorm_exchange.pulls %} + {% for issue in github.stackstorm_exchange.pulls -%} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} + +*Issues* ({{ github.stackstorm_exchange.issues|length}} new issue(s)): +{% if github.stackstorm_exchange.issues %} + {% for issue in github.stackstorm.issues -%} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> {% endfor %} {% else %} None. {% endif %} + *Forum Posts* (*{{ forum_posts|length }}* new post(s)) {% if forum_posts %} {% for post in forum_posts -%} - * <{{ post.link }}|{{ post.title }}> by {{ post.author }} + • <{{ post.link }}|{{ post.title }}> by {{ post.author }} {% endfor %} {% else %} None. From ef7ba494d5780843e7f34f428b629216c35f7e48 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 17:12:49 +0100 Subject: [PATCH 15/28] Update code so it works with templates which contain unicode. --- actions/lib/community.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actions/lib/community.py b/actions/lib/community.py index e5f6cba..477c782 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -1,4 +1,5 @@ import os +import codecs from datetime import datetime from datetime import timedelta @@ -46,7 +47,7 @@ def build_text(logger, token, forum_feed_url, template_path, github_users=None, template_path = os.path.join(BASE_DIR, '../../', template_path) template_path = os.path.abspath(template_path) - with open(template_path, 'r') as fp: + with codecs.open(template_path, encoding='utf-8') as fp: template_data = fp.read() template_context = { From dfd6c0fcb2c1b5d9983705b312bb25d056d4b4cb Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 31 Jan 2019 17:16:04 +0100 Subject: [PATCH 16/28] Update formatting. --- etc/message_template.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 96fa8d9..09a45ae 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,6 +1,6 @@ Good morning, team. Here's what happened yesterday at StackStorm. -**StackStorm Github Organization** +*StackStorm Github Organization* *Pull Requests* ({{ github.stackstorm.pulls|length}} new pull request(s)): {% if github.stackstorm.pulls %} @@ -20,7 +20,7 @@ None. None. {% endif %} -**StackStorm-Exchange Organization** +*StackStorm-Exchange Organization* *Pull Requests* ({{ github.stackstorm_exchange.pulls|length}} new pull request(s)): {% if github.stackstorm_exchange.pulls %} From 8136e6b9309eda9dbd589919b6463c8a539f62eb Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 10:37:00 +0100 Subject: [PATCH 17/28] Initial split of one massive actions in three more smaller and re-usable ones. --- actions/build-and-message.yaml | 7 ++-- actions/build-text.yaml | 2 +- actions/get_forum_posts.py | 30 +++++++++++++++++ actions/get_forum_posts.yaml | 20 ++++++++++++ actions/get_github_issues.py | 35 ++++++++++++++++++++ actions/get_github_issues.yaml | 25 ++++++++++++++ actions/lib/community.py | 21 ------------ actions/lib/forum_posts.py | 3 +- actions/lib/github_issues.py | 59 ++++++++++++++++++++++++++++++++++ actions/lib/utils.py | 30 +++++++++++++++++ 10 files changed, 206 insertions(+), 26 deletions(-) create mode 100644 actions/get_forum_posts.py create mode 100644 actions/get_forum_posts.yaml create mode 100644 actions/get_github_issues.py create mode 100644 actions/get_github_issues.yaml create mode 100644 actions/lib/github_issues.py create mode 100644 actions/lib/utils.py diff --git a/actions/build-and-message.yaml b/actions/build-and-message.yaml index e51ae9a..e4f15cd 100644 --- a/actions/build-and-message.yaml +++ b/actions/build-and-message.yaml @@ -1,20 +1,23 @@ --- -name: build-and-message +name: retrieve_data_and_send_message_to_slack pack: st2community -description: Send update to given channel. +description: Retrieve daily statistics and send message to Slack channel. runner_type: orquesta entry_point: workflows/build-and-message.yaml enabled: true parameters: channel: + description: "Slack channel to send the message to." type: string required: true github_users: + description: "Github users / organizations to retrieve issues and PRs for." type: array items: type: "string" required: true delta: + description: "Time period to retrieve data for (from now - delta to now)." type: object required: true default: diff --git a/actions/build-text.yaml b/actions/build-text.yaml index 637546b..8e610aa 100644 --- a/actions/build-text.yaml +++ b/actions/build-text.yaml @@ -1,7 +1,7 @@ --- name: build-text pack: st2community -description: Retrive various daily summary (new issues and PRs in all the repos, new forum posts, ec.). +description: Retrieve various daily summary (new issues and PRs in all the repos, new forum posts, etc.) and assemble summary text. runner_type: python-script entry_point: build_text.py enabled: true diff --git a/actions/get_forum_posts.py b/actions/get_forum_posts.py new file mode 100644 index 0000000..4d8fa3e --- /dev/null +++ b/actions/get_forum_posts.py @@ -0,0 +1,30 @@ +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from st2common.runners.base_action import Action + +from lib.utils import get_timedelta_object_from_delta_arg +from lib.forum_posts import get_forum_posts + +__all__ = [ + 'GetForumPostsAction' +] + + +class GetForumPostsAction(Action): + def run(self, feed_url, delta): + time_delta = get_timedelta_object_from_delta_arg(delta) + result = get_forum_posts(feed_url=feed_url, delta=time_delta) + return result diff --git a/actions/get_forum_posts.yaml b/actions/get_forum_posts.yaml new file mode 100644 index 0000000..5d3db09 --- /dev/null +++ b/actions/get_forum_posts.yaml @@ -0,0 +1,20 @@ +--- +name: get_forum_posts +pack: st2community +description: Retrieve recent forum posts. +runner_type: python-script +entry_point: get_forum_posts.py +enabled: true +parameters: + feed_url: + description: "Forum RSS feed URL." + type: string + required: true + default: "{{ config_context.forum_feed_url }}" + delta: + description: "Time period to retrieve forum posts for." + type: object + required: true + default: + days: 1 + minutes: 10 diff --git a/actions/get_github_issues.py b/actions/get_github_issues.py new file mode 100644 index 0000000..add1632 --- /dev/null +++ b/actions/get_github_issues.py @@ -0,0 +1,35 @@ +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from github import Github + +from st2common.runners.base_action import Action + +from lib.utils import get_timedelta_object_from_delta_arg +from lib.github_issues import get_issues_and_prs_for_user + +__all__ = [ + 'GetGithubIssuesAction' +] + + +class GetGithubIssuesAction(Action): + def run(self, token, user, delta): + time_delta = get_timedelta_object_from_delta_arg(delta) + github = Github(token) + github_user = github.get_user(user) + result = get_issues_and_prs_for_user(github_user=github_user, user=user, + time_delta=time_delta) + return result diff --git a/actions/get_github_issues.yaml b/actions/get_github_issues.yaml new file mode 100644 index 0000000..99da9e6 --- /dev/null +++ b/actions/get_github_issues.yaml @@ -0,0 +1,25 @@ +--- +name: get_github_issues +pack: st2community +description: Retrieve recent Github issues and pull requests. +runner_type: python-script +entry_point: get_github_issues.py +enabled: true +parameters: + token: + description: "Github token used to authenticate." + type: string + secret: true + required: true + default: "{{ config_context.token }}" + username: + description: "Username of the Github user / organization to retrieve issues for." + type: string + required: true + delta: + description: "Time period to retrieve issuesfor." + type: object + required: true + default: + days: 1 + minutes: 10 diff --git a/actions/lib/community.py b/actions/lib/community.py index 477c782..20322fb 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -12,27 +12,6 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -def get_issues_and_prs_for_repo(repo, delta): - """ - Retrieve new issues and PRs for the provided user and time period. - """ - result = { - 'issues': [], - 'prs': [] - } - - since_dt = (datetime.now() - delta) - issues = list(repo.get_issues(since=since_dt)) - - for issue in issues: - if issue.pull_request: - result['prs'].append(issue) - else: - result['issues'].append(issue) - - return result - - def build_text(logger, token, forum_feed_url, template_path, github_users=None, delta=timedelta(days=1, minutes=10)): """ diff --git a/actions/lib/forum_posts.py b/actions/lib/forum_posts.py index 7e7cdf2..4fab7d0 100644 --- a/actions/lib/forum_posts.py +++ b/actions/lib/forum_posts.py @@ -3,7 +3,6 @@ from datetime import datetime from datetime import timedelta -import six import feedparser __all__ = [ @@ -15,7 +14,7 @@ def get_forum_posts(feed_url, delta=timedelta(days=1, minutes=10)): """ Retrieve forum posts which are been created between now - delta. """ - feed = feedparser.parse('https://forum.stackstorm.com/latest.rss') + feed = feedparser.parse(feed_url) filter_date = (datetime.utcnow() - delta) diff --git a/actions/lib/github_issues.py b/actions/lib/github_issues.py new file mode 100644 index 0000000..87ceb56 --- /dev/null +++ b/actions/lib/github_issues.py @@ -0,0 +1,59 @@ +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import datetime + +__all__ = [ + 'get_issues_and_prs_for_repo', + 'get_issues_and_prs_for_user' +] + + +def get_issues_and_prs_for_repo(repo, time_delta): + """ + Retrieve new issues and PRs for the provided user and time period. + """ + result = { + 'issues': [], + 'prs': [] + } + + since_dt = (datetime.now() - time_delta) + issues = list(repo.get_issues(since=since_dt)) + + for issue in issues: + if issue.pull_request: + result['prs'].append(issue) + else: + result['issues'].append(issue) + + return result + + +def get_issues_and_prs_for_user(github_user, time_delta): + """ + Retrieve issues and PRs for all the Github repos for the provided user. + """ + result = { + 'issues': [], + 'prs': [] + } + + for repo in github_user.get_repos(): + result = get_issues_and_prs_for_repo(repo=repo, time_delta=time_delta) + result['issues'].extend(result['issues']) + result['prs'].extend(result['prs']) + + return result diff --git a/actions/lib/utils.py b/actions/lib/utils.py new file mode 100644 index 0000000..576c6f0 --- /dev/null +++ b/actions/lib/utils.py @@ -0,0 +1,30 @@ +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import timedelta + +__all__ = [ + 'get_timedelta_object_from_delta_arg' +] + +def get_timedelta_object_from_delta_arg(delta): + time_delta = timedelta( + days=delta.get('days', 0), + hours=delta.get('hours', 0), + minutes=delta.get('minutes', 0), + seconds=delta.get('seconds', 0) + ) + + return time_delta From 121c6aa534cdd7e5c47db53d0dddecf74ae6fe55 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 17:49:45 +0100 Subject: [PATCH 18/28] More progress on new workflow. --- actions/assemble_message.py | 35 +++++++++++++++ ...{build-text.yaml => assemble_message.yaml} | 24 ++++------ actions/build_text.py | 44 ------------------- actions/get_github_issues.py | 7 ++- actions/lib/community.py | 3 +- actions/lib/forum_posts.py | 13 ++++++ actions/workflows/build-and-message.yaml | 37 +++++++++++++--- 7 files changed, 91 insertions(+), 72 deletions(-) create mode 100644 actions/assemble_message.py rename actions/{build-text.yaml => assemble_message.yaml} (50%) delete mode 100644 actions/build_text.py diff --git a/actions/assemble_message.py b/actions/assemble_message.py new file mode 100644 index 0000000..58f4284 --- /dev/null +++ b/actions/assemble_message.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import timedelta +from st2common.runners.base_action import Action + +from lib import community + +__all__ = [ + 'AssembleMessageAction' +] + + +class AssembleMessageAction(Action): + def run(self, forum_posts, github_data, template_path, delta): + """ + Build and return rendered text. + """ + from pprint import pprint + pprint('aaaaa') + pprint(forum_posts) + pprint(github_data) diff --git a/actions/build-text.yaml b/actions/assemble_message.yaml similarity index 50% rename from actions/build-text.yaml rename to actions/assemble_message.yaml index 8e610aa..c3d3d63 100644 --- a/actions/build-text.yaml +++ b/actions/assemble_message.yaml @@ -1,27 +1,19 @@ --- -name: build-text +name: assemble_message pack: st2community description: Retrieve various daily summary (new issues and PRs in all the repos, new forum posts, etc.) and assemble summary text. runner_type: python-script -entry_point: build_text.py +entry_point: assemble_message.py enabled: true parameters: - github_users: - description: "Github users / organizations to retrieve recent issues and pull requests for." + forum_posts: type: array items: - type: "string" - default: - - "StackStorm" - - "StackStorm-Exchange" - required: true - delta: - description: "Time period to retrieve summary for." - type: object - required: true - default: - days: 1 - minutes: 10 + type: "object" + github_data: + type: array + items: + type: "object" template_path: description: "Path to the Jinja template file for the Slack message (relative to the pack directory)." type: "string" diff --git a/actions/build_text.py b/actions/build_text.py deleted file mode 100644 index 45a883c..0000000 --- a/actions/build_text.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -""" -Community Update Action -""" - -from datetime import timedelta -from st2common.runners.base_action import Action - -from lib import community - -__all__ = [ - 'BuildTextAction' -] - - -class BuildTextAction(Action): - """Community Update Action - """ - def __init__(self, config): - super(BuildTextAction, self).__init__(config) - self._token = config.get('token') - self._forum_feed_url = config.get('forum_feed_url') - - def run(self, github_users, template_path, delta): - """ - Build and return rendered text - """ - time_delta = timedelta( - days=delta.get('days', 0), - hours=delta.get('hours', 0), - minutes=delta.get('minutes', 0), - seconds=delta.get('seconds', 0) - ) - - return { - 'body': community.build_text( - logger=self.logger, - token=self._token, - forum_feed_url=self._forum_feed_url, - github_users=github_users, - delta=time_delta, - template_path=template_path, - ) - } diff --git a/actions/get_github_issues.py b/actions/get_github_issues.py index add1632..91134aa 100644 --- a/actions/get_github_issues.py +++ b/actions/get_github_issues.py @@ -26,10 +26,9 @@ class GetGithubIssuesAction(Action): - def run(self, token, user, delta): + def run(self, token, username, delta): time_delta = get_timedelta_object_from_delta_arg(delta) github = Github(token) - github_user = github.get_user(user) - result = get_issues_and_prs_for_user(github_user=github_user, user=user, - time_delta=time_delta) + github_user = github.get_user(username) + result = get_issues_and_prs_for_user(github_user=github_user, time_delta=time_delta) return result diff --git a/actions/lib/community.py b/actions/lib/community.py index 20322fb..273726a 100644 --- a/actions/lib/community.py +++ b/actions/lib/community.py @@ -12,8 +12,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -def build_text(logger, token, forum_feed_url, template_path, github_users=None, - delta=timedelta(days=1, minutes=10)): +def build_text(logger, delta=timedelta(days=1, minutes=10)): """ Retrieve the following information for a given time period and return slack text to be sent: diff --git a/actions/lib/forum_posts.py b/actions/lib/forum_posts.py index 4fab7d0..cedfbcd 100644 --- a/actions/lib/forum_posts.py +++ b/actions/lib/forum_posts.py @@ -1,4 +1,7 @@ import time +import json + +from st2common.util.jsonify import json_encode from datetime import datetime from datetime import timedelta @@ -33,4 +36,14 @@ def get_forum_posts(feed_url, delta=timedelta(days=1, minutes=10)): # Items are sorted in the oldest to newest order result = sorted(result, key=lambda x: x['published_dt']) + + # Remove complex types (datetime, etc) + # TODO: Add escape Jinja filter which is available to Orquesta workflows + keys_to_remove = ['published_dt', 'summary', 'summary_detail'] + for item in result: + for key in keys_to_remove: + if key in item: + del item[key] + + # Serialzie it to json and back to end up only with simple types return result diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index 5bc454f..5207718 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -1,6 +1,6 @@ version: 1.0 -description: Send update to given channel. +description: Send daily summary to given Slack channel. input: - github_users @@ -8,18 +8,43 @@ input: - delta tasks: - buildMessage: - action: st2community.build-text + get_forum_posts: + action: st2community.get_forum_posts input: - github_users: <% ctx(github_users) %> delta: <% ctx(delta) %> next: - when: <% succeeded() %> do: - - sendMessage + - assemble_message + publish: + - forum_posts: <% result().result %> + get_github_issues: + action: st2community.get_github_issues + with: + items: <% ctx(github_users) %> + concurrency: 1 + input: + username: <% item() %> + delta: <% ctx(delta) %> + next: + - when: <% succeeded() %> + do: + - assemble_message + publish: + - github_data: <% task(get_github_issues).result.items.select($.result.result) %> + assemble_message: + join: all + action: st2community.assemble_message + input: + forum_posts: <% ctx().forum_posts %> + github_data: <% ctx().github_data %> + next: + - when: <% succeeded() %> + do: + - send_message_to_slack publish: - message: <% result().result.body %> - sendMessage: + send_message_to_slack: action: slack.chat.postMessage input: channel: <% ctx(channel) %> From a193154a0ddd6faabd0a50b72291b41c690bde26 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 17:53:28 +0100 Subject: [PATCH 19/28] Also remove published_parsed key. --- actions/lib/forum_posts.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/actions/lib/forum_posts.py b/actions/lib/forum_posts.py index cedfbcd..c330e51 100644 --- a/actions/lib/forum_posts.py +++ b/actions/lib/forum_posts.py @@ -1,7 +1,4 @@ import time -import json - -from st2common.util.jsonify import json_encode from datetime import datetime from datetime import timedelta @@ -39,7 +36,7 @@ def get_forum_posts(feed_url, delta=timedelta(days=1, minutes=10)): # Remove complex types (datetime, etc) # TODO: Add escape Jinja filter which is available to Orquesta workflows - keys_to_remove = ['published_dt', 'summary', 'summary_detail'] + keys_to_remove = ['published_dt', 'published_parsed', 'summary', 'summary_detail'] for item in result: for key in keys_to_remove: if key in item: From 8495a197b74581151ee5e3a6b0c4b603ee547e1b Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 17:59:56 +0100 Subject: [PATCH 20/28] Add quotes, fix signature. --- actions/assemble_message.py | 2 +- actions/workflows/build-and-message.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actions/assemble_message.py b/actions/assemble_message.py index 58f4284..3b6def5 100644 --- a/actions/assemble_message.py +++ b/actions/assemble_message.py @@ -25,7 +25,7 @@ class AssembleMessageAction(Action): - def run(self, forum_posts, github_data, template_path, delta): + def run(self, forum_posts, github_data, template_path): """ Build and return rendered text. """ diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index 5207718..8364579 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -36,8 +36,8 @@ tasks: join: all action: st2community.assemble_message input: - forum_posts: <% ctx().forum_posts %> - github_data: <% ctx().github_data %> + forum_posts: "<% ctx().forum_posts %>" + github_data: "<% ctx().github_data %>" next: - when: <% succeeded() %> do: From f390d9b6807a9f7457c47100ce88b9949fb54fd9 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 23:28:37 +0100 Subject: [PATCH 21/28] Finish the workflow. --- actions/assemble_message.py | 30 ++++++++-- actions/lib/community.py | 71 ------------------------ actions/lib/github_issues.py | 20 ++++--- actions/workflows/build-and-message.yaml | 2 +- etc/message_template.j2 | 64 ++++++++------------- 5 files changed, 61 insertions(+), 126 deletions(-) delete mode 100644 actions/lib/community.py diff --git a/actions/assemble_message.py b/actions/assemble_message.py index 3b6def5..84b1da1 100644 --- a/actions/assemble_message.py +++ b/actions/assemble_message.py @@ -14,22 +14,40 @@ # See the License for the specific language governing permissions and # limitations under the License. -from datetime import timedelta +import os +import codecs + + +from jinja2 import Environment + from st2common.runners.base_action import Action -from lib import community __all__ = [ 'AssembleMessageAction' ] +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + class AssembleMessageAction(Action): def run(self, forum_posts, github_data, template_path): """ Build and return rendered text. """ - from pprint import pprint - pprint('aaaaa') - pprint(forum_posts) - pprint(github_data) + + template_path = os.path.join(BASE_DIR, '../', template_path) + template_path = os.path.abspath(template_path) + + with codecs.open(template_path, encoding='utf-8') as fp: + template_data = fp.read() + + template_context = { + 'github_data': github_data, + 'forum_posts': forum_posts + } + + # Add all information to the template context and render the template + env = Environment(trim_blocks=True, lstrip_blocks=True) + rendered = env.from_string(template_data).render(template_context) + return rendered diff --git a/actions/lib/community.py b/actions/lib/community.py deleted file mode 100644 index 273726a..0000000 --- a/actions/lib/community.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -import codecs - -from datetime import datetime -from datetime import timedelta - -from github import Github -from jinja2 import Environment - -from lib.forum_posts import get_forum_posts - -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) - - -def build_text(logger, delta=timedelta(days=1, minutes=10)): - """ - Retrieve the following information for a given time period and return slack - text to be sent: - - * Github issues and pull requests for the provided users - * Forum posts - """ - github_users = github_users or [] - - template_path = os.path.join(BASE_DIR, '../../', template_path) - template_path = os.path.abspath(template_path) - - with codecs.open(template_path, encoding='utf-8') as fp: - template_data = fp.read() - - template_context = { - 'github': {}, - 'forum_posts': [] - } - - # 1. Retrieve Github stats for the provided Github users / organizations - github = Github(token) - - for user in github_users: - logger.debug('Retrieving Github issues and prs for user %s' % (user)) - - github_user = github.get_user(user) - - # Iterate over all the repos - # TODO - this is slow, use whitelist / blacklist? - user_issues = [] - user_prs = [] - - for repo in github_user.get_repos(): - result = get_issues_and_prs_for_repo(repo=repo, delta=delta) - user_issues.extend(result['issues']) - user_prs.extend(result['prs']) - - # NOTE: Jinja doesn't support referencing dict keys with "-" in them - username = user.replace('-', '_').lower() - template_context['github'][username] = { - 'user': user, - 'issues': user_issues, - 'pulls': user_prs - } - - # 2. Retrieve forum posts from forum.stackstorm.com - logger.debug('Retrieving forum posts') - - forum_posts = get_forum_posts(feed_url=forum_feed_url, delta=delta) - template_context['forum_posts'] = forum_posts - - # Add all information to the template context and render the template - env = Environment(trim_blocks=True, lstrip_blocks=True) - rendered = env.from_string(template_data).render(template_context) - return rendered diff --git a/actions/lib/github_issues.py b/actions/lib/github_issues.py index 87ceb56..2a8449b 100644 --- a/actions/lib/github_issues.py +++ b/actions/lib/github_issues.py @@ -27,17 +27,21 @@ def get_issues_and_prs_for_repo(repo, time_delta): """ result = { 'issues': [], - 'prs': [] + 'pulls': [] } since_dt = (datetime.now() - time_delta) issues = list(repo.get_issues(since=since_dt)) for issue in issues: + # Convert Python object in a native Python type (dict) + issue_dict = issue.raw_data + issue_dict['repository'] = issue.repository.raw_data + if issue.pull_request: - result['prs'].append(issue) + result['pulls'].append(issue_dict) else: - result['issues'].append(issue) + result['issues'].append(issue_dict) return result @@ -47,13 +51,15 @@ def get_issues_and_prs_for_user(github_user, time_delta): Retrieve issues and PRs for all the Github repos for the provided user. """ result = { + 'username': github_user.login.replace('-', '_').lower(), + 'username_friendly': github_user.login, 'issues': [], - 'prs': [] + 'pulls': [] } for repo in github_user.get_repos(): - result = get_issues_and_prs_for_repo(repo=repo, time_delta=time_delta) - result['issues'].extend(result['issues']) - result['prs'].extend(result['prs']) + repo_result = get_issues_and_prs_for_repo(repo=repo, time_delta=time_delta) + result['issues'].extend(repo_result['issues']) + result['pulls'].extend(repo_result['pulls']) return result diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/build-and-message.yaml index 8364579..bf5e370 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/build-and-message.yaml @@ -43,7 +43,7 @@ tasks: do: - send_message_to_slack publish: - - message: <% result().result.body %> + - message: <% result().result %> send_message_to_slack: action: slack.chat.postMessage input: diff --git a/etc/message_template.j2 b/etc/message_template.j2 index 09a45ae..c3b9879 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -1,46 +1,5 @@ Good morning, team. Here's what happened yesterday at StackStorm. -*StackStorm Github Organization* - -*Pull Requests* ({{ github.stackstorm.pulls|length}} new pull request(s)): -{% if github.stackstorm.pulls %} - {% for issue in github.stackstorm.pulls -%} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} -{% else %} -None. -{% endif %} - -*Issues* ({{ github.stackstorm.issues|length}} new issue(s)): -{% if github.stackstorm.issues %} - {% for issue in github.stackstorm.issues -%} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} -{% else %} -None. -{% endif %} - -*StackStorm-Exchange Organization* - -*Pull Requests* ({{ github.stackstorm_exchange.pulls|length}} new pull request(s)): -{% if github.stackstorm_exchange.pulls %} - {% for issue in github.stackstorm_exchange.pulls -%} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} -{% else %} -None. -{% endif %} - -*Issues* ({{ github.stackstorm_exchange.issues|length}} new issue(s)): -{% if github.stackstorm_exchange.issues %} - {% for issue in github.stackstorm.issues -%} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} -{% else %} -None. -{% endif %} - - *Forum Posts* (*{{ forum_posts|length }}* new post(s)) {% if forum_posts %} {% for post in forum_posts -%} @@ -49,3 +8,26 @@ None. {% else %} None. {% endif %} + +{%+ for github_user_data in github_data %} + *{{ github_user_data['username_friendly'] }} Github Organization* + + *Issues* ({{ github_user_data['issues']|length}} new issue(s)): + {% if github_user_data['issues'] %} + {% for issue in github_user_data['issues'] %} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} + {% else %} + None. + {% endif %} + + *Pull Requests* ({{ github_user_data['pulls']|length}} new issue(s)): + {% if github_user_data['pulls'] %} + {% for issue in github_user_data['pulls'] %} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} + {% else %} + None. + {% endif %} + +{% endfor %} From e230308f0ac144912d30a612f17ea22c7e2dd9e3 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 23:34:33 +0100 Subject: [PATCH 22/28] Update rules, rename action. --- ...l => retrieve_data_and_send_daily_stats_to_slack.yaml} | 4 ++-- ...l => retrieve_data_and_send_daily_stats_to_slack.yaml} | 2 +- rules/post_daily_summary_to_slack.yaml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename actions/{build-and-message.yaml => retrieve_data_and_send_daily_stats_to_slack.yaml} (82%) rename actions/workflows/{build-and-message.yaml => retrieve_data_and_send_daily_stats_to_slack.yaml} (92%) diff --git a/actions/build-and-message.yaml b/actions/retrieve_data_and_send_daily_stats_to_slack.yaml similarity index 82% rename from actions/build-and-message.yaml rename to actions/retrieve_data_and_send_daily_stats_to_slack.yaml index e4f15cd..7b2f163 100644 --- a/actions/build-and-message.yaml +++ b/actions/retrieve_data_and_send_daily_stats_to_slack.yaml @@ -1,9 +1,9 @@ --- -name: retrieve_data_and_send_message_to_slack +name: retrieve_data_and_send_daily_stats_to_slack pack: st2community description: Retrieve daily statistics and send message to Slack channel. runner_type: orquesta -entry_point: workflows/build-and-message.yaml +entry_point: workflows/retrieve_data_and_send_daily_stats_to_slack.yaml enabled: true parameters: channel: diff --git a/actions/workflows/build-and-message.yaml b/actions/workflows/retrieve_data_and_send_daily_stats_to_slack.yaml similarity index 92% rename from actions/workflows/build-and-message.yaml rename to actions/workflows/retrieve_data_and_send_daily_stats_to_slack.yaml index bf5e370..cc1333c 100644 --- a/actions/workflows/build-and-message.yaml +++ b/actions/workflows/retrieve_data_and_send_daily_stats_to_slack.yaml @@ -1,6 +1,6 @@ version: 1.0 -description: Send daily summary to given Slack channel. +description: Retrieve data from various sources and daily summary to given Slack channel. input: - github_users diff --git a/rules/post_daily_summary_to_slack.yaml b/rules/post_daily_summary_to_slack.yaml index 388aff9..2ddd7ed 100644 --- a/rules/post_daily_summary_to_slack.yaml +++ b/rules/post_daily_summary_to_slack.yaml @@ -1,7 +1,7 @@ --- -name: "stackstorm_update" +name: "post_daily_summary_to_slack" pack: "st2community" -description: "Gather and publish various statistics for previous 24 hours." +description: "Gather and publish various statistics for previous 24 hours to Slack." enabled: true trigger: @@ -14,12 +14,12 @@ trigger: second: 0 action: - ref: "st2community.build-and-message" + ref: "st2community.retrieve_data_and_send_daily_stats_to_slack" parameters: + channel: "#stackstorm" github_users: - "StackStorm" - "StackStorm-Exchange" - channel: "#stackstorm" delta: days: 1 minutes: 10 From d2480bd5587d7299294fdedbb8fbd93abcd5ae9c Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Mon, 4 Feb 2019 23:45:23 +0100 Subject: [PATCH 23/28] Fix message formatting in the Jinja template. --- etc/message_template.j2 | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index c3b9879..c477512 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -2,32 +2,32 @@ Good morning, team. Here's what happened yesterday at StackStorm. *Forum Posts* (*{{ forum_posts|length }}* new post(s)) {% if forum_posts %} - {% for post in forum_posts -%} + {% for post in forum_posts %} • <{{ post.link }}|{{ post.title }}> by {{ post.author }} {% endfor %} {% else %} None. {% endif %} -{%+ for github_user_data in github_data %} - *{{ github_user_data['username_friendly'] }} Github Organization* +{% for github_user_data in github_data %} +*{{ github_user_data['username_friendly'] }} Github Organization* - *Issues* ({{ github_user_data['issues']|length}} new issue(s)): - {% if github_user_data['issues'] %} - {% for issue in github_user_data['issues'] %} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} - {% else %} - None. - {% endif %} - - *Pull Requests* ({{ github_user_data['pulls']|length}} new issue(s)): - {% if github_user_data['pulls'] %} - {% for issue in github_user_data['pulls'] %} - • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> - {% endfor %} - {% else %} - None. - {% endif %} +*Issues* ({{ github_user_data['issues']|length}} new issue(s)): +{% if github_user_data['issues'] %} + {% for issue in github_user_data['issues'] %} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} +*Pull Requests* ({{ github_user_data['pulls']|length}} new pull request(s)): +{% if github_user_data['pulls'] %} + {% for issue in github_user_data['pulls'] %} + • <{{ issue.repository.html_url }}|{{ issue.repository.name }}>: <{{ issue.pull_request.html_url }}|{{ issue.title }}> by <{{ issue.user.html_url }}|{{ issue.user.login }}> + {% endfor %} +{% else %} +None. +{% endif %} +\n {% endfor %} From f6975afe191469ab9bfa36b62c18985ac7311676 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Tue, 5 Feb 2019 10:21:08 +0100 Subject: [PATCH 24/28] For explicitness sake, change config option name from token to github_token. --- actions/get_github_issues.yaml | 2 +- config.schema.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/get_github_issues.yaml b/actions/get_github_issues.yaml index 99da9e6..21f4e11 100644 --- a/actions/get_github_issues.yaml +++ b/actions/get_github_issues.yaml @@ -11,7 +11,7 @@ parameters: type: string secret: true required: true - default: "{{ config_context.token }}" + default: "{{ config_context.github_token }}" username: description: "Username of the Github user / organization to retrieve issues for." type: string diff --git a/config.schema.yaml b/config.schema.yaml index 3e63097..d2782bb 100644 --- a/config.schema.yaml +++ b/config.schema.yaml @@ -1,5 +1,5 @@ --- -token: +github_token: description: "Github authentication token." type: "string" secret: true From eaa869c40089421ff2a2a5a76d6c68f1984ff9d3 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Tue, 5 Feb 2019 10:21:23 +0100 Subject: [PATCH 25/28] Update template. --- etc/message_template.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/message_template.j2 b/etc/message_template.j2 index c477512..6b94764 100644 --- a/etc/message_template.j2 +++ b/etc/message_template.j2 @@ -29,5 +29,5 @@ None. {% else %} None. {% endif %} -\n + {% endfor %} From e9179018a36a276948848ab54eb0ec5948a55911 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Tue, 5 Feb 2019 11:06:45 +0100 Subject: [PATCH 26/28] Use temporary workaround until we deploy new version of st2 to cicd. --- actions/get_forum_posts.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/actions/get_forum_posts.yaml b/actions/get_forum_posts.yaml index 5d3db09..3eb01b8 100644 --- a/actions/get_forum_posts.yaml +++ b/actions/get_forum_posts.yaml @@ -10,7 +10,10 @@ parameters: description: "Forum RSS feed URL." type: string required: true - default: "{{ config_context.forum_feed_url }}" + # TODO: Temporary workaround until version with fix in https://github.com/StackStorm/st2/pull/4531 + # is deployed to cicd + default: "https://forum.stackstorm.com/latest.rss" + #default: "{{ config_context.forum_feed_url }}" delta: description: "Time period to retrieve forum posts for." type: object From 64290f49ac976452051ce33dc636ab6c4071cee8 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Tue, 5 Feb 2019 12:55:21 +0100 Subject: [PATCH 27/28] Temporary workaround until new version of st2 is deployed to cicd. --- actions/get_github_issues.py | 4 +++- actions/get_github_issues.yaml | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/actions/get_github_issues.py b/actions/get_github_issues.py index 91134aa..c267ffa 100644 --- a/actions/get_github_issues.py +++ b/actions/get_github_issues.py @@ -26,8 +26,10 @@ class GetGithubIssuesAction(Action): - def run(self, token, username, delta): + #def run(self, token, username, delta): + def run(self, username, delta, token=None): time_delta = get_timedelta_object_from_delta_arg(delta) + token = self.config['github_token'] github = Github(token) github_user = github.get_user(username) result = get_issues_and_prs_for_user(github_user=github_user, time_delta=time_delta) diff --git a/actions/get_github_issues.yaml b/actions/get_github_issues.yaml index 21f4e11..86c68c4 100644 --- a/actions/get_github_issues.yaml +++ b/actions/get_github_issues.yaml @@ -10,8 +10,9 @@ parameters: description: "Github token used to authenticate." type: string secret: true - required: true - default: "{{ config_context.github_token }}" + # TODO: Uncomment when new version of st2 is deployed to cicd + #required: false + #default: "{{ config_context.github_token }}" username: description: "Username of the Github user / organization to retrieve issues for." type: string From 51b2e86a027d1868d9a5d554a1c9f8998c39d4cc Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Tue, 5 Feb 2019 13:02:39 +0100 Subject: [PATCH 28/28] Bump pack version. --- pack.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pack.yaml b/pack.yaml index f76cdd8..5af279d 100644 --- a/pack.yaml +++ b/pack.yaml @@ -2,7 +2,7 @@ ref: st2community name: st2community description: Pack to help manage Stackstorm's community. -version: 0.1.1 +version: 0.2.0 keywords: - StackStorm - Community