• 
      

    Isolate service connect UI APIs into their own object.

    Review Request #15221 — Created Aug. 11, 2026 and submitted

    Information

    Review Board
    release-9.x

    Reviewers

    In prior changes I'd added some new classmethods to BaseHostingService
    in order to implement the new Connected Services page. As this grows,
    it's making the hosting service even more unwieldy. This change moves
    those out into a helper object, which can be subclassed for
    service-specific functionality.

    Ran unit tests.

    Summary ID
    Isolate service connect UI APIs into their own object.
    In prior changes I'd added some new classmethods to BaseHostingService in order to implement the new Connected Services page. As this grows, it's making the hosting service even more unwieldy. This change moves those out into a helper object, which can be subclassed for service-specific functionality. Testing Done: Ran unit tests.
    sponzwvpxzsmzurmzzvowpwuumkrxwzv
    Description From Last Updated

    Can we make BaseHostingServiceConnectUI generic over the hosting service type?

    maubin maubin

    render_to_string() should already be a SafeString.

    chipx86 chipx86

    Can we make these keyword-only, so if we ever change any of this call sites will be stable?

    chipx86 chipx86

    I assume this is the case, but I want to check: This is just a priority list for the names, …

    chipx86 chipx86

    This is missing the full module path.

    chipx86 chipx86

    render_to_string() should be a SafeString already.

    chipx86 chipx86

    This is missing a Version Added.

    chipx86 chipx86

    'django.utils.safestring.mark_safe' imported but unused Column: 1 Error code: F401

    reviewbot reviewbot

    This is missing the full module path.

    chipx86 chipx86
    david
    chipx86
    1. Looks good. A few very small things.

    2. Show all issues

      render_to_string() should already be a SafeString.

    3. reviewboard/hostingsvcs/base/connect_ui.py (Diff revision 2)
       
       
       
       
      Show all issues

      Can we make these keyword-only, so if we ever change any of this call sites will be stable?

    4. reviewboard/hostingsvcs/base/connect_ui.py (Diff revision 2)
       
       
       
       
       
      Show all issues

      I assume this is the case, but I want to check: This is just a priority list for the names, right? Since hosting services can set both of these to True.

      1. Yes. Something like github should be listed as "Source hosting" even if it also does issues.

    5. Show all issues

      This is missing the full module path.

    6. Show all issues

      render_to_string() should be a SafeString already.

    7. Show all issues

      This is missing a Version Added.

    8. 
        
    david
    Review request changed
    Commits:
    Summary ID
    Isolate service connect UI APIs into their own object.
    In prior changes I'd added some new classmethods to BaseHostingService in order to implement the new Connected Services page. As this grows, it's making the hosting service even more unwieldy. This change moves those out into a helper object, which can be subclassed for service-specific functionality. Testing Done: Ran unit tests.
    sponzwvpxzsmzurmzzvowpwuumkrxwzv
    Isolate service connect UI APIs into their own object.
    In prior changes I'd added some new classmethods to BaseHostingService in order to implement the new Connected Services page. As this grows, it's making the hosting service even more unwieldy. This change moves those out into a helper object, which can be subclassed for service-specific functionality. Testing Done: Ran unit tests.
    sponzwvpxzsmzurmzzvowpwuumkrxwzv

    Checks run (1 failed, 1 succeeded)

    flake8 failed.
    JSHint passed.

    flake8

    david
    maubin
    1. 
        
    2. Show all issues

      Can we make BaseHostingServiceConnectUI generic over the hosting service type?

      1. While I can do that in the definition, I think it breaks for subclasses because it makes the two classes depend on each other at definition time. Neither of these works:

        class GitHubConnectUI(BaseGitHubConnectUI[GitHub]):
            ...
        
        class GitHub(BaseHostingService...):
            connect_ui_cls = GitHubConnectUI
        

        class GitHub(BaseHostingService...):
            connect_ui_cls = GitHubConnectUI
        
        class GitHubConnectUI(BaseGitHubConnectUI[GitHub]):
            ...
        
      2. Ah I see.

    3. 
        
    maubin
    1. Ship It!
    2. 
        
    david
    maubin
    1. Ship It!
    2. 
        
    chipx86
    1. 
        
    2. Show all issues

      This is missing the full module path.

    3. 
        
    david
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-9.x (fd1168b)