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: Add automatic tagging for github integration #4028

Merged
merged 31 commits into from
Aug 12, 2024

Conversation

novakzaballa
Copy link
Contributor

@novakzaballa novakzaballa commented May 27, 2024

Thanks for submitting a PR! Please check the boxes below:

  • I have run pre-commit to check linting
  • I have added information to docs/ if required so people know about the feature!
  • I have filled in the "Changes" section below?
  • I have filled in the "How did you test this code" section below?
  • I have used a Conventional Commit title for this Pull Request

Changes

  • When a project is lilnked to a GitHub repository, the following tags are added to the project:
    The tags added are:
    PR Open
    PR Merged
    PR Closed
    PR Draft
    Issue Open
    Issue Closed

  • Add automatic tagging of features linked to GitHub resources. The tags are added on response to events in Flagsmith, like linking/unlinking PR/Issues, and also in response to events in GitHub like closing/reopening/marking as draft/merging PR/Issues. Each feature can have only one active PR tag and one active Issue tag at any time.

How did you test this code?

Unit tests added.

For local manual testing, the corresponding FE PR is #4035
It would be necessary to configure a local dev environment with these two branches (BE/FE) for testing until this BE PR is merged.

NOTE

For the case of multiple PRs/Issues linked to the same feature, we should consider tagging the feature as closed/merged only when all the linked Issues/PRs are closed/merged correspondingly.

Copy link

vercel bot commented May 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs ⬜️ Ignored (Inspect) Visit Preview Aug 12, 2024 1:20pm
flagsmith-frontend-preview ⬜️ Ignored (Inspect) Visit Preview Aug 12, 2024 1:20pm
flagsmith-frontend-staging ⬜️ Ignored (Inspect) Visit Preview Aug 12, 2024 1:20pm

@github-actions github-actions bot added the api Issue related to the REST API label May 27, 2024
@novakzaballa novakzaballa changed the title feat: Add automatic tagging for github integration feat: Add automatic tagging for github integration - WIP May 27, 2024
Copy link
Contributor

github-actions bot commented May 27, 2024

Uffizzi Preview deployment-55059 was deleted.

Copy link

codecov bot commented May 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.91%. Comparing base (948a87a) to head (479c8a0).
Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4028      +/-   ##
==========================================
+ Coverage   96.88%   96.91%   +0.02%     
==========================================
  Files        1172     1176       +4     
  Lines       39035    39345     +310     
==========================================
+ Hits        37820    38131     +311     
+ Misses       1215     1214       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@zachaysan zachaysan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of comments but nothing I don't trust that you'll handle.

api/conftest.py Outdated
Comment on lines 973 to 975
from tests.unit.features.test_unit_feature_external_resources_views import (
mocked_requests_post,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think mocked_requests_post should be converted into a fixture and added to a conftest.py instead of importing it like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted into a fixture in conftest.py

api/conftest.py Outdated
)
mock_generate_token.return_value = "mocked_token"

mocker.patch("requests.post", side_effect=mocked_requests_post)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is mocked_requests_post coming from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted into a fixture in conftest

Comment on lines +31 to +45
tag_by_event_type = {
"pull_request": {
"closed": GitHubTag.PR_CLOSED.value,
"converted_to_draft": GitHubTag.PR_DRAFT.value,
"opened": GitHubTag.PR_OPEN.value,
"reopened": GitHubTag.PR_OPEN.value,
"ready_for_review": GitHubTag.PR_OPEN.value,
"merged": GitHubTag.PR_MERGED.value,
},
"issues": {
"closed": GitHubTag.ISSUE_CLOSED.value,
"opened": GitHubTag.ISSUE_OPEN.value,
"reopened": GitHubTag.ISSUE_OPEN.value,
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section should probably live in the constants.py module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was tempted to put it in constants, however, it would lose context and require extra comments since it's used only in the context of the github.py file. i.e. the event_type in its name refers to a webhook request event type.

Comment on lines 48 to 50
def handle_installation_deleted(payload: dict[str, typing.Any]) -> None:
installation_id = payload.get("installation", {}).get("id")
if installation_id:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to fail without an exception if installation_id is None?

Copy link
Contributor Author

@novakzaballa novakzaballa May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! At least initially we want an unhandled exception in case of these unexpected cases. GitHub should never send an "installation.delete" event without an installation ID, if that happens we want the alerts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +70 to +60
if feature:
if (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return early here.

if not feature:
    return
if ( #....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it's the same, right? I will keep this since it is a positive condition, it is returning early anyway, and the code is readable in this way.

from django.db import migrations


class Migration(migrations.Migration):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to combine this migration with the other one.

Copy link
Contributor Author

@novakzaballa novakzaballa May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Done.

Comment on lines +95 to +101
from integrations.github.constants import (
GitHubTag,
github_tag_description,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you need to inline import these constants? Surely they would be topline imports since there should be no cyclical import issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I have a circular import issue otherwise.

Comment on lines 338 to 339

print(feature_external_resource)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to remove this print statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

url = reverse("api-v1:github-webhook")

# When
client = APIClient()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the api_client fixture instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 1056 to 1061
# def test_handle_installation_deleted_with_non_existing_installation(mocker: MockerFixture):
# payload = {"installation": {"id": 456}}
# handle_installation_deleted(payload)
# mock_logger.error.assert_called_once_with(
# "Github Configuration with installation_id 456 does not exist"
# )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra commented out code. Should be deleted, yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Thanks! Deleted

@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 7, 2024
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 7, 2024
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 9, 2024
Copy link
Contributor

@zachaysan zachaysan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with some comments that may be helpful

Comment on lines +75 to +81
feature.tags.remove(
*feature.tags.filter(
Q(type=TagType.GITHUB.value) & Q(label__startswith=tag_label_pattern)
)
)

feature.tags.add(github_tag)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to call save() when removing or adding the tags?

Comment on lines +884 to +887
assert (
response.json()["non_field_errors"][0]
== "The fields feature, url must make a unique set."
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the fields feature and url do not make a unique set. Does the test set these as duplicates elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because already exists in this fixture:
this:

def feature_external_resource_gh_pr(

feature_external_resource: FeatureExternalResource,
) -> None:
# Given
settings.GITHUB_WEBHOOK_SECRET = WEBHOOK_SECRET
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If settings is being set like this it is better pulling it into the test as a fixture.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Comment on lines 722 to 725
mocker_logger.error.assert_called_once_with(
"GitHub Configuration with installation_id 765432 does not exist"
"The installation_id is not present in the payload: {'installation': {'test': 765432}, 'action': 'deleted'}"
)
assert response.status_code == status.HTTP_200_OK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this error really return an HTTP 200 response?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, 200 is enough.

Comment on lines 748 to 751
mocker_logger.error.assert_called_once_with(
"The installation_id is not present in the payload: {'installation': {'test': 765432}, 'action': 'deleted'}"
"GitHub Configuration with installation_id 765432 does not exist"
)
assert response.status_code == status.HTTP_200_OK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea with this error, should these really be 200 responses?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, 200 is enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 9, 2024
@novakzaballa novakzaballa force-pushed the feat/add-tags-for-github-integration branch from 07292e4 to 42d2ade Compare August 9, 2024 17:49
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 9, 2024
@novakzaballa novakzaballa force-pushed the feat/add-tags-for-github-integration branch from 42d2ade to e9e1e59 Compare August 9, 2024 19:15
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 9, 2024
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Aug 12, 2024
@novakzaballa novakzaballa added this pull request to the merge queue Aug 12, 2024
Merged via the queue into main with commit 7920e8e Aug 12, 2024
35 checks passed
@novakzaballa novakzaballa deleted the feat/add-tags-for-github-integration branch August 12, 2024 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Issue related to the REST API feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants