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

fix: GitHub integration tagging issues #4586

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions api/integrations/github/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class GitHubTag(Enum):
PR_MERGED = "PR Merged"
PR_CLOSED = "PR Closed"
PR_DRAFT = "PR Draft"
PR_DEQUEUED = "PR Dequeued"
ISSUE_OPEN = "Issue Open"
ISSUE_CLOSED = "Issue Closed"

Expand All @@ -52,6 +53,7 @@ class GitHubTag(Enum):
GitHubTag.PR_MERGED.value: "This feature has a linked PR merged",
GitHubTag.PR_CLOSED.value: "This feature has a linked PR closed",
GitHubTag.PR_DRAFT.value: "This feature has a linked PR draft",
GitHubTag.PR_DEQUEUED.value: "This feature has a linked PR dequeued",
GitHubTag.ISSUE_OPEN.value: "This feature has a linked issue open",
GitHubTag.ISSUE_CLOSED.value: "This feature has a linked issue closed",
}
41 changes: 30 additions & 11 deletions api/integrations/github/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
FEATURE_ENVIRONMENT_URL,
FEATURE_TABLE_HEADER,
FEATURE_TABLE_ROW,
GITHUB_TAG_COLOR,
LINK_FEATURE_TITLE,
LINK_SEGMENT_TITLE,
UNLINKED_FEATURE_TEXT,
UPDATED_FEATURE_TEXT,
GitHubEventType,
GitHubTag,
github_tag_description,
)
from integrations.github.dataclasses import GithubData
from integrations.github.models import GithubConfiguration
from integrations.github.models import GithubConfiguration, GitHubRepository
from integrations.github.tasks import call_github_app_webhook_for_feature_state
from projects.tags.models import Tag, TagType

Expand All @@ -34,6 +36,7 @@
"converted_to_draft": GitHubTag.PR_DRAFT.value,
"opened": GitHubTag.PR_OPEN.value,
"reopened": GitHubTag.PR_OPEN.value,
"dequeued": GitHubTag.PR_DEQUEUED.value,
"ready_for_review": GitHubTag.PR_OPEN.value,
"merged": GitHubTag.PR_MERGED.value,
},
Expand All @@ -46,7 +49,7 @@


def tag_feature_per_github_event(
event_type: str, action: str, metadata: dict[str, Any]
event_type: str, action: str, metadata: dict[str, Any], repo_full_name: str
) -> None:

# Get Feature with external resource of type GITHUB and url matching the resource URL
Expand All @@ -56,17 +59,31 @@ def tag_feature_per_github_event(
external_resources__url=metadata.get("html_url"),
).first()

if feature:
# Check to see if any feature objects match and if not return
# to allow the webhook processing complete.
if not feature:
return

repository_owner, repository_name = repo_full_name.split(sep="/", maxsplit=1)
tagging_enabled = GitHubRepository.objects.get(
project=feature.project,
repository_owner=repository_owner,
repository_name=repository_name,
).tagging_enabled

if tagging_enabled:
if (
event_type == "pull_request"
and action == "closed"
and metadata.get("merged")
):
action = "merged"
# Get corresponding project Tag to tag the feature
github_tag = Tag.objects.get(
# Get or create the corresponding project Tag to tag the feature
github_tag, _ = Tag.objects.get_or_create(
color=GITHUB_TAG_COLOR,
description=github_tag_description[tag_by_event_type[event_type][action]],
label=tag_by_event_type[event_type][action],
project=feature.project_id,
project=feature.project,
is_system_tag=True,
type=TagType.GITHUB.value,
)
Expand Down Expand Up @@ -97,11 +114,13 @@ def handle_installation_deleted(payload: dict[str, Any]) -> None:

def handle_github_webhook_event(event_type: str, payload: dict[str, Any]) -> None:
if event_type == "installation" and payload.get("action") == "deleted":
handle_installation_deleted(payload)
elif event_type in tag_by_event_type:
action = str(payload.get("action"))
return handle_installation_deleted(payload)

action = str(payload.get("action"))
if action in tag_by_event_type[event_type]:
repo_full_name = payload["repository"]["full_name"]
metadata = payload.get("issue", {}) or payload.get("pull_request", {})
tag_feature_per_github_event(event_type, action, metadata)
tag_feature_per_github_event(event_type, action, metadata, repo_full_name)


def generate_body_comment(
Expand Down Expand Up @@ -166,7 +185,7 @@ def generate_body_comment(
return result


def check_not_none(value: any) -> bool:
def check_not_none(value: Any) -> bool:
return value is not None


Expand Down
2 changes: 2 additions & 0 deletions api/integrations/github/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.db import models
from django_lifecycle import (
AFTER_CREATE,
AFTER_UPDATE,
BEFORE_DELETE,
LifecycleModelMixin,
hook,
Expand Down Expand Up @@ -93,6 +94,7 @@ def delete_feature_external_resources(
).delete()

@hook(AFTER_CREATE)
@hook(AFTER_UPDATE, when="tagging_enabled", has_changed=True, was=False)
def create_github_tags(
self,
) -> None:
Expand Down
14 changes: 14 additions & 0 deletions api/tests/unit/integrations/github/test_unit_github_github.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from integrations.github.github import tag_feature_per_github_event


def test_tag_feature_per_github_event_with_empty_feature(db: None) -> None:
# Given / When
result = tag_feature_per_github_event(
event_type="test",
action="closed",
metadata={},
repo_full_name="test/repo",
)

# Then
assert result is None
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"html_url": "https://github.com/repositoryownertest/repositorynametest/issues/11",
"merged": True,
},
"repository": {
"full_name": "repositoryownertest/repositorynametest",
},
"action": "closed",
}
)
Expand All @@ -49,7 +52,7 @@
WEBHOOK_SIGNATURE_WITHOUT_INSTALLATION_ID = (
"sha1=f99796bd3cebb902864e87ed960c5cca8772ff67"
)
WEBHOOK_MERGED_ACTION_SIGNATURE = "sha1=712ec7a5db14aad99d900da40738ebb9508ecad2"
WEBHOOK_MERGED_ACTION_SIGNATURE = "sha1=f3f7e1e9b43448d570451317447d3b4f8f8142de"
WEBHOOK_SECRET = "secret-key"


Expand Down
Loading