From 84e0449cbe39abfa1809063cc4166e657963fba8 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 16:05:02 +0100 Subject: [PATCH 01/18] Add a logger and update the config handling --- baldrick/github/github_api.py | 76 +++++++++---------- baldrick/github/tests/test_github_api.py | 4 +- baldrick/plugins/github_pull_requests.py | 11 +-- .../plugins/tests/test_circleci_artifacts.py | 4 +- .../plugins/tests/test_github_milestones.py | 4 +- .../tests/test_github_pull_requests.py | 4 +- baldrick/plugins/tests/test_github_pushes.py | 4 +- .../tests/test_github_towncrier_changelog.py | 4 +- 8 files changed, 55 insertions(+), 56 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 8830b72..84cd5a0 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -7,9 +7,10 @@ import dateutil.parser from flask import current_app +from loguru import logger from ttldict import TTLOrderedDict -from baldrick.config import loads +from baldrick.config import loads, Config from baldrick.github.github_auth import github_request_headers __all__ = ['GitHubHandler', 'IssueHandler', 'RepoHandler', 'PullRequestHandler'] @@ -17,8 +18,7 @@ HOST = "https://api.github.com" HOST_NONAPI = "https://github.com" -cfg_cache = TTLOrderedDict(default_ttl=60 * 60) - +file_cache = TTLOrderedDict(default_ttl=60) def paged_github_json_request(url, headers=None): @@ -70,9 +70,12 @@ def _headers(self): def _url_contents(self): return f'{HOST}/repos/{self.repo}/contents/' - def get_file_contents(self, path_to_file, branch=None): - if not branch: - branch = 'master' + def get_file_contents(self, path_to_file, branch='master'): + global file_cache + cache_key = f"{self.repo}:{path_to_file}@{branch}" + if cache_key in file_cache: + return file_cache[cache_key] + url_file = self._url_contents + path_to_file data = {'ref': branch} response = requests.get(url_file, params=data, headers=self._headers) @@ -80,10 +83,12 @@ def get_file_contents(self, path_to_file, branch=None): raise FileNotFoundError(url_file) assert response.ok, response.content contents_base64 = response.json()['content'] - return base64.b64decode(contents_base64).decode() + contents = base64.b64decode(contents_base64).decode() - def get_repo_config(self, branch=None, path_to_file='pyproject.toml', - warn_on_failure=True): + file_cache[cache_key] = contents + return contents + + def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): """ Load configuration from the repository. @@ -97,32 +102,37 @@ def get_repo_config(self, branch=None, path_to_file='pyproject.toml', Path to the ``pyproject.toml`` file in the repository. Will default to the root of the repository. - warn_on_failure : `bool` - Emit warning on failure to load the pyproject file. - Returns ------- cfg : `baldrick.config.Config` Configuration parameters. """ - # Allow non-existent file but raise error when cannot parse + app_config = current_app.conf.copy() + fallback_config = Config() + repo_config = Config() + try: file_content = self.get_file_contents(path_to_file, branch=branch) - return loads(file_content, tool=current_app.bot_username) - except Exception as e: - # Attempt to load the fallback config just in case + except FileNotFoundError: + logger.debug(f"No config file found in {self.repo} on branch {branch}.") + file_content = None + + if file_content: + try: + config = loads(file_content, tool=current_app.bot_username) + except Exception: + logger.exception("Failed to load config in {self.repo} on branch {branch}.") + if getattr(current_app, "fall_back_config", None): try: - return loads(file_content, tool=current_app.fall_back_config) - except Exception: # pragma: no cover - pass + fallback_config = loads(file_content, tool=current_app.fall_back_config) + except Exception: + logger.info("Failed to load fallback config in {self.repo} on branch {branch}.") - if warn_on_failure: - warnings.warn(str(e)) - - # Empty dict means calling code set the default - repo_config = current_app.conf.copy() + # Priority is 1) repo_config 2) fallback_config 3) app_config + app_config.update_from_config(fallback_config) + repo_config.update_from_config(app_config) return repo_config @@ -134,14 +144,7 @@ def get_config_value(self, cfg_key, cfg_default=None, branch=None): defined, they are extracted from the global app configuration. If this does not exist either, the value is set to the ``cfg_default`` argument. """ - - global cfg_cache - - cfg_cache_key = (self.repo, branch, self.installation) - if cfg_cache_key not in cfg_cache: - cfg_cache[cfg_cache_key] = self.get_repo_config(branch=branch) - - cfg = cfg_cache.get(cfg_cache_key, {}) + cfg = self.get_repo_config(branch=branch) config = current_app.conf.get(cfg_key, {}).copy() config.update(cfg.get(cfg_key, {})) @@ -675,8 +678,7 @@ def get_file_contents(self, path_to_file, branch=None): branch = self.head_branch return super().get_file_contents(path_to_file, branch=branch) - def get_repo_config(self, branch=None, path_to_file='pyproject.toml', - warn_on_failure=True): + def get_repo_config(self, branch=None, path_to_file='pyproject.toml'): """ Load user configuration for bot. @@ -690,9 +692,6 @@ def get_repo_config(self, branch=None, path_to_file='pyproject.toml', Path to the ``pyproject.toml`` file in the repository. Will default to the root of the repository. - warn_on_failure : `bool` - Emit warning on failure to load the pyproject file. - Returns ------- cfg : dict @@ -701,8 +700,7 @@ def get_repo_config(self, branch=None, path_to_file='pyproject.toml', """ if not branch: branch = self.base_branch - return super().get_repo_config(branch=branch, path_to_file=path_to_file, - warn_on_failure=warn_on_failure) + return super().get_repo_config(branch=branch, path_to_file=path_to_file) def has_modified(self, filelist): """Check if PR has modified any of the given list of filename(s).""" diff --git a/baldrick/github/tests/test_github_api.py b/baldrick/github/tests/test_github_api.py index 28aaa2d..8e62b0d 100644 --- a/baldrick/github/tests/test_github_api.py +++ b/baldrick/github/tests/test_github_api.py @@ -5,7 +5,7 @@ import pytest from baldrick.config import loads -from baldrick.github.github_api import (cfg_cache, RepoHandler, IssueHandler, +from baldrick.github.github_api import (file_cache, RepoHandler, IssueHandler, PullRequestHandler) @@ -78,7 +78,7 @@ def test_urls(self): class TestRealRepoHandler: def setup_method(self, method): - cfg_cache.clear() + file_cache.clear() def setup_class(self): self.repo = RepoHandler('astropy/astropy-bot') diff --git a/baldrick/plugins/github_pull_requests.py b/baldrick/plugins/github_pull_requests.py index cabd7e6..e50ae4f 100644 --- a/baldrick/plugins/github_pull_requests.py +++ b/baldrick/plugins/github_pull_requests.py @@ -1,4 +1,5 @@ from flask import current_app +from loguru import logger from baldrick.github.github_api import RepoHandler, PullRequestHandler from baldrick.blueprints.github import github_webhook_handler @@ -82,6 +83,8 @@ def handle_pull_requests(repo_handler, payload, headers): is_new = (event == 'pull_request') & (payload['action'] == 'opened') + logger.debug(f"Processing {event} event for {event} #{number} on {repo_handler.repo}") + return process_pull_request( repo_handler.repo, number, repo_handler.installation, action=payload['action'], is_new=is_new) @@ -96,11 +99,9 @@ def process_pull_request(repository, number, installation, action, pr_config = pr_handler.get_config_value("pull_requests", {}) if not pr_config.get("enabled", False): - return "Skipping PR checks, disabled in config." - - # Disable if the config is not present - if pr_config is None: - return + msg = "Skipping PR checks, disabled in config." + logger.debug(msg) + return msg # Don't comment on closed PR if pr_handler.is_closed: diff --git a/baldrick/plugins/tests/test_circleci_artifacts.py b/baldrick/plugins/tests/test_circleci_artifacts.py index b50d624..51dde56 100644 --- a/baldrick/plugins/tests/test_circleci_artifacts.py +++ b/baldrick/plugins/tests/test_circleci_artifacts.py @@ -1,7 +1,7 @@ import logging from unittest.mock import patch, call -from baldrick.github.github_api import cfg_cache +from baldrick.github.github_api import file_cache from baldrick.github.github_api import RepoHandler from baldrick.plugins.circleci_artifacts import set_commit_status_for_artifacts @@ -48,7 +48,7 @@ def setup_method(self, method): self.repo_handler = RepoHandler("nota/repo", "1234") self.get_file_contents = self.get_file_contents_mock.start() - cfg_cache.clear() + file_cache.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_milestones.py b/baldrick/plugins/tests/test_github_milestones.py index 275e913..191a8df 100644 --- a/baldrick/plugins/tests/test_github_milestones.py +++ b/baldrick/plugins/tests/test_github_milestones.py @@ -1,6 +1,6 @@ from unittest.mock import patch, PropertyMock -from baldrick.github.github_api import cfg_cache +from baldrick.github.github_api import file_cache from baldrick.github.github_api import RepoHandler, PullRequestHandler from baldrick.plugins.github_milestones import process_milestone, MISSING_MESSAGE, PRESENT_MESSAGE @@ -42,7 +42,7 @@ def setup_method(self, method): self.milestone.return_value = None self.get_file_contents = self.get_file_contents_mock.start() - cfg_cache.clear() + file_cache.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_pull_requests.py b/baldrick/plugins/tests/test_github_pull_requests.py index 775ac28..689ce79 100644 --- a/baldrick/plugins/tests/test_github_pull_requests.py +++ b/baldrick/plugins/tests/test_github_pull_requests.py @@ -2,7 +2,7 @@ from copy import copy from unittest.mock import MagicMock, patch, PropertyMock -from baldrick.github.github_api import cfg_cache +from baldrick.github.github_api import file_cache from baldrick.plugins.github_pull_requests import (pull_request_handler, PULL_REQUEST_CHECKS) @@ -52,7 +52,7 @@ def setup_method(self, method): self.get_installation_token.return_value = 'abcdefg' self.labels.return_value = [] - cfg_cache.clear() + file_cache.clear() def teardown_method(self, method): self.requests_get_mock.stop() diff --git a/baldrick/plugins/tests/test_github_pushes.py b/baldrick/plugins/tests/test_github_pushes.py index 22a571d..4cdc7bf 100644 --- a/baldrick/plugins/tests/test_github_pushes.py +++ b/baldrick/plugins/tests/test_github_pushes.py @@ -2,7 +2,7 @@ from copy import copy from unittest.mock import MagicMock, patch -from baldrick.github.github_api import cfg_cache +from baldrick.github.github_api import file_cache from baldrick.plugins.github_pushes import push_handler, PUSH_HANDLERS test_handler = MagicMock() @@ -38,7 +38,7 @@ def setup_method(self, method): self.get_installation_token.return_value = 'abcdefg' - cfg_cache.clear() + file_cache.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_towncrier_changelog.py b/baldrick/plugins/tests/test_github_towncrier_changelog.py index be514f8..5cdc528 100644 --- a/baldrick/plugins/tests/test_github_towncrier_changelog.py +++ b/baldrick/plugins/tests/test_github_towncrier_changelog.py @@ -3,7 +3,7 @@ import pytest -from baldrick.github.github_api import cfg_cache +from baldrick.github.github_api import file_cache from baldrick.github.github_api import RepoHandler, PullRequestHandler from baldrick.plugins.github_towncrier_changelog import process_towncrier_changelog @@ -35,7 +35,7 @@ def setup_method(self, method): self.get_file_contents = self.get_file_contents_mock.start() self.modified_files = self.modified_files_mock.start() - cfg_cache.clear() + file_cache.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() From b66344a6a89ff79f0f4a3ec530c0cff8ecfa6ef0 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 16:49:35 +0100 Subject: [PATCH 02/18] Push the default flask logging through loguru --- baldrick/__init__.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/baldrick/__init__.py b/baldrick/__init__.py index 0482b95..4116a7a 100644 --- a/baldrick/__init__.py +++ b/baldrick/__init__.py @@ -1,3 +1,8 @@ +import logging + +from loguru import logger +from flask.logging import default_handler + from baldrick import github # noqa __all__ = ['create_app', '__version__'] @@ -7,6 +12,23 @@ GLOBAL_TOML = '' +class InterceptHandler(logging.Handler): + log_level_to_name = {5: 'TRACE', + 10: 'DEBUG', + 20: 'INFO', + 25: 'SUCCESS', + 30: 'WARNING', + 40: 'ERROR', + 50: 'CRITICAL'} + + def emit(self, record): + # Retrieve context where the logging call occurred, this happens to be in the 6th frame upward + logger_opt = logger.opt(depth=6, exception=record.exc_info) + logger_opt.log(self.log_level_to_name.get(record.levelno, record.levelno), record.getMessage()) + +logging.basicConfig(handlers=[InterceptHandler()], level=0) + + def _init_global_toml(): import os global GLOBAL_TOML @@ -45,6 +67,7 @@ def create_app(name, register_blueprints=True): from baldrick.blueprints import github_blueprint, circleci_blueprint app = Flask(name) + app.logger.removeHandler(default_handler) app.wsgi_app = ProxyFix(app.wsgi_app) From 0c1f181e9450bafedcbf8a115e78e25e87b0c90b Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 17:03:23 +0100 Subject: [PATCH 03/18] Add loguru to deps --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 572b238..85f1740 100644 --- a/setup.py +++ b/setup.py @@ -27,4 +27,5 @@ "humanize", "towncrier", "toml", + "loguru", "ttldict"]) From 9e8f97c16d115d8be56b273d795f7e8f35a9f648 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 17:12:47 +0100 Subject: [PATCH 04/18] Fixes --- baldrick/github/github_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 84cd5a0..6f54612 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -122,13 +122,13 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): try: config = loads(file_content, tool=current_app.bot_username) except Exception: - logger.exception("Failed to load config in {self.repo} on branch {branch}.") + logger.exception(f"Failed to load config in {self.repo} on branch {branch}.") if getattr(current_app, "fall_back_config", None): try: fallback_config = loads(file_content, tool=current_app.fall_back_config) except Exception: - logger.info("Failed to load fallback config in {self.repo} on branch {branch}.") + logger.debug(f"Didn't find a fallback config in {self.repo} on branch {branch}.") # Priority is 1) repo_config 2) fallback_config 3) app_config app_config.update_from_config(fallback_config) From 1deaf857f5b987a2923f30dd95cd820e82ed5f20 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 17:48:09 +0100 Subject: [PATCH 05/18] more logging and stuff --- baldrick/__init__.py | 19 +---------- baldrick/github/github_api.py | 9 +++++- baldrick/logging.py | 32 +++++++++++++++++++ baldrick/plugins/circleci_artifacts.py | 13 ++++---- baldrick/plugins/github_milestones.py | 6 +++- baldrick/plugins/github_pull_requests.py | 2 +- .../plugins/github_towncrier_changelog.py | 3 ++ 7 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 baldrick/logging.py diff --git a/baldrick/__init__.py b/baldrick/__init__.py index 4116a7a..e264e9f 100644 --- a/baldrick/__init__.py +++ b/baldrick/__init__.py @@ -1,8 +1,8 @@ import logging -from loguru import logger from flask.logging import default_handler +import baldrick.logging from baldrick import github # noqa __all__ = ['create_app', '__version__'] @@ -12,23 +12,6 @@ GLOBAL_TOML = '' -class InterceptHandler(logging.Handler): - log_level_to_name = {5: 'TRACE', - 10: 'DEBUG', - 20: 'INFO', - 25: 'SUCCESS', - 30: 'WARNING', - 40: 'ERROR', - 50: 'CRITICAL'} - - def emit(self, record): - # Retrieve context where the logging call occurred, this happens to be in the 6th frame upward - logger_opt = logger.opt(depth=6, exception=record.exc_info) - logger_opt.log(self.log_level_to_name.get(record.levelno, record.levelno), record.getMessage()) - -logging.basicConfig(handlers=[InterceptHandler()], level=0) - - def _init_global_toml(): import os global GLOBAL_TOML diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 6f54612..e256fd9 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -73,8 +73,13 @@ def _url_contents(self): def get_file_contents(self, path_to_file, branch='master'): global file_cache cache_key = f"{self.repo}:{path_to_file}@{branch}" - if cache_key in file_cache: + + # It seems that this is the only safe way to do this with + # TTLOrderedDict + try: return file_cache[cache_key] + except KeyError: + pass url_file = self._url_contents + path_to_file data = {'ref': branch} @@ -134,6 +139,8 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): app_config.update_from_config(fallback_config) repo_config.update_from_config(app_config) + logger.trace(repo_config) + return repo_config def get_config_value(self, cfg_key, cfg_default=None, branch=None): diff --git a/baldrick/logging.py b/baldrick/logging.py new file mode 100644 index 0000000..2232ba3 --- /dev/null +++ b/baldrick/logging.py @@ -0,0 +1,32 @@ +import logging + +from os import environ + +from loguru import logger + +LOG_LEVEL_TO_NAME = {5: 'TRACE', + 10: 'DEBUG', + 20: 'INFO', + 25: 'SUCCESS', + 30: 'WARNING', + 40: 'ERROR', + 50: 'CRITICAL'} + +LOG_NAME_TO_LEVEL = {v: k for k, v in LOG_LEVEL_TO_NAME.items()} + +class InterceptHandler(logging.Handler): + """ + Handler to route stdlib logs to loguru + """ + def emit(self, record): + # Retrieve context where the logging call occurred, this happens to be in the 6th frame upward + logger_opt = logger.opt(depth=6, exception=record.exc_info) + + # Log with name to support formatting if known, otherwise use the level number + logger_opt.log(LOG_LEVEL_TO_NAME.get(record.levelno, record.levelno), record.getMessage()) + +# Retrieve default log level from same environment variable as loguru +log_level = LOG_NAME_TO_LEVEL.get(environ.get("BALDRICK_LOG_LEVEL", "INFO"), "INFO") + +# Configuration for stdlib logger to route messages to loguru; must be run before other imports +logging.basicConfig(handlers=[InterceptHandler()], level=log_level) diff --git a/baldrick/plugins/circleci_artifacts.py b/baldrick/plugins/circleci_artifacts.py index 66a7dc0..8293381 100644 --- a/baldrick/plugins/circleci_artifacts.py +++ b/baldrick/plugins/circleci_artifacts.py @@ -1,9 +1,8 @@ -import logging import requests -from baldrick.blueprints.circleci import circleci_webhook_handler +from loguru import logger -LOGGER = logging.getLogger(__name__) +from baldrick.blueprints.circleci import circleci_webhook_handler @circleci_webhook_handler @@ -11,10 +10,12 @@ def set_commit_status_for_artifacts(repo_handler, payload, headers): ci_config = repo_handler.get_config_value("circleci_artifacts", {}) if not ci_config.get("enabled", False): - return "Skipping artifact check, disabled in config." + msg = "Skipping artifact check, disabled in config." + logger.debug(msg) + return msg if payload['status'] == 'success': - LOGGER.info(r"Got successful call for repo: %s/%s", payload['username'], payload['reponame']) + logger.info(f"Got successful call for repo: {payload['username']}{payload['reponame']}") artifacts = get_artifacts_from_build(payload) for name, config in ci_config.items(): @@ -23,7 +24,7 @@ def set_commit_status_for_artifacts(repo_handler, payload, headers): continue url = get_documentation_url_from_artifacts(artifacts, config['url']) - LOGGER.debug("Found artifact: %s", url) + logger.debug("Found artifact: {url}") if url: repo_handler.set_status("success", diff --git a/baldrick/plugins/github_milestones.py b/baldrick/plugins/github_milestones.py index 169e0bf..fe09e3c 100644 --- a/baldrick/plugins/github_milestones.py +++ b/baldrick/plugins/github_milestones.py @@ -1,3 +1,5 @@ +from loguru import logger + from baldrick.plugins.github_pull_requests import pull_request_handler MISSING_MESSAGE = 'This pull request has no milestone set.' @@ -9,11 +11,13 @@ def process_milestone(pr_handler, repo_handler): """ A very simple set a failing status if the milestone is not set. """ - mc_config = pr_handler.get_config_value("milestones", {}) if not mc_config.get('enabled', False): + logger.debug("Skipping milestone plugin as disabled in config") return + logger.debug(f"Checking milestones on {pr_handler.repo}#{pr_handler.number}") + fail_message = mc_config.get("missing_message", MISSING_MESSAGE) pass_message = mc_config.get("present_message", PRESENT_MESSAGE) diff --git a/baldrick/plugins/github_pull_requests.py b/baldrick/plugins/github_pull_requests.py index e50ae4f..0737ed5 100644 --- a/baldrick/plugins/github_pull_requests.py +++ b/baldrick/plugins/github_pull_requests.py @@ -83,7 +83,7 @@ def handle_pull_requests(repo_handler, payload, headers): is_new = (event == 'pull_request') & (payload['action'] == 'opened') - logger.debug(f"Processing {event} event for {event} #{number} on {repo_handler.repo}") + logger.debug(f"Processing event {event} #{number} on {repo_handler.repo}") return process_pull_request( repo_handler.repo, number, repo_handler.installation, diff --git a/baldrick/plugins/github_towncrier_changelog.py b/baldrick/plugins/github_towncrier_changelog.py index 3b51cde..9b0b515 100644 --- a/baldrick/plugins/github_towncrier_changelog.py +++ b/baldrick/plugins/github_towncrier_changelog.py @@ -2,6 +2,7 @@ import re from collections import OrderedDict +from loguru import logger from toml import loads from .github_pull_requests import pull_request_handler @@ -119,8 +120,10 @@ def process_towncrier_changelog(pr_handler, repo_handler): cl_config = pr_handler.get_config_value('towncrier_changelog', {}) if not cl_config.get('enabled', False): + logger.debug("Skipping towncrier changelog plugin as disabled in config") return None + logger.debug(f"Checking towncrier changelog on {pr_handler.repo}#{pr_handler.number}") skip_label = cl_config.get('changelog_skip_label', None) config = load_towncrier_config(pr_handler) From b5d8d90ef6afefad8732a543b989806acb1fb27d Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 17:53:42 +0100 Subject: [PATCH 06/18] where has my logging gone? --- baldrick/github/github_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index e256fd9..e330d76 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -139,7 +139,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): app_config.update_from_config(fallback_config) repo_config.update_from_config(app_config) - logger.trace(repo_config) + logger.trace(f"Got this repo_config {repo_config}") return repo_config From 0bd278016a34d3112a6fbf1e7074dab0dafa95eb Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 17:59:33 +0100 Subject: [PATCH 07/18] even more log --- baldrick/github/github_api.py | 2 +- baldrick/plugins/circleci_artifacts.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index e330d76..25919a1 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -139,7 +139,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): app_config.update_from_config(fallback_config) repo_config.update_from_config(app_config) - logger.trace(f"Got this repo_config {repo_config}") + logger.debug(f"Got this repo_config {repo_config}") return repo_config diff --git a/baldrick/plugins/circleci_artifacts.py b/baldrick/plugins/circleci_artifacts.py index 8293381..1e42da3 100644 --- a/baldrick/plugins/circleci_artifacts.py +++ b/baldrick/plugins/circleci_artifacts.py @@ -15,7 +15,7 @@ def set_commit_status_for_artifacts(repo_handler, payload, headers): return msg if payload['status'] == 'success': - logger.info(f"Got successful call for repo: {payload['username']}{payload['reponame']}") + logger.info(f"Got CircleCI 'success' status for repo: {payload['username']}/{payload['reponame']}") artifacts = get_artifacts_from_build(payload) for name, config in ci_config.items(): @@ -24,7 +24,7 @@ def set_commit_status_for_artifacts(repo_handler, payload, headers): continue url = get_documentation_url_from_artifacts(artifacts, config['url']) - logger.debug("Found artifact: {url}") + logger.debug(f"Found artifact: {url}") if url: repo_handler.set_status("success", From 05dfa5e2a058b43c51798abd7e3259bdbb2737fe Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 18:04:04 +0100 Subject: [PATCH 08/18] what is happening --- baldrick/github/github_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 25919a1..be8ad0f 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -126,6 +126,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): if file_content: try: config = loads(file_content, tool=current_app.bot_username) + logger.debug(f"Got the following config from {self.repo}@{branch}: {config}") except Exception: logger.exception(f"Failed to load config in {self.repo} on branch {branch}.") @@ -139,7 +140,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): app_config.update_from_config(fallback_config) repo_config.update_from_config(app_config) - logger.debug(f"Got this repo_config {repo_config}") + logger.debug(f"Got this combined config {repo_config}") return repo_config From fae5c213f766ffede375869de7e506ac9a88d3fe Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Tue, 3 Sep 2019 18:11:35 +0100 Subject: [PATCH 09/18] Reorder config priority implementation --- baldrick/github/github_api.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index be8ad0f..b6443d2 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -137,12 +137,14 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): logger.debug(f"Didn't find a fallback config in {self.repo} on branch {branch}.") # Priority is 1) repo_config 2) fallback_config 3) app_config + logger.debug(f"{app_config}, {fallback_config}") app_config.update_from_config(fallback_config) - repo_config.update_from_config(app_config) + logger.debug(f"{app_config}, {repo_config}") + app_config.update_from_config(repo_config) - logger.debug(f"Got this combined config {repo_config}") + logger.debug(f"Got this combined config {app_config}") - return repo_config + return app_config def get_config_value(self, cfg_key, cfg_default=None, branch=None): """ From 7e8904a67f13b6f8b9e4d6175ae1df16c44a7d4f Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 10:11:28 +0100 Subject: [PATCH 10/18] Fix tests and pytest logging integration --- baldrick/__init__.py | 8 +++--- baldrick/conftest.py | 25 +++++++++++++++++-- baldrick/github/github_api.py | 5 ++-- .../plugins/tests/test_circleci_artifacts.py | 3 ++- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/baldrick/__init__.py b/baldrick/__init__.py index e264e9f..d943be8 100644 --- a/baldrick/__init__.py +++ b/baldrick/__init__.py @@ -1,8 +1,6 @@ +import os import logging -from flask.logging import default_handler - -import baldrick.logging from baldrick import github # noqa __all__ = ['create_app', '__version__'] @@ -37,7 +35,8 @@ def create_app(name, register_blueprints=True): app """ - import os + # Setup loguru integration, must be run before import flask. + import baldrick.logging # noqa from flask import Flask @@ -50,7 +49,6 @@ def create_app(name, register_blueprints=True): from baldrick.blueprints import github_blueprint, circleci_blueprint app = Flask(name) - app.logger.removeHandler(default_handler) app.wsgi_app = ProxyFix(app.wsgi_app) diff --git a/baldrick/conftest.py b/baldrick/conftest.py index c3e1089..ce0417d 100644 --- a/baldrick/conftest.py +++ b/baldrick/conftest.py @@ -1,8 +1,8 @@ import os +import logging import pytest - -from baldrick import create_app +from loguru import logger PRIVATE_KEY = """ @@ -38,6 +38,7 @@ @pytest.fixture def app(): + from baldrick import create_app os.environ['GITHUB_APP_INTEGRATION_ID'] = '1234' os.environ['GITHUB_APP_PRIVATE_KEY'] = PRIVATE_KEY return create_app('testbot') @@ -46,3 +47,23 @@ def app(): @pytest.fixture def client(app): return app.test_client() + + +@pytest.fixture +def caplog(caplog): + """ + Override the default pytest caplog fixture to work with loguru. + """ + + # Remove all logging but this redirect to standard logging + logger.remove() + + class PropogateHandler(logging.Handler): + def emit(self, record): + logging.getLogger(record.name).handle(record) + + handler_id = logger.add(PropogateHandler(), format="{message}") + + yield caplog + + logger.remove(handler_id) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index b6443d2..457c2bd 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -125,10 +125,11 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): if file_content: try: - config = loads(file_content, tool=current_app.bot_username) + app_config = loads(file_content, tool=current_app.bot_username) logger.debug(f"Got the following config from {self.repo}@{branch}: {config}") except Exception: - logger.exception(f"Failed to load config in {self.repo} on branch {branch}.") + logger.error( + f"Failed to load config in {self.repo} on branch {branch}, despite finding a pyproject.toml file.") if getattr(current_app, "fall_back_config", None): try: diff --git a/baldrick/plugins/tests/test_circleci_artifacts.py b/baldrick/plugins/tests/test_circleci_artifacts.py index 51dde56..837ee32 100644 --- a/baldrick/plugins/tests/test_circleci_artifacts.py +++ b/baldrick/plugins/tests/test_circleci_artifacts.py @@ -99,7 +99,8 @@ def test_artifacts(self, app, caplog): with caplog.at_level(logging.DEBUG): set_commit_status_for_artifacts(self.repo_handler, self.basic_payload(), {}) - assert len(caplog.records) == 3 + circle_records = [r for r in caplog.records if r.name == 'baldrick.plugins.circleci_artifacts'] + assert len(circle_records) == 3 assert "test/testbot" in caplog.text assert "https://24-88881093-gh.circle-artifacts.com/0/raw-test-output/go-test-report.xml" in caplog.text assert "https://24-88881093-gh.circle-artifacts.com/0/raw-test-output/go-test.out" in caplog.text From 35d403febff5a220295b79ba63d10db10e1e7c0c Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 10:17:49 +0100 Subject: [PATCH 11/18] Add tests to check config fallback priority --- baldrick/github/github_api.py | 2 +- baldrick/github/tests/test_github_api.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 457c2bd..0789f8b 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -125,7 +125,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): if file_content: try: - app_config = loads(file_content, tool=current_app.bot_username) + repo_config = loads(file_content, tool=current_app.bot_username) logger.debug(f"Got the following config from {self.repo}@{branch}: {config}") except Exception: logger.error( diff --git a/baldrick/github/tests/test_github_api.py b/baldrick/github/tests/test_github_api.py index 8e62b0d..c45f424 100644 --- a/baldrick/github/tests/test_github_api.py +++ b/baldrick/github/tests/test_github_api.py @@ -69,8 +69,7 @@ def test_urls(self): TEST_FALLBACK_CONFIG = """ [tool.nottestbot] [tool.nottestbot.pr] -setting1 = 2 -setting2 = 3 +setting1 = 5 setting3 = 4 """ @@ -103,6 +102,18 @@ def test_get_fallback_config(self, app): mock_get.return_value = TEST_FALLBACK_CONFIG + # These are set to False in YAML; defaults must not be used. + assert self.repo.get_config_value('pr')['setting1'] == 5 + assert self.repo.get_config_value('pr')['setting3'] == 4 + + def test_get_fallback_with_primary_config(self, app): + + with app.app_context(): + app.fall_back_config = "nottestbot" + with patch.object(self.repo, 'get_file_contents') as mock_get: # noqa + + mock_get.return_value = TEST_CONFIG + TEST_FALLBACK_CONFIG + # These are set to False in YAML; defaults must not be used. assert self.repo.get_config_value('pr')['setting1'] == 2 assert self.repo.get_config_value('pr')['setting2'] == 3 From 2fafd968b2f65ad9921e72f64253e425ec5efda7 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 10:22:30 +0100 Subject: [PATCH 12/18] pep8 --- baldrick/__init__.py | 1 - baldrick/github/github_api.py | 6 ++---- baldrick/logging.py | 2 ++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/baldrick/__init__.py b/baldrick/__init__.py index d943be8..31577d5 100644 --- a/baldrick/__init__.py +++ b/baldrick/__init__.py @@ -1,5 +1,4 @@ import os -import logging from baldrick import github # noqa diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 0789f8b..8b4adbd 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -2,7 +2,6 @@ import base64 import re import requests -import warnings from datetime import datetime import dateutil.parser @@ -20,6 +19,7 @@ file_cache = TTLOrderedDict(default_ttl=60) + def paged_github_json_request(url, headers=None): response = requests.get(url, headers=headers) @@ -126,7 +126,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): if file_content: try: repo_config = loads(file_content, tool=current_app.bot_username) - logger.debug(f"Got the following config from {self.repo}@{branch}: {config}") + logger.debug(f"Got the following config from {self.repo}@{branch}: {repo_config}") except Exception: logger.error( f"Failed to load config in {self.repo} on branch {branch}, despite finding a pyproject.toml file.") @@ -138,9 +138,7 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): logger.debug(f"Didn't find a fallback config in {self.repo} on branch {branch}.") # Priority is 1) repo_config 2) fallback_config 3) app_config - logger.debug(f"{app_config}, {fallback_config}") app_config.update_from_config(fallback_config) - logger.debug(f"{app_config}, {repo_config}") app_config.update_from_config(repo_config) logger.debug(f"Got this combined config {app_config}") diff --git a/baldrick/logging.py b/baldrick/logging.py index 2232ba3..50a3812 100644 --- a/baldrick/logging.py +++ b/baldrick/logging.py @@ -14,6 +14,7 @@ LOG_NAME_TO_LEVEL = {v: k for k, v in LOG_LEVEL_TO_NAME.items()} + class InterceptHandler(logging.Handler): """ Handler to route stdlib logs to loguru @@ -25,6 +26,7 @@ def emit(self, record): # Log with name to support formatting if known, otherwise use the level number logger_opt.log(LOG_LEVEL_TO_NAME.get(record.levelno, record.levelno), record.getMessage()) + # Retrieve default log level from same environment variable as loguru log_level = LOG_NAME_TO_LEVEL.get(environ.get("BALDRICK_LOG_LEVEL", "INFO"), "INFO") From 6d5a54d4c01a5cafead4457b63a1a48048f138d7 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 10:46:34 +0100 Subject: [PATCH 13/18] Make config logging quieter --- baldrick/github/github_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 8b4adbd..fd436ce 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -120,13 +120,13 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): try: file_content = self.get_file_contents(path_to_file, branch=branch) except FileNotFoundError: - logger.debug(f"No config file found in {self.repo} on branch {branch}.") + logger.debug(f"No config file found in {self.repo}@{branch}.") file_content = None if file_content: try: repo_config = loads(file_content, tool=current_app.bot_username) - logger.debug(f"Got the following config from {self.repo}@{branch}: {repo_config}") + logger.trace(f"Got the following config from {self.repo}@{branch}: {repo_config}") except Exception: logger.error( f"Failed to load config in {self.repo} on branch {branch}, despite finding a pyproject.toml file.") @@ -135,13 +135,13 @@ def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): try: fallback_config = loads(file_content, tool=current_app.fall_back_config) except Exception: - logger.debug(f"Didn't find a fallback config in {self.repo} on branch {branch}.") + logger.trace(f"Didn't find a fallback config in {self.repo}@{branch}.") # Priority is 1) repo_config 2) fallback_config 3) app_config app_config.update_from_config(fallback_config) app_config.update_from_config(repo_config) - logger.debug(f"Got this combined config {app_config}") + logger.debug(f"Got this combined config from {self.repo}@{branch}: {app_config}") return app_config From 51fd03cf763b465d586931dcd24d8edaad8458ac Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 15:29:27 +0100 Subject: [PATCH 14/18] change to FILE_CACHE --- baldrick/github/github_api.py | 7 +++---- baldrick/github/tests/test_github_api.py | 4 ++-- baldrick/plugins/tests/test_circleci_artifacts.py | 4 ++-- baldrick/plugins/tests/test_github_milestones.py | 4 ++-- baldrick/plugins/tests/test_github_pull_requests.py | 4 ++-- baldrick/plugins/tests/test_github_pushes.py | 4 ++-- baldrick/plugins/tests/test_github_towncrier_changelog.py | 4 ++-- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index fd436ce..cbdff58 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -17,7 +17,7 @@ HOST = "https://api.github.com" HOST_NONAPI = "https://github.com" -file_cache = TTLOrderedDict(default_ttl=60) +FILE_CACHE = TTLOrderedDict(default_ttl=60) def paged_github_json_request(url, headers=None): @@ -71,13 +71,12 @@ def _url_contents(self): return f'{HOST}/repos/{self.repo}/contents/' def get_file_contents(self, path_to_file, branch='master'): - global file_cache cache_key = f"{self.repo}:{path_to_file}@{branch}" # It seems that this is the only safe way to do this with # TTLOrderedDict try: - return file_cache[cache_key] + return FILE_CACHE[cache_key] except KeyError: pass @@ -90,7 +89,7 @@ def get_file_contents(self, path_to_file, branch='master'): contents_base64 = response.json()['content'] contents = base64.b64decode(contents_base64).decode() - file_cache[cache_key] = contents + FILE_CACHE[cache_key] = contents return contents def get_repo_config(self, branch='master', path_to_file='pyproject.toml'): diff --git a/baldrick/github/tests/test_github_api.py b/baldrick/github/tests/test_github_api.py index c45f424..184bf85 100644 --- a/baldrick/github/tests/test_github_api.py +++ b/baldrick/github/tests/test_github_api.py @@ -5,7 +5,7 @@ import pytest from baldrick.config import loads -from baldrick.github.github_api import (file_cache, RepoHandler, IssueHandler, +from baldrick.github.github_api import (FILE_CACHE, RepoHandler, IssueHandler, PullRequestHandler) @@ -77,7 +77,7 @@ def test_urls(self): class TestRealRepoHandler: def setup_method(self, method): - file_cache.clear() + FILE_CACHE.clear() def setup_class(self): self.repo = RepoHandler('astropy/astropy-bot') diff --git a/baldrick/plugins/tests/test_circleci_artifacts.py b/baldrick/plugins/tests/test_circleci_artifacts.py index 837ee32..66bc2eb 100644 --- a/baldrick/plugins/tests/test_circleci_artifacts.py +++ b/baldrick/plugins/tests/test_circleci_artifacts.py @@ -1,7 +1,7 @@ import logging from unittest.mock import patch, call -from baldrick.github.github_api import file_cache +from baldrick.github.github_api import FILE_CACHE from baldrick.github.github_api import RepoHandler from baldrick.plugins.circleci_artifacts import set_commit_status_for_artifacts @@ -48,7 +48,7 @@ def setup_method(self, method): self.repo_handler = RepoHandler("nota/repo", "1234") self.get_file_contents = self.get_file_contents_mock.start() - file_cache.clear() + FILE_CACHE.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_milestones.py b/baldrick/plugins/tests/test_github_milestones.py index 191a8df..78c2b70 100644 --- a/baldrick/plugins/tests/test_github_milestones.py +++ b/baldrick/plugins/tests/test_github_milestones.py @@ -1,6 +1,6 @@ from unittest.mock import patch, PropertyMock -from baldrick.github.github_api import file_cache +from baldrick.github.github_api import FILE_CACHE from baldrick.github.github_api import RepoHandler, PullRequestHandler from baldrick.plugins.github_milestones import process_milestone, MISSING_MESSAGE, PRESENT_MESSAGE @@ -42,7 +42,7 @@ def setup_method(self, method): self.milestone.return_value = None self.get_file_contents = self.get_file_contents_mock.start() - file_cache.clear() + FILE_CACHE.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_pull_requests.py b/baldrick/plugins/tests/test_github_pull_requests.py index 689ce79..dc4e4b0 100644 --- a/baldrick/plugins/tests/test_github_pull_requests.py +++ b/baldrick/plugins/tests/test_github_pull_requests.py @@ -2,7 +2,7 @@ from copy import copy from unittest.mock import MagicMock, patch, PropertyMock -from baldrick.github.github_api import file_cache +from baldrick.github.github_api import FILE_CACHE from baldrick.plugins.github_pull_requests import (pull_request_handler, PULL_REQUEST_CHECKS) @@ -52,7 +52,7 @@ def setup_method(self, method): self.get_installation_token.return_value = 'abcdefg' self.labels.return_value = [] - file_cache.clear() + FILE_CACHE.clear() def teardown_method(self, method): self.requests_get_mock.stop() diff --git a/baldrick/plugins/tests/test_github_pushes.py b/baldrick/plugins/tests/test_github_pushes.py index 4cdc7bf..a451d72 100644 --- a/baldrick/plugins/tests/test_github_pushes.py +++ b/baldrick/plugins/tests/test_github_pushes.py @@ -2,7 +2,7 @@ from copy import copy from unittest.mock import MagicMock, patch -from baldrick.github.github_api import file_cache +from baldrick.github.github_api import FILE_CACHE from baldrick.plugins.github_pushes import push_handler, PUSH_HANDLERS test_handler = MagicMock() @@ -38,7 +38,7 @@ def setup_method(self, method): self.get_installation_token.return_value = 'abcdefg' - file_cache.clear() + FILE_CACHE.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() diff --git a/baldrick/plugins/tests/test_github_towncrier_changelog.py b/baldrick/plugins/tests/test_github_towncrier_changelog.py index 5cdc528..41e86eb 100644 --- a/baldrick/plugins/tests/test_github_towncrier_changelog.py +++ b/baldrick/plugins/tests/test_github_towncrier_changelog.py @@ -3,7 +3,7 @@ import pytest -from baldrick.github.github_api import file_cache +from baldrick.github.github_api import FILE_CACHE from baldrick.github.github_api import RepoHandler, PullRequestHandler from baldrick.plugins.github_towncrier_changelog import process_towncrier_changelog @@ -35,7 +35,7 @@ def setup_method(self, method): self.get_file_contents = self.get_file_contents_mock.start() self.modified_files = self.modified_files_mock.start() - file_cache.clear() + FILE_CACHE.clear() def teardown_method(self, method): self.get_file_contents_mock.stop() From e1a2daa0d7e1f516586f3b14c7136e98067417a9 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 16:13:50 +0100 Subject: [PATCH 15/18] add an env var for TTL --- baldrick/github/github_api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index cbdff58..184f40d 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -1,15 +1,16 @@ """Module to handle GitHub API.""" import base64 +import os import re -import requests from datetime import datetime import dateutil.parser +import requests from flask import current_app from loguru import logger from ttldict import TTLOrderedDict -from baldrick.config import loads, Config +from baldrick.config import Config, loads from baldrick.github.github_auth import github_request_headers __all__ = ['GitHubHandler', 'IssueHandler', 'RepoHandler', 'PullRequestHandler'] @@ -17,7 +18,7 @@ HOST = "https://api.github.com" HOST_NONAPI = "https://github.com" -FILE_CACHE = TTLOrderedDict(default_ttl=60) +FILE_CACHE = TTLOrderedDict(default_ttl=os.environ('BALDRICK_FILE_CACHE_TTL', 60)) def paged_github_json_request(url, headers=None): From 60cfacc44a1193fb43627a2f6067deb11a43b6d9 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 17:03:33 +0100 Subject: [PATCH 16/18] Add a line about the TTL --- doc/heroku.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/heroku.rst b/doc/heroku.rst index 3750822..81385f7 100644 --- a/doc/heroku.rst +++ b/doc/heroku.rst @@ -50,3 +50,8 @@ interface, as mentioned. The main required environment variables (also see The whole key, including the ``BEGIN`` and ``END`` header and footer should be pasted into the field. + +* ``BALDRICK_FILE_CACHE_TTL``, This defaults to 60 seconds and controls the + amount of time a file retrieved from GitHub will be cached. This is important + because otherwise reading the bot config from the repository will cause many + requests to GitHub. From 7f5abaa6f46a20ffea3756611fc41f829310fce2 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 19:49:52 +0100 Subject: [PATCH 17/18] Update heroku.rst --- doc/heroku.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/heroku.rst b/doc/heroku.rst index 81385f7..4afb4d6 100644 --- a/doc/heroku.rst +++ b/doc/heroku.rst @@ -54,4 +54,4 @@ interface, as mentioned. The main required environment variables (also see * ``BALDRICK_FILE_CACHE_TTL``, This defaults to 60 seconds and controls the amount of time a file retrieved from GitHub will be cached. This is important because otherwise reading the bot config from the repository will cause many - requests to GitHub. + requests to GitHub. The value is in seconds. From 101bf715a3f9c15cd2d0eaf0293bbca1b1fb0afc Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Thu, 5 Sep 2019 12:16:40 +0100 Subject: [PATCH 18/18] Fix envron get --- baldrick/github/github_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baldrick/github/github_api.py b/baldrick/github/github_api.py index 184f40d..a4f861f 100644 --- a/baldrick/github/github_api.py +++ b/baldrick/github/github_api.py @@ -18,7 +18,7 @@ HOST = "https://api.github.com" HOST_NONAPI = "https://github.com" -FILE_CACHE = TTLOrderedDict(default_ttl=os.environ('BALDRICK_FILE_CACHE_TTL', 60)) +FILE_CACHE = TTLOrderedDict(default_ttl=os.environ.get('BALDRICK_FILE_CACHE_TTL', 60)) def paged_github_json_request(url, headers=None):