Skip to content
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
20 changes: 20 additions & 0 deletions backend/analytics_server/mhq/api/request_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from functools import wraps
from typing import Any, Dict, List
from uuid import UUID
from datetime import datetime

from flask import request
from stringcase import snakecase
from voluptuous import Invalid
from werkzeug.exceptions import BadRequest
from mhq.utils.time import time_now
from mhq.store.models.code.repository import TeamRepos
from mhq.service.code.models.org_repo import RawOrgRepo
from mhq.store.models.code import WorkflowFilter, CodeProvider

Expand Down Expand Up @@ -92,3 +95,20 @@ def coerce_org_repo(repo: Dict[str, str]) -> RawOrgRepo:

def coerce_org_repos(repos: List[Dict[str, str]]) -> List[RawOrgRepo]:
return [coerce_org_repo(repo) for repo in repos]


def coerce_team_repo(team_repo: Dict[str, str]) -> TeamRepos:

assert uuid_validator(team_repo.get("org_repo_id"))

return TeamRepos(
team_id=team_repo["team_id"],
org_repo_id=team_repo["org_repo_id"],
prod_branch=team_repo.get("prod_branch"),
prod_branches=team_repo.get("prod_branches"),
is_active=team_repo.get("is_active", True),
)


def coerce_team_repos(repos: List[Dict[str, str]]) -> List[TeamRepos]:
return [coerce_team_repo(repo) for repo in repos]
17 changes: 16 additions & 1 deletion backend/analytics_server/mhq/api/resources/code_resouces.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Dict, List
from mhq.service.code.models.lead_time import LeadTimeMetrics
from mhq.api.resources.core_resources import adapt_user_info
from mhq.store.models.code import PullRequest, OrgRepo
from mhq.store.models.code import PullRequest, OrgRepo, TeamRepos
from mhq.store.models.core import Users


Expand Down Expand Up @@ -123,3 +123,18 @@ def adapt_org_repo(org_repo: OrgRepo) -> Dict[str, any]:
"created_at": org_repo.created_at.isoformat(),
"updated_at": org_repo.updated_at.isoformat(),
}


def adapt_team_repos(team_repos: List[TeamRepos]) -> List[Dict[str, any]]:
return [
{
"team_id": str(team_repo.team_id),
"org_repo_id": str(team_repo.org_repo_id),
"prod_branch": team_repo.prod_branch,
"prod_branches": team_repo.prod_branches,
"is_active": team_repo.is_active,
"created_at": team_repo.created_at.isoformat(),
"updated_at": team_repo.updated_at.isoformat(),
}
for team_repo in team_repos
]
30 changes: 28 additions & 2 deletions backend/analytics_server/mhq/api/teams.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from flask import Blueprint
from typing import Any, Dict, List
from voluptuous import Required, Schema, Optional, All, Coerce
from werkzeug.exceptions import BadRequest
from mhq.store.models.code.repository import TeamRepos
from mhq.service.code.models.org_repo import RawOrgRepo
from mhq.api.resources.code_resouces import adapt_org_repo
from mhq.api.resources.code_resouces import adapt_org_repo, adapt_team_repos
from mhq.service.code.repository_service import get_repository_service
from mhq.api.resources.core_resources import adapt_team
from mhq.store.models.core.teams import Team
from mhq.service.core.teams import get_team_service

from mhq.api.request_utils import coerce_org_repos, dataschema
from mhq.api.request_utils import coerce_org_repos, coerce_team_repos, dataschema
from mhq.service.query_validator import get_query_validator

app = Blueprint("teams", __name__)
Expand Down Expand Up @@ -109,3 +111,27 @@ def update_team_repos(team_id: str, repos: List[RawOrgRepo]):
team_repos = get_repository_service().update_team_repos(team, repos)

return [adapt_org_repo(repo) for repo in team_repos]


@app.route("/teams/<team_id>/team_repos", methods={"PATCH"})
@dataschema(
Schema(
{
Required("team_repos_data"): All(list, Coerce(coerce_team_repos)),
}
),
)
def patch_team_repos_mapping(team_id: str, team_repos_data: List[TeamRepos]):

query_validator = get_query_validator()
team = query_validator.team_validator(team_id)

for team_repo in team_repos_data:
if team_repo.team_id != team_id:
raise BadRequest(
f"Team Repo with repo_id: {team_repo.org_repo_id} team_id: {team_repo.team_id} does not match team in request url: {team_id}."
)

team_repos_service = get_repository_service()
team_repos = team_repos_service.patch_team_repos_mapping(team, team_repos_data)
return adapt_team_repos(team_repos)
21 changes: 20 additions & 1 deletion backend/analytics_server/mhq/service/code/repository_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from mhq.service.code.models.org_repo import RawOrgRepo
from mhq.store.models.code import OrgRepo
from mhq.store.models.core import Team
from mhq.store.repos.code import CodeRepoService
from mhq.store.repos.code import CodeRepoService, TeamRepos


class RepositoryService:
Expand Down Expand Up @@ -100,6 +100,25 @@ def update_org_repos(

return self._code_repo_service.update_org_repos(updated_org_repos)

def patch_team_repos_mapping(self, team: Team, team_repos: List[TeamRepos]):

existing_team_repos = self.get_team_repos(team)

existing_team_repo_ids = set([str(repo.id) for repo in existing_team_repos])

team_repo_ids = set([str(repo.org_repo_id) for repo in team_repos])

team_repos_mappings_not_in_db = list(
team_repo_ids.difference(existing_team_repo_ids)
)

if team_repos_mappings_not_in_db:
raise Exception(
f"Team Repo Mappings does not exist for team: {str(team.id)} and repos {team_repos_mappings_not_in_db}"
)

return self._code_repo_service.patch_team_repos_mapping(team, team_repos)

def _update_team_incident_services(self, team: Team, org_repos: List[OrgRepo]):

incident_services = self._update_org_incident_services(team.org_id, org_repos)
Expand Down
11 changes: 11 additions & 0 deletions backend/analytics_server/mhq/store/repos/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ def update_team_repos(self, team: Team, org_repos: List[OrgRepo]):

self._db.session.commit()

@rollback_on_exc
def patch_team_repos_mapping(
self, team: Team, team_repos: List[TeamRepos]
) -> List[TeamRepos]:
[self._db.session.merge(team_repo) for team_repo in team_repos]
self._db.session.commit()
team_repo_ids = [str(team_repo.org_repo_id) for team_repo in team_repos]
return self._db.session.query(TeamRepos).filter(
TeamRepos.team_id == team.id, TeamRepos.org_repo_id.in_(team_repo_ids)
)

@rollback_on_exc
def get_org_repos_used_across_teams(self, org_id: str) -> List[OrgRepo]:
"""
Expand Down