예제 #1
0
    def get_owners(cls, project_id, data):
        """
        For a given project_id, and event data blob.
        We combine the schemas from IssueOwners and CodeOwners.

        If Everyone is returned, this means we implicitly are
        falling through our rules and everyone is responsible.

        If an empty list is returned, this means there are explicitly
        no owners.
        """
        from sentry.models import ProjectCodeOwners

        ownership = cls.get_ownership_cached(project_id)
        if not ownership:
            ownership = cls(project_id=project_id)

        codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)
        ownership.schema = cls.get_combined_schema(ownership, codeowners)

        rules = cls._matching_ownership_rules(ownership, project_id, data)

        if not rules:
            return cls.Everyone if ownership.fallthrough else [], None

        owners = {o for rule in rules for o in rule.owners}
        owners_to_actors = resolve_actors(owners, project_id)
        ordered_actors = []
        for rule in rules:
            for o in rule.owners:
                if o in owners and owners_to_actors.get(o) is not None:
                    ordered_actors.append(owners_to_actors[o])
                    owners.remove(o)

        return ordered_actors, rules
예제 #2
0
    def get_autoassign_owners(cls, project_id, data, limit=2):
        """
        Get the auto-assign owner for a project if there are any.

        We combine the schemas from IssueOwners and CodeOwners.

        Returns a tuple of (auto_assignment_enabled, list_of_owners, assigned_by_codeowners: boolean).
        """
        from sentry.models import ProjectCodeOwners

        with metrics.timer("projectownership.get_autoassign_owners"):
            ownership = cls.get_ownership_cached(project_id)
            codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)
            assigned_by_codeowners = False
            if not (ownership or codeowners):
                return False, [], assigned_by_codeowners

            if not ownership:
                ownership = cls(project_id=project_id)

            ownership_rules = cls._matching_ownership_rules(
                ownership, project_id, data)
            codeowners_rules = (cls._matching_ownership_rules(
                codeowners, project_id, data) if codeowners else [])

            if not (codeowners_rules or ownership_rules):
                return ownership.auto_assignment, [], assigned_by_codeowners

            ownership_actors = cls._find_actors(project_id, ownership_rules,
                                                limit)
            codeowners_actors = cls._find_actors(project_id, codeowners_rules,
                                                 limit)

            # Can happen if the ownership rule references a user/team that no longer
            # is assigned to the project or has been removed from the org.
            if not (ownership_actors or codeowners_actors):
                return ownership.auto_assignment, [], assigned_by_codeowners

            # Ownership rules take precedence over codeowner rules.
            actors = [*ownership_actors, *codeowners_actors][:limit]

            # Only the first item in the list is used for assignment, the rest are just used to suggest suspect owners.
            # So if ownership_actors is empty, it will be assigned by codeowners_actors
            if len(ownership_actors) == 0:
                assigned_by_codeowners = True

            from sentry.models import ActorTuple

            return (
                ownership.auto_assignment,
                ActorTuple.resolve_many(actors),
                assigned_by_codeowners,
            )
예제 #3
0
    def get_autoassign_owners(cls, project_id, data, limit=2):
        """
        Get the auto-assign owner for a project if there are any.

        We combine the schemas from IssueOwners and CodeOwners.

        Returns a tuple of (auto_assignment_enabled, list_of_owners).
        """
        from sentry.models import ProjectCodeOwners

        with metrics.timer("projectownership.get_autoassign_owners"):
            ownership = cls.get_ownership_cached(project_id)
            codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)

            if not (ownership or codeowners):
                return False, []

            if not ownership:
                ownership = cls(project_id=project_id)

            ownership.schema = cls.get_combined_schema(ownership, codeowners)

            rules = cls._matching_ownership_rules(ownership, project_id, data)
            if not rules:
                return ownership.auto_assignment, []

            # We want the last matching rule to take the most precedence.
            owners = [owner for rule in rules for owner in rule.owners]
            owners.reverse()
            actors = {
                key: val
                for key, val in resolve_actors({owner
                                                for owner in owners},
                                               project_id).items() if val
            }
            actors = [actors[owner] for owner in owners
                      if owner in actors][:limit]

            # Can happen if the ownership rule references a user/team that no longer
            # is assigned to the project or has been removed from the org.
            if not actors:
                return ownership.auto_assignment, []

            from sentry.models import ActorTuple

            return ownership.auto_assignment, ActorTuple.resolve_many(actors)
예제 #4
0
    def get_owners(
        cls, project_id: int, data: Mapping[str, Any]
    ) -> Tuple[Union["Everyone", Sequence["ActorTuple"]],
               Optional[Sequence[Rule]]]:
        """
        For a given project_id, and event data blob.
        We combine the schemas from IssueOwners and CodeOwners.

        If there are no matching rules, check ProjectOwnership.fallthrough:
            If ProjectOwnership.fallthrough is enabled, return Everyone (all project members)
             - we implicitly are falling through our rules and everyone is responsible.
            If ProjectOwnership.fallthrough is disabled, return an empty list
             - there are explicitly no owners

        If there are matching rules, return the ordered actors.
            The order is determined by iterating through rules sequentially, evaluating
            CODEOWNERS (if present), followed by Ownership Rules
        """
        from sentry.models import ProjectCodeOwners

        ownership = cls.get_ownership_cached(project_id)
        if not ownership:
            ownership = cls(project_id=project_id)

        codeowners = ProjectCodeOwners.get_codeowners_cached(project_id)
        ownership.schema = cls.get_combined_schema(ownership, codeowners)

        rules = cls._matching_ownership_rules(ownership, project_id, data)

        if not rules:
            return cls.Everyone if ownership.fallthrough else [], None

        owners = {o for rule in rules for o in rule.owners}
        owners_to_actors = resolve_actors(owners, project_id)
        ordered_actors = []
        for rule in rules:
            for o in rule.owners:
                if o in owners and owners_to_actors.get(o) is not None:
                    ordered_actors.append(owners_to_actors[o])
                    owners.remove(o)

        return ordered_actors, rules