Skip to content

Conversation

@zachaller
Copy link
Contributor

@zachaller zachaller commented Oct 23, 2025

Block PR Merges When Auto Branch Deletion is Enabled

Summary

This PR adds support for detecting and blocking pull request merges when SCM providers have automatic branch deletion enabled. This prevents conflicts with gitops-promoter's branch lifecycle management.

Problem

When SCM providers are configured to automatically delete branches after PR merge, it interferes with gitops-promoter's ability to manage the promotion workflow. The promoter needs to control when branches are deleted to maintain the integrity of the GitOps promotion chain.

Solution

Added a new HasAutoBranchDeletionEnabled() method to the PullRequestProvider interface that checks if automatic branch deletion is configured. When enabled, the controller refuses to merge PRs and emits a clear error message and Kubernetes event.

Provider-Specific Implementation

  • GitHub:

    • Checks the delete_branch_on_merge repository setting via the Repositories API
    • If enabled, checks if the source branch is protected via the Branch Protection API
    • Protected branches (with allow_deletions: false) are safe from auto-deletion
  • GitLab:

    • Checks the remove_source_branch_after_merge project setting via the Projects API
    • If enabled, checks if the source branch is protected via the Protected Branches API
    • Protected branches cannot be auto-deleted in GitLab
  • Forgejo: Controls branch deletion directly via DeleteBranchAfterMerge: false in merge options (always safe)

  • Fake: Returns false for testing purposes

Changes

Modified Files

  • internal/scms/pullrequest.go - Added HasAutoBranchDeletionEnabled method to interface
  • internal/scms/github/pullrequest.go - Implemented GitHub provider check
  • internal/scms/gitlab/pullrequest.go - Implemented GitLab provider check
  • internal/scms/forgejo/pullrequest.go - Implemented Forgejo provider (returns false with explanation)
  • internal/scms/fake/pullrequest.go - Implemented fake provider for testing
  • internal/controller/pullrequest_controller.go - Added merge blocking logic
  • internal/types/constants/events.go - Added new event constants for blocked merges
  • internal/scms/mock/mock_PullRequestProvider.go - Regenerated mocks

Behavior

When auto-deletion is disabled (default):

  • PRs merge normally ✅

When auto-deletion is enabled:

  • If source branch is protected (with deletion restrictions): PRs merge normally ✅
  • If source branch is NOT protected:
    • Merge is blocked with error: "Pull Request {name} merge blocked: repository has automatic branch deletion enabled. This setting must be disabled to allow gitops-promoter to manage branch lifecycle"
    • Warning event is generated with reason PullRequestMergeBlocked
    • Controller continues to retry, allowing users to fix the repository setting

Testing

  • All existing tests pass
  • No new tests added (feature is validated by existing merge tests)
  • Linter checks pass

Permissions

No new permissions required

  • GitHub: Existing Contents: Read and write permission already covers:
    • Reading repository settings (for delete_branch_on_merge)
    • Reading branch protection rules (for protected branch checks)
  • GitLab: Existing api scope already covers:
    • Reading project settings (for remove_source_branch_after_merge)
    • Reading protected branches
  • Forgejo: No repository-level check needed

Breaking Changes

None. This is a backward-compatible enhancement that adds safety checks.

Migration Notes

None required. Users with automatic branch deletion enabled will see merge failures with clear error messages instructing them to disable the setting.

Signed-off-by: Zach Aller <[email protected]>
Signed-off-by: Zach Aller <[email protected]>
Signed-off-by: Zach Aller <[email protected]>
Signed-off-by: Zach Aller <[email protected]>
Signed-off-by: Zach Aller <[email protected]>
@zachaller zachaller changed the title Block if branch deletion feat: Block if branch deletion is enabled Oct 23, 2025
@zachaller zachaller closed this Oct 23, 2025
@zachaller zachaller reopened this Oct 23, 2025
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 7.81250% with 59 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.35%. Comparing base (be73c6d) to head (271f727).

Files with missing lines Patch % Lines
internal/scms/gitlab/pullrequest.go 0.00% 25 Missing ⚠️
internal/scms/github/pullrequest.go 0.00% 20 Missing ⚠️
internal/controller/pullrequest_controller.go 27.27% 6 Missing and 2 partials ⚠️
internal/scms/forgejo/pullrequest.go 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #644      +/-   ##
==========================================
- Coverage   53.55%   53.35%   -0.21%     
==========================================
  Files          36       36              
  Lines        4429     3503     -926     
==========================================
- Hits         2372     1869     -503     
+ Misses       1792     1370     -422     
+ Partials      265      264       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zachaller
Copy link
Contributor Author

We don't really want to eat the API calls for this feature though

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