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

GitHub: Add bi-directional sync #3565

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

savish28
Copy link
Member

@savish28 savish28 commented Aug 12, 2021

Context: Github Bi-directional Sync

Related Pull Request: Cloud-CV/EvalAI-Starters#52

Models Considered:

  • Challenge
  • Challenge Phase

Deliverables:

  • Add github_token
  • Add sync for non-file fields
  • Add sync for file fields for challenge model
  • Add only updated fields commit

Testing without celery:
https://user-images.githubusercontent.com/32800267/129727539-80d18fd0-7cdc-489d-a3c6-0b346ce605c8.mp4

@KhalidRmb
cc: @Ram81

@savish28 savish28 changed the title GitHub: add bi-directional sync for non-file challenge field GitHub: Add bi-directional sync Aug 20, 2021
URLS = {"contents": "/repos/{}/contents/{}", "repos": "/repos/{}"}


class Github_Interface:
Copy link
Member

Choose a reason for hiding this comment

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

Please rename class to GithubInterface

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

return None
return response.json()

def return_github_url(self, url):
Copy link
Member

Choose a reason for hiding this comment

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

rename the method to get_github_url

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

url = "{0}{1}".format(base_url, url)
return url

def get_content_from_path(self, path):
Copy link
Member

Choose a reason for hiding this comment

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

Please add docstring for this method

Copy link
Member Author

Choose a reason for hiding this comment

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

Added.

return response

def get_data_from_path(self, path):
content_response = self.get_content_from_path(path)
Copy link
Member

Choose a reason for hiding this comment

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

same here

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

return string_data

def update_content_from_path(self, path, content):
url = URLS.get("contents").format(self.GITHUB_REPOSITORY, path)
Copy link
Member

Choose a reason for hiding this comment

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

same here

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.


@app.task
def github_challenge_phase_sync(challenge_phase):
from .serializers import ChallengePhaseSerializer
Copy link
Member

Choose a reason for hiding this comment

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

move to global imports

Copy link
Member Author

Choose a reason for hiding this comment

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

Since it is a circular import.

from .serializers import ChallengePhaseSerializer

for obj in serializers.deserialize("json", challenge_phase):
challenge_phase_obj = obj.object
Copy link
Member

Choose a reason for hiding this comment

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

create a util method for deserializing and use that

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

"is_restricted_to_select_one_submission",
"is_partial_submission_evaluation_enabled",
"allowed_submission_file_types",
]
Copy link
Member

Choose a reason for hiding this comment

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

move to a common util file

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

github.update_data_from_path("challenge_config.yaml", content_str)

# File fields Update
file_fields = ["description"]
Copy link
Member

Choose a reason for hiding this comment

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

same here

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

def github_sync_challenge(sender, instance, created, **kwargs):
if instance.github_repository and instance.github_token:
serialized_obj = serializers.serialize("json", [instance])
github_challenge_sync.delay(serialized_obj)
Copy link
Member

Choose a reason for hiding this comment

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

@savish28 the method names are confusing github_challenge_sync and github_sync_challenge (post save hook) it is not clear what these methods are for. Please rename the methods.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@codecov-commenter
Copy link

codecov-commenter commented Aug 24, 2021

Codecov Report

Merging #3565 (2fd2db6) into master (96968d6) will decrease coverage by 1.40%.
The diff coverage is 37.15%.

@@            Coverage Diff             @@
##           master    #3565      +/-   ##
==========================================
- Coverage   72.93%   71.53%   -1.41%     
==========================================
  Files          83       20      -63     
  Lines        5368     3235    -2133     
==========================================
- Hits         3915     2314    -1601     
+ Misses       1453      921     -532     
Impacted Files Coverage Δ
frontend/src/js/controllers/authCtrl.js 53.91% <6.38%> (-12.95%) ⬇️
frontend/src/js/controllers/profileCtrl.js 79.76% <20.00%> (-13.10%) ⬇️
frontend/src/js/controllers/permissionCtrl.js 36.36% <22.22%> (-63.64%) ⬇️
frontend/src/js/controllers/challengeCtrl.js 63.54% <37.00%> (-10.15%) ⬇️
frontend/src/js/controllers/updateProfileCtrl.js 82.55% <44.44%> (-10.30%) ⬇️
frontend/src/js/controllers/challengeListCtrl.js 95.74% <50.00%> (+1.06%) ⬆️
...ntend/src/js/controllers/challengeHostTeamsCtrl.js 70.50% <66.66%> (-1.18%) ⬇️
frontend/src/js/controllers/teamsCtrl.js 71.17% <75.00%> (ø)
frontend/src/js/controllers/ChallengeInviteCtrl.js 100.00% <100.00%> (ø)
frontend/src/js/controllers/SubmissionFilesCtrl.js 95.45% <100.00%> (ø)
... and 30 more
Impacted Files Coverage Δ
frontend/src/js/controllers/authCtrl.js 53.91% <6.38%> (-12.95%) ⬇️
frontend/src/js/controllers/profileCtrl.js 79.76% <20.00%> (-13.10%) ⬇️
frontend/src/js/controllers/permissionCtrl.js 36.36% <22.22%> (-63.64%) ⬇️
frontend/src/js/controllers/challengeCtrl.js 63.54% <37.00%> (-10.15%) ⬇️
frontend/src/js/controllers/updateProfileCtrl.js 82.55% <44.44%> (-10.30%) ⬇️
frontend/src/js/controllers/challengeListCtrl.js 95.74% <50.00%> (+1.06%) ⬆️
...ntend/src/js/controllers/challengeHostTeamsCtrl.js 70.50% <66.66%> (-1.18%) ⬇️
frontend/src/js/controllers/teamsCtrl.js 71.17% <75.00%> (ø)
frontend/src/js/controllers/ChallengeInviteCtrl.js 100.00% <100.00%> (ø)
frontend/src/js/controllers/SubmissionFilesCtrl.js 95.45% <100.00%> (ø)
... and 30 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2bc3487...2fd2db6. Read the comment docs.

@RishabhJain2018
Copy link
Member

@Ram81 @savish28 Is this PR ready for review?

@savish28
Copy link
Member Author

savish28 commented Sep 9, 2021

@RishabhJain2018 Yes it is!!

@@ -0,0 +1,37 @@
# Fields from Challenge, ChallengePhase model to be considered for github_sync

challenge_non_file_fields = [
Copy link
Member

Choose a reason for hiding this comment

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

@savish28 is there a way we can use the serializer or model to generate this list of fields? Currently, if a new field gets added we'll have to add it here manually. It might happen that some forgets adding it here which would mean there is no sync happening for that field. If we can use models/serializer for this list it would be great

Copy link
Member Author

Choose a reason for hiding this comment

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

@Ram81, we only wish to have only selected fields(that are editable from frontend) in the sync and not all fields, getting it from serializer would mean using all fields and that is undesirable because there are a lot of fields that are not in the challenge_config and might also be critical to share those.

URLS = {"contents": "/repos/{}/contents/{}", "repos": "/repos/{}"}


class GithubInterface:
Copy link
Member

Choose a reason for hiding this comment

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

@savish28 can we move this class to a separate file called github_interface.py

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah sure :) Done.

if not github.is_repository():
return
try:
# Challenge Non-file field Update
Copy link
Member

Choose a reason for hiding this comment

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

Change to Challenge non-file field update

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

content_str = yaml.dump(challenge_config_yaml, sort_keys=False)
github.update_data_from_path("challenge_config.yaml", content_str)

# Challenge File fields Update
Copy link
Member

Choose a reason for hiding this comment

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

Change to Challenge file fields update

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

continue
github.update_data_from_path(field_path, getattr(challenge, field))
except Exception as e:
logger.info("Github Sync unsuccessful due to {}".format(e))
Copy link
Member

Choose a reason for hiding this comment

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

Why is this a info log? This should be a error log

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

field_path, getattr(challenge_phase, field)
)
break

Copy link
Member

Choose a reason for hiding this comment

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

remove newline

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

github.update_data_from_path(
field_path, getattr(challenge_phase, field)
)
break
Copy link
Member

Choose a reason for hiding this comment

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

why do we have a break here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because at a time only one challenge_phase is updated. Because it is initiated by post-hook of ChallengePhase

break

except Exception as e:
logger.info(
Copy link
Member

Choose a reason for hiding this comment

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

same here, Why is this not a error log?

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@@ -226,6 +231,13 @@ def create_eks_cluster_for_challenge(sender, instance, created, **kwargs):
aws.challenge_approval_callback(sender, instance, field_name, **kwargs)


@receiver(signals.post_save, sender="challenges.Challenge")
def challenge_sync(sender, instance, created, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

rename to challenge_details_sync

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@@ -347,6 +359,16 @@ def save(self, *args, **kwargs):
return challenge_phase_instance


@receiver(signals.post_save, sender="challenges.ChallengePhase")
def challenge_phase_sync(sender, instance, created, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

change to challenge_phase_details_sync

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@savish28
Copy link
Member Author

@Ram81 Ping! :)

@Ram81
Copy link
Member

Ram81 commented Nov 28, 2021

Thanks for the ping @savish28. I will review this PR today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants