aicoe/sesheta/actions/label.py
#!/usr/bin/env python3# sesheta-actions# Copyright(C) 2019,2020 Christoph Görn## This program is free software: you can redistribute it and / or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>. """Sesheta's actions.""" import osimport logging from datetime import datetime import aiohttpimport gidgethub from octomachinery.github.api.tokens import GitHubOAuthTokenfrom octomachinery.github.api.raw_client import RawGitHubAPIfrom octomachinery.app.runtime.context import RUNTIME_CONTEXT _LOGGER = logging.getLogger(__name__) NEEDS_REBASE_LABEL_NAME = "do-not-merge/needs-rebase"GITHUB_DEFAULT_LABELS = [ "bug", "documentation", "duplicate", "enhancement", "good first issue", "help wanted", "invalid", "question", "wontfix",] DEFAULT_LABELS = [Line too long (80 > 79 characters) {"name": "bot", "color": "698b69", "description": "to a cyborg team mate!"},Line too long (103 > 79 characters) {"name": "human_intervention_required", "color": "f3ccff", "description": "to a human team mate!"},Line too long (109 > 79 characters) {"name": "thoth/human_intervention_required", "color": "f3ccff", "description": "to a human team mate!"}, { "name": "thoth/potential-observation", "color": "f3ccff",Line too long (96 > 79 characters) "description": "This might be an observation to be included in Thoth's Knowledge Graph", }, { "name": "thoth/group-programming", "color": "3bbf72", "description": "A potential item for a group-programming session...", },Line too long (105 > 79 characters) {"name": "potential_flake", "color": "f3ccff", "description": "This might be a flake of some kind."},Line too long (111 > 79 characters) {"name": "thoth/potential-flake", "color": "f3ccff", "description": "This might be a flake of some kind."}, {"name": "test:flake", "color": "f3ccff", "description": "A test flake."}, {"name": "test/flake", "color": "f3ccff", "description": "A test flake."},] DEFAULT_MILESTONES_THOTH = [Line too long (106 > 79 characters) {"title": "v0.6.0", "description": "Tracking Milestone for v0.6.0", "due_on": "2020-05-29T19:00:00Z"},Line too long (107 > 79 characters) {"title": "v0.7.0", "description": "Security Indicator Aggregation", "due_on": "2020-06-30T23:00:00Z"},Line too long (99 > 79 characters) {"title": "v0.8.0", "description": "Advise-backed Kebechet", "due_on": "2020-07-17T23:00:00Z"},Line too long (106 > 79 characters) {"title": "adviser-v0.17.0", "description": "moar stable Adviser!", "due_on": "2020-09-14T13:00:00Z"},Line too long (111 > 79 characters) {"title": "adviser-v0.18.0", "description": "Security Indicator advise", "due_on": "2020-09-28T13:00:00Z"}, { "title": "investigator-v0.5.0", "description": "add Kafka to our infrastructure", "due_on": "2020-09-28T13:00:00Z", },Line too long (107 > 79 characters) {"title": "slo-reporter-v0.7.0", "description": "more SLI and docs", "due_on": "2020-09-28T13:00:00Z"},Line too long (108 > 79 characters) {"title": "kebechet-v1.1.0", "description": "proactive cyborg nr. 1", "due_on": "2020-10-12T13:00:00Z"}, { "title": "python38-migration", "description": "migrate libraries and applications to Python 3.8", "due_on": "2020-11-23T13:00:00Z", },] Line too long (119 > 79 characters)async def create_or_update_milestone(slug: str, title: str, description: str, state: str = "open", due_on: str = None): """Create or update the Milestone in the given repository.""" access_token = GitHubOAuthToken(os.environ["GITHUB_ACCESS_TOKEN"]) async with aiohttp.ClientSession() as client:Line too long (93 > 79 characters) github_api = RawGitHubAPI(access_token, session=client, user_agent="sesheta-actions") # prepare a milestoneLine too long (85 > 79 characters) milestone_data = {"title": title, "description": description, "state": state} if due_on is not None: milestone_data["due_on"] = due_on due_on_datetime = datetime.strptime(due_on, "%Y-%m-%dT%H:%M:%SZ") if due_on_datetime < datetime.utcnow():Line too long (92 > 79 characters) _LOGGER.info(f"Milestone '{title}' has a due date in the past... skipping!") return try: # and see if it exists _LOGGER.debug("checking %s for %s", slug, title) Line too long (83 > 79 characters) async for milestone in github_api.getiter(f"/repos/{slug}/milestones"): _LOGGER.debug("found %s: %s", slug, milestone) if (milestone["title"] == title) and (Line too long (96 > 79 characters) (milestone["due_on"] != due_on) or (milestone["description"] != description) ): _LOGGER.debug("updating %s: %s", slug, milestone_data) del milestone_data["title"]Line too long (114 > 79 characters) await github_api.patch(f"/repos/{slug}/milestones/{milestone['number']}", data=milestone_data) return _LOGGER.debug("creating %s: %s", slug, milestone_data)Line too long (83 > 79 characters) await github_api.post(f"/repos/{slug}/milestones", data=milestone_data) except gidgethub.BadRequest as bad: _LOGGER.error(f"Milestone '{title}', Repo: '{slug}': {bad}") return async def create_or_update_label(slug: str, name: str, color: str = "") -> str: """Create or update the label in the given repository.""" access_token = GitHubOAuthToken(os.environ["GITHUB_ACCESS_TOKEN"]) async with aiohttp.ClientSession() as client:Line too long (93 > 79 characters) github_api = RawGitHubAPI(access_token, session=client, user_agent="sesheta-actions") try: _LOGGER.debug("get item...")Line too long (108 > 79 characters) label = await github_api.getitem(f"/repos/{slug}/labels/{name}", preview_api_version="symmetra") if label["color"] != color: _LOGGER.debug("patching item color...") await github_api.patch( f"/repos/{slug}/labels/{name}", preview_api_version="symmetra", data={"new_name": name, "color": color}, ) except gidgethub.BadRequest as bad: _LOGGER.error(f"Label '{name}', Repo: '{slug}': {bad}") try: resp = await github_api.post( f"/repos/{slug}/labels", preview_api_version="symmetra", data={"name": name, "color": color}, ) except gidgethub.BadRequest as created: _LOGGER.info( f"Label '{name}', Repo: '{slug}': created", ) # TODO maybe this should be a little more robust? return async def do_not_merge(pr_url: str) -> bool: """Check if the given Pull Request has any of the DNM labels.""" try: github_api = RUNTIME_CONTEXT.app_installation_client pr = await github_api.getitem(pr_url) for label in pr["labels"]:Line too long (104 > 79 characters) if label["name"].startswith("do-not-merge") or label["name"].startswith("work-in-progress"): return True except Exception as err: _LOGGER.error(str(err)) return False