Skip to content

#xref: https://github.com/github/accessibility-audits/issues/14958 #19

@TNTurner23

Description

@TNTurner23

Problem

The Rename Branch dialog does not validate the new branch name against repository rulesets. The Create Branch dialog already checks repo rules and shows warnings/errors when a branch name violates repository rulesets, but renaming a branch has no such validation. This means users can attempt to rename a branch to a name that violates repository rulesets, which will then be rejected in the commit form (or server side if pushed outside of Desktop).

Solution

Added repo rules validation to the Rename Branch dialog, matching the Create Branch dialog's behavior. As part of this, extracted the shared validation logic into a reusable utility to avoid duplication.

Changes

  1. New shared utility (app/src/ui/lib/branch-name-rule-validation.tsx):

    • checkBranchNameRules() — pure async function that validates a branch name against repo rulesets and returns an error/warning result (or null if valid)
    • renderBranchNameRuleError() — stateless render helper for error/warning UI
    • IBranchRuleError — shared type for the error state
  2. Rename Branch dialog (app/src/ui/rename-branch/rename-branch-dialog.tsx):

    • Added accounts and cachedRepoRulesets props
    • Debounced validation on name change (500ms) using the shared utility
    • Validates on dialog open via componentDidMount so pre-filled names show violations immediately
    • Shows InputError (blocks rename) or InputWarning (allows with caution) based on bypass status
    • Connected aria-describedby for screen reader accessibility
  3. Create Branch dialog (app/src/ui/create-branch/create-branch-dialog.tsx):

    • Refactored to use the same shared utility, eliminating ~80 lines of duplicated logic
  4. Dialog width (app/styles/ui/_dialog.scss):

    • Set fixed width: 400px on the rename-branch dialog (matching create-branch) to prevent jarring resize when errors appear
  5. Prop wiring (app/src/ui/app.tsx):

    • Passes accounts and cachedRepoRulesets to the RenameBranch popup

Acceptance Criteria

  • Given a GitHub repository with branch name pattern rulesets configured, When the user opens the Rename Branch dialog and types a name that violates a non-bypassable rule, Then an error message is shown and the Rename button is disabled
  • Given a GitHub repository with branch name pattern rulesets configured, When the user opens the Rename Branch dialog and types a name that violates a bypassable rule, Then a warning message is shown but the Rename button remains enabled
  • Given a GitHub repository with branch name pattern rulesets configured, When the user opens the Rename Branch dialog and the pre-filled branch name violates a rule, Then the error/warning is shown immediately on dialog open
  • Given a GitHub repository with branch name pattern rulesets configured, When the user opens the Rename Branch dialog and types a name that passes all rules, Then no error or warning is shown and the Rename button is enabled
  • Given a local-only repository (not on GitHub), When the user opens the Rename Branch dialog, Then no repo rules validation is performed (same as before)
  • Given any repository, When the user clears the branch name field, Then the Rename button is disabled (existing behavior preserved)
  • Given any repository, When the user opens the Create Branch dialog, Then it behaves identically to before (no regression from shared utility extraction)

Risk Assessment

Risk tier: Medium — UI and API integration
Affected areas: Rename Branch dialog UI, Create Branch dialog (refactor only), popup prop wiring in app.tsx
Could break: Branch renaming or creation flow if shared utility has a bug; unnecessary API calls for non-GitHub repos (mitigated by useRepoRulesLogic guard in the shared function)
Edge cases considered:

  • Non-GitHub repositories: isRepositoryWithGitHubRepository check in shared utility prevents API calls
  • Free plan + private repos: useRepoRulesLogic returns false, skipping validation
  • Race conditions: Branch name staleness checks after each async operation in both dialogs
  • Empty branch name: Shared utility returns null immediately
  • User types faster than API responds: Debounce clears pending calls; staleness checks ignore stale results
  • Dialog opens with violating name pre-filled: componentDidMount triggers immediate validation

Screenshots

CleanShot.2026-03-18.at.16.57.07-converted.mp4

Test Plan

Automated: No new unit tests — the core checkBranchNameRules() calls the GitHub API, and the existing test infrastructure does not mock repo rules API responses. The underlying RepoRulesMetadataRules.getFailedRules() and parseRepoRules() logic is unchanged and already has coverage.

Manual QA:

  1. Open a repository with branch name pattern rulesets configured on GitHub
  2. Right-click a branch and select "Rename..."
  3. Type a name that violates a rule → verify error/warning appears
  4. Type a valid name → verify no error/warning
  5. Verify the error appears immediately on dialog open if the current branch name violates rules
  6. Open a local (non-GitHub) repository → verify rename works without any validation delay
  7. Verify the Create Branch dialog still works correctly (no regression from refactor)

Release notes

Notes: [Added] Rename branch dialog now validates branch names against repository rulesets, showing warnings or errors when names violate configured branch name pattern rules

_Originally posted by @tidy-dev in https://github.com/desktop/desktop/pull/21822_``

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions