Skip to content

Conversation

Zahed-Riyaz
Copy link
Contributor

@Zahed-Riyaz Zahed-Riyaz commented Jul 16, 2025

This PR amends #4737 to store github_branch field for challenge creation.

- Update create_or_update_github_challenge to use both github_repository and github_branch for challenge lookup
- Add default branch logic: when GITHUB_REF_NAME is empty, defaults to 'challenge'
- Create combined migration 0113 that adds github_branch field and unique constraint
- Fix database seeder to use unique github values for each challenge
- Update tests to expect 'challenge' as default branch name
- Enable multiple challenge versions from same repository using different branches

Fixes issue where different branches would update existing challenges instead of creating new ones.
@Zahed-Riyaz Zahed-Riyaz marked this pull request as ready for review July 17, 2025 00:14
@Zahed-Riyaz Zahed-Riyaz changed the title Add github_branch to models Add field to store github_branch for challenges Jul 17, 2025
Copy link
Collaborator

@gchhablani gchhablani left a comment

Choose a reason for hiding this comment

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

Left some initial comments.

# The github branch name used to create/update the challenge
github_branch = models.CharField(
max_length=200, null=True, blank=True, default=""
max_length=200, null=True, blank=True, default=challenge
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this not be within quotes?

github_branch = request.data.get("GITHUB_BRANCH_NAME", "")

github_branch = request.data.get("GITHUB_BRANCH_NAME") or request.data.get(
"BRANCH_NAME", "challenge"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you please add a reference as to where these keys are being populated from?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need a fallback? Should we not always expect a branch? Since the challenge repo will be pushing at some branch?

Copy link
Contributor Author

@Zahed-Riyaz Zahed-Riyaz Jul 17, 2025

Choose a reason for hiding this comment

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

I don't believe there's a reference of the keys in EvalAI documentation, but originally I used GITHUB_REF_NAME and was instructed to change it to GITHUB_BRANCH_NAME during PR review in #4737.

I updated the empty string default to "challenge" now for backward compatibility so that old existing challenges (I believe in local servers) will now have a github_branch versus an empty string. Any challenge on the platform would naturally always expect a github_branch and will store one.
Modern workflows should always specify the branch, older scripts and code if for whatever reason don't specify the github_branch, they'll have a default fallback for good measure.

Screenshot 2025-07-17 at 2 45 51 PM

Comment on lines 60 to 64
# Data migration to populate existing records
migrations.RunPython(
populate_github_branch_default,
reverse_populate_github_branch_default,
),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we running populate github branch default and then reversing it??

Copy link
Contributor Author

@Zahed-Riyaz Zahed-Riyaz Jul 17, 2025

Choose a reason for hiding this comment

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

The migration itself was written to handle the populating at first (then reverse it for use of script), but now that a script is explicitly written for it, it might be best to remove it from the migration entirely.

Comment on lines 60 to 64
# Data migration to populate existing records
migrations.RunPython(
populate_github_branch_default,
reverse_populate_github_branch_default,
),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this the best way to handle this scenario?

Comment on lines +1 to +27
#!/usr/bin/env python
# Command to run: python manage.py shell < scripts/migration/populate_github_branch.py
"""
Populate existing challenges with github_branch="challenge" for backward compatibility.
This script should be run after the migration to ensure all existing challenges
have the github_branch field populated with the default value.
"""

import traceback

from challenges.models import Challenge
from django.db import models


def populate_github_branch_fields():
"""
Populate existing challenges with empty github_branch fields to use "challenge" as default.
"""
print("Starting github_branch field population...")

challenges_to_update = (
Challenge.objects.filter(github_repository__isnull=False)
.exclude(github_repository="")
.filter(
models.Q(github_branch__isnull=True) | models.Q(github_branch="")
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we already have this script to populate and back-fill, why do we need to the populate/reverse populate methods at all?

) or self.request.data.get("BRANCH_NAME")
if not branch:
branch = "challenge"
pattern = r"^challenge-\d{4}-[a-zA-Z0-9]+$"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will this also be okay with just "challenge" (default) if passed?

self.assertEqual(response.json(), expected)

# Verify github_branch defaults to empty string when not provided
# Verify github_branch defaults to "challenge" when not provided
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please also add when the branch name is "challenge", when branch name is "xyzabc", and when branch name is "challenge-2025-v2" (whatever format you have chosen).

Copy link

codecov bot commented Jul 17, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 76.91%. Comparing base (96968d6) to head (c8bd7c9).
Report is 1222 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4745      +/-   ##
==========================================
+ Coverage   72.93%   76.91%   +3.98%     
==========================================
  Files          83       21      -62     
  Lines        5368     3608    -1760     
==========================================
- Hits         3915     2775    -1140     
+ Misses       1453      833     -620     

see 75 files with indirect coverage changes

see 75 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Zahed-Riyaz
Copy link
Contributor Author

Zahed-Riyaz commented Jul 17, 2025

The migration as of now adds challenge_github_repo_branch_partial_idx which ensures that challenges are unique to the repository's branch, i.e, validating that the combination of branch and repo is unique to a challenge and can't be used to create multiple challenges.

This is why changes were made in test_views.py. To ensure each challenge has a unique name, the following change was made :
challenge <-> challenge1 in the GetChallengeBasedonTeams set up.

@Zahed-Riyaz Zahed-Riyaz requested a review from gchhablani July 17, 2025 17:16
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.

2 participants