Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: stop syncing labels from labels.yaml #249

Merged
merged 2 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.. A new scriv changelog fragment.

- Stopped the bot from updating a repository's labels based on ``labels.yaml``, as this is now handled by the `repo_checks <https://github.com/openedx/repo-tools/tree/master/edx_repo_tools/repo_checks>`_ tool. The ``labels.yaml`` file is now unused and can be safely deleted from any openedx-webhooks data repositories.
4 changes: 1 addition & 3 deletions openedx_webhooks/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,14 @@ def get_people_file():
people[p].update(people_data_yaml[p])
return people


def get_orgs_file():
orgs = _read_yaml_data_file("orgs.yaml")
for org_data in list(orgs.values()):
if "name" in org_data:
orgs[org_data["name"]] = org_data
return orgs

def get_labels_file():
return _read_yaml_data_file("labels.yaml")

def get_person_certain_time(person: Dict, certain_time: datetime.datetime) -> Dict:
"""
Return person data structure for a particular time
Expand Down
4 changes: 1 addition & 3 deletions openedx_webhooks/jira_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from urlobject import URLObject

from openedx_webhooks.auth import get_github_session, get_jira_session
from openedx_webhooks.tasks.github_work import get_repo_labels, synchronize_labels
from openedx_webhooks.tasks.github_work import get_repo_labels
from openedx_webhooks.utils import (
jira_get, jira_paginated_get, sentry_extra_context,
github_pr_num, github_pr_url, github_pr_repo,
Expand Down Expand Up @@ -272,8 +272,6 @@ def issue_updated():
fail_msg += ' {0}'.format(event["issue"]["fields"]["issuetype"])
raise Exception(fail_msg)

synchronize_labels(pr_repo)

repo_labels = get_repo_labels(repo=pr_repo)
repo_labels_lower = {name.lower() for name in repo_labels}

Expand Down
41 changes: 1 addition & 40 deletions openedx_webhooks/tasks/github_work.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,11 @@
from typing import Any, Dict

from openedx_webhooks.auth import get_github_session
from openedx_webhooks.info import get_labels_file
from openedx_webhooks.tasks import logger
from openedx_webhooks.utils import (
log_check_response,
memoize_timed,
paginated_get,
)
from openedx_webhooks.utils import paginated_get


def get_repo_labels(repo: str) -> Dict[str, Dict[str, Any]]:
"""Get a dict mapping label names to full label info."""
url = f"/repos/{repo}/labels"
repo_labels = {lbl["name"]: lbl for lbl in paginated_get(url, session=get_github_session())}
return repo_labels


@memoize_timed(minutes=15)
def synchronize_labels(repo: str) -> None:
"""Ensure the labels in `repo` match the specs in openedx-webhooks-data/labels.yaml"""

url = f"/repos/{repo}/labels"
repo_labels = get_repo_labels(repo)
desired_labels = get_labels_file()
for name, label_data in desired_labels.items():
if label_data.get("delete", False):
# A label that should not exist in the repo.
if name in repo_labels:
logger.info(f"Deleting label {name} from {repo}")
resp = get_github_session().delete(f"{url}/{name}")
log_check_response(resp)
else:
# A label that should exist in the repo.
label_data["name"] = name
if name in repo_labels:
repo_label = repo_labels[name]
color_differs = repo_label["color"] != label_data["color"]
repo_desc = repo_label.get("description", "") or ""
desired_desc = label_data.get("description", "") or ""
desc_differs = repo_desc != desired_desc
if color_differs or desc_differs:
logger.info(f"Updating label {name} in {repo}")
resp = get_github_session().patch(f"{url}/{name}", json=label_data)
log_check_response(resp)
else:
logger.info(f"Adding label {name} to {repo}")
resp = get_github_session().post(url, json=label_data)
log_check_response(resp)
6 changes: 0 additions & 6 deletions openedx_webhooks/tasks/pr_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
from openedx_webhooks.auth import get_github_session, get_jira_session
from openedx_webhooks.lib.github.models import PrId
from openedx_webhooks.tasks import logger
from openedx_webhooks.tasks import github_work
from openedx_webhooks.tasks.jira_work import (
delete_jira_issue,
transition_jira_issue,
Expand Down Expand Up @@ -417,8 +416,6 @@ def fix_ospr(self) -> None:
desired=json_safe_dict(self.desired),
)

self.actions.synchronize_labels(repo=self.prid.full_name)

comment_kwargs = {}

make_issue = False
Expand Down Expand Up @@ -785,9 +782,6 @@ def initial_state(self, *, current: Dict, desired: Dict) -> None:
Does nothing when really fixing, but captures information for dry runs.
"""

def synchronize_labels(self, *, repo: str) -> None:
github_work.synchronize_labels(repo)

def create_ospr_issue(
self, *,
pr_url: str,
Expand Down
72 changes: 2 additions & 70 deletions tests/fake_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
import datetime
import itertools
import random
import re
from dataclasses import dataclass, field
from typing import Any, Dict, Iterable, List, Optional, Set
from urllib.parse import unquote

from openedx_webhooks.cla_check import CLA_CONTEXT
from openedx_webhooks.types import GhProject
Expand All @@ -22,26 +20,14 @@


class FakeGitHubException(faker.FakerException):
def __init__(self, message, errors=None):
super().__init__(message)
self.errors = errors

def as_json(self) -> Dict:
j = {"message": str(self)}
if self.errors:
j["errors"] = self.errors
return j

class DoesNotExist(FakeGitHubException):
"""A requested object does not exist."""
status_code = 404

class ValidationError(FakeGitHubException):
status_code = 422

def __init__(self, message="Validation Failed", **kwargs):
super().__init__(message=message, errors=[kwargs])

def fake_sha():
"""A realistic stand-in for a commit sha."""
return "".join(random.choice("0123456789abcdef") for c in range(32))
Expand Down Expand Up @@ -72,10 +58,6 @@ class Label:
color: Optional[str] = "ededed"
description: Optional[str] = None

def __post_init__(self):
if self.color is not None and not re.fullmatch(r"[0-9a-fA-F]{6}", self.color):
raise ValidationError(resource="Label", code="invalid", field="color")

def as_json(self):
return dataclasses.asdict(self)

Expand Down Expand Up @@ -272,33 +254,16 @@ def get_label(self, name: str) -> Label:
def has_label(self, name: str) -> bool:
return name in self.labels

def set_labels(self, data: List[Dict]) -> None:
def _set_labels(self, data: List[Dict]) -> None:
self.labels = {}
for kwargs in data:
self.add_label(**kwargs)

def get_labels(self) -> List[Label]:
return sorted(self.labels.values(), key=lambda l: l.name)

def add_label(self, **kwargs) -> Label:
label = Label(**kwargs)
if label.name in self.labels:
raise ValidationError(resource="Label", code="already_exists", field="name")
self.labels[label.name] = label
return label

def update_label(self, name: str, **kwargs) -> Label:
label = self.get_label(name)
new_label = dataclasses.replace(label, **kwargs)
self.labels[name] = new_label
return new_label

def delete_label(self, name: str) -> None:
try:
del self.labels[name]
except KeyError:
raise DoesNotExist(f"Label {self.full_name} {name!r} does not exist")


class Flaky404:
"""
Expand Down Expand Up @@ -361,7 +326,7 @@ def get_user(self, login: str, create: bool = False) -> User:

def make_repo(self, owner: str, repo: str, private: bool=False) -> Repo:
r = Repo(self, owner, repo, private)
r.set_labels(DEFAULT_LABELS)
r._set_labels(DEFAULT_LABELS)
self.repos[f"{owner}/{repo}"] = r
return r

Expand Down Expand Up @@ -446,39 +411,6 @@ def _post_pr_status_update(self, match, request, _context) -> List[Dict[str, Any
self.cla_statuses[match['sha']] = data
return [data]

# Repo labels

@faker.route(r"/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/labels")
def _get_labels(self, match, _request, _context) -> List[Dict]:
# https://developer.github.com/v3/issues/labels/#list-labels-for-a-repository
r = self.get_repo(match["owner"], match["repo"])
return [label.as_json() for label in r.labels.values()]

@faker.route(r"/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/labels", "POST")
def _post_labels(self, match, request, context) -> Dict:
# https://developer.github.com/v3/issues/labels/#create-a-label
r = self.get_repo(match["owner"], match["repo"])
label = r.add_label(**request.json())
context.status_code = 201
return label.as_json()

@faker.route(r"/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/labels/(?P<name>.*)", "PATCH")
def _patch_labels(self, match, request, _context) -> Dict:
# https://developer.github.com/v3/issues/labels/#update-a-label
r = self.get_repo(match["owner"], match["repo"])
data = request.json()
if "name" in data:
data.pop("name")
label = r.update_label(unquote(match["name"]), **data)
return label.as_json()

@faker.route(r"/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/labels/(?P<name>.*)", "DELETE")
def _delete_labels(self, match, _request, context) -> None:
# https://developer.github.com/v3/issues/labels/#delete-a-label
r = self.get_repo(match["owner"], match["repo"])
r.delete_label(unquote(match["name"]))
context.status_code = 204

# Comments

@faker.route(r"/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/issues/(?P<number>\d+)/comments(\?.*)?")
Expand Down
11 changes: 0 additions & 11 deletions tests/repo_data/openedx/openedx-webhooks-data/labels.yaml

This file was deleted.

6 changes: 1 addition & 5 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@

import pathlib

from repo_tools_data_schema import validate_labels, validate_orgs, validate_people
from repo_tools_data_schema import validate_orgs, validate_people

TEST_DATA_DIR = pathlib.Path(__file__).parent / "repo_data" / "openedx" / "openedx-webhooks-data"


def test_labels_yaml():
validate_labels(TEST_DATA_DIR / "labels.yaml")


def test_orgs_yaml():
validate_orgs(TEST_DATA_DIR / "orgs.yaml")

Expand Down
Loading