• 
      

    Improve GitHub repo owner/name storage.

    Review Request #15342 — Created Sept. 24, 2026 and updated

    Information

    Review Board
    release-9.x

    Reviewers

    The way that GitHub repos were storing their owner name was quite
    awkward. Each individual form (private user, public user, private org,
    public org) had its own prefix, and when we'd need to conditionally look
    up keys based on this.

    This change adds a new storage mechanism and accessor for the GitHub
    repository owner and name. These are stored in a new canonical form by
    the GitHub repository form(s). If the repo does not have the new
    canonical form, it will fall back to the ugly lookups previously used.
    The fallback (and check_repository(), which resolves the owner and
    name inline from submitted form data before anything is saved) respects
    plan_field_prefix, keeping subclasses like GitHub Enterprise working.

    As part of this, get_repository_display_path() no longer
    reverse-engineers the owner and name from the clone URL, since the same
    information is available in extra_data. If the stored data is unusable,
    it falls back to the raw path rather than parsing it.

    The _get_repository_owner_raw() and _get_repository_name_raw()
    methods are removed. Their only remaining caller was
    check_repository(), which now resolves the owner and name itself.

    Ran unit tests.

    Summary ID
    Improve GitHub repo owner/name storage.
    The way that GitHub repos were storing their owner name was quite awkward. Each individual form (private user, public user, private org, public org) had its own prefix, and when we'd need to conditionally look up keys based on this. This change adds a new storage mechanism and accessor for the GitHub repository owner and name. These are stored in a new canonical form by the GitHub repository form(s). If the repo does not have the new canonical form, it will fall back to the ugly lookups previously used. The fallback (and `check_repository()`, which resolves the owner and name inline from submitted form data before anything is saved) respects `plan_field_prefix`, keeping subclasses like GitHub Enterprise working. As part of this, `get_repository_display_path()` no longer reverse-engineers the owner and name from the clone URL, since the same information is available in extra_data. If the stored data is unusable, it falls back to the raw path rather than parsing it. The `_get_repository_owner_raw()` and `_get_repository_name_raw()` methods are removed. Their only remaining caller was `check_repository()`, which now resolves the owner and name itself. Testing Done: Ran unit tests.
    ulsqxkwnsuosurznqrplyxxyozyrmvwm
    Description From Last Updated

    Should we call .lower() on the owner and name when we save it so that its always in the casing …

    maubin maubin

    This calls GitHub directly, so it won't work for GitHub Enterprise. We should use self._hosting_service_cls here instead.

    maubin maubin

    We should document that this can now raise KeyError and InvalidPlanError.

    maubin maubin
    maubin
    1. 
        
    2. Show all issues

      Should we call .lower() on the owner and name when we save it so that its always in the casing that GitHub uses in its API? Instead of always having to remember to call .lower() when comparing them.

      1. I don't think that buys anything. GitHub's API doesn't force lowercase, it's case insensitive. Because the API just returns what the owner chose (microsoft/TypeScript, reviewboard/ReviewBot), we still need to do lower() in places like get_accessible_repositories(). Storing it as lowercase would give us one lower() call instead of two, but also impacts the way we show things in the UI.

    3. Show all issues

      This calls GitHub directly, so it won't work for GitHub Enterprise. We should use self._hosting_service_cls here instead.

    4. Show all issues

      We should document that this can now raise KeyError and InvalidPlanError.

    5. 
        
    david
    Review request changed
    Commits:
    Summary ID
    Improve GitHub repo owner/name storage.
    The way that GitHub repos were storing their owner name was quite awkward. Each individual form (private user, public user, private org, public org) had its own prefix, and when we'd need to conditionally look up keys based on this. This change adds a new storage mechanism and accessor for the GitHub repository owner and name. These are stored in a new canonical form by the GitHub repository form(s). If the repo does not have the new canonical form, it will fall back to the ugly lookups previously used. The fallback (and `check_repository()`, which resolves the owner and name inline from submitted form data before anything is saved) respects `plan_field_prefix`, keeping subclasses like GitHub Enterprise working. As part of this, `get_repository_display_path()` no longer reverse-engineers the owner and name from the clone URL, since the same information is available in extra_data. If the stored data is unusable, it falls back to the raw path rather than parsing it. The `_get_repository_owner_raw()` and `_get_repository_name_raw()` methods are removed. Their only remaining caller was `check_repository()`, which now resolves the owner and name itself. Testing Done: Ran unit tests.
    ulsqxkwnsuosurznqrplyxxyozyrmvwm
    Improve GitHub repo owner/name storage.
    The way that GitHub repos were storing their owner name was quite awkward. Each individual form (private user, public user, private org, public org) had its own prefix, and when we'd need to conditionally look up keys based on this. This change adds a new storage mechanism and accessor for the GitHub repository owner and name. These are stored in a new canonical form by the GitHub repository form(s). If the repo does not have the new canonical form, it will fall back to the ugly lookups previously used. The fallback (and `check_repository()`, which resolves the owner and name inline from submitted form data before anything is saved) respects `plan_field_prefix`, keeping subclasses like GitHub Enterprise working. As part of this, `get_repository_display_path()` no longer reverse-engineers the owner and name from the clone URL, since the same information is available in extra_data. If the stored data is unusable, it falls back to the raw path rather than parsing it. The `_get_repository_owner_raw()` and `_get_repository_name_raw()` methods are removed. Their only remaining caller was `check_repository()`, which now resolves the owner and name itself. Testing Done: Ran unit tests.
    ulsqxkwnsuosurznqrplyxxyozyrmvwm

    Checks run (2 succeeded)

    flake8 passed.
    JSHint passed.
    maubin
    1. Ship It!
    2.