class GitlabBranchRename::Operation

Public Class Methods

new(configuration, logger) click to toggle source
# File lib/gitlab_branch_rename/operation.rb, line 5
def initialize(configuration, logger)
  @configuration = configuration
  @logger = logger
end

Public Instance Methods

execute() click to toggle source
# File lib/gitlab_branch_rename/operation.rb, line 10
def execute
  projects = Gitlab.projects(min_access_level: @configuration.minimum_access_level,
                             owned: true,
                             per_page: 5)
  projects.auto_paginate do |project|
    @logger.info("Evaluating #{project.path_with_namespace}")

    # Verify this project meets criteria for renaming
    unless @configuration.has_visibility.include?(project.visibility)
      @logger.debug("Project has visibility #{project.visibility}, skipping")
      next
    end
    if project.archived
      @logger.debug("Project is archived")
      next
    end

    # Feature: Skip forks?

    # Skip projects you don"t have proper permission to change
    # Verify it meets your criteria for renaming default branch
    if @configuration.is_default_branch and project.default_branch != @configuration.branch_to_rename
      @logger.debug("Project default branch does not match is_default_branch criteria")
      next
    end

    # Feature: verify new branch doesn't already exist

    # Verify new branch doesn't exist already
    begin
      Gitlab.branch(project.id, @configuration.new_branch_name)
      @logger.debug("Destination branch #{@configuration.new_branch_name} already exists")
      next
    rescue Gitlab::Error::NotFound => e
      @logger.debug("Destination branch #{@configuration.new_branch_name} does not exist yet")
    end

    # Save branch protection parameters
    old_branch = begin
                   Gitlab.branch(project.id, @configuration.branch_to_rename)
                 rescue Gitlab::Error::NotFound => e
                   @logger.warn("Project #{project.path_with_namespace} doesn't have branch #{@configuration.branch_to_rename}")
                   next
                 end
    branch_protection_parameters = nil
    if old_branch.protected
      # Save branch protection information
      bpp_raw = Gitlab.protected_branch(project.id, old_branch.name)
      bpp_hash = bpp_raw.to_hash
      branch_protection_parameters = bpp_hash.slice("push_access_levels", "merge_access_levels", "unprotect_access_levels", "code_owner_approval_required")
      @logger.debug("Will transfer branch protection parameters: #{branch_protection_parameters}")
    end

    # Confirm or pretend
    msg = "Rename #{project.path_with_namespace} branch #{@configuration.branch_to_rename} to #{@configuration.new_branch_name} " +
        (branch_protection_parameters.nil? ? "without" : "with") + " protection"
    if @configuration.pretend
      puts(msg)
      @logger.info(msg)
      next
    end
    unless @configuration.skip_confirm
      puts(msg)
      print("\tContinue with rename and delete? (y/N) ")
      input = gets.chomp
      if input != "y"
        msg = "Skipping branch rename for #{project.path_with_namespace} based on user input #{input}"
        puts(msg)
        @logger.info(msg)
        next
      end
      @logger.info("User confirmed branch rename for #{project.path_with_namespace}")
    end

    # Create new branch
    begin
      Gitlab.create_branch(project.id, @configuration.new_branch_name, old_branch.name)
      @logger.debug("Created new branch with name #{@configuration.new_branch_name}")
    rescue StandardError => e
      @logger.error("Error creating new branch: #{e}")
      next
    end

    # Protect branch
    unless branch_protection_parameters.nil?
      begin
        Gitlab.protect_branch(project.id, @configuration.new_branch_name, branch_protection_parameters)
        @logger.debug("Protected branch with parameters #{branch_protection_parameters}")
      rescue StandardError => e
        @logger.error("Error protecting new branch: #{e} with #{branch_protection_parameters}")
      end
    end

    # Feature: Update PRs? Issues?

    # Change default branch
    begin
      Gitlab.edit_project(project.id, {default_branch: @configuration.new_branch_name})
      @logger.debug("Changed default branch")
    rescue StandardError => e
      @logger.error("Error changing default branch: #{e}")
    end

    # Unprotect protected branches
    if branch_protection_parameters
      begin
        Gitlab.unprotect_branch(project.id, old_branch.name)
        @logger.debug("Unprotected old branch")
      rescue StandardError => e
        @logger.error("Error unprotecting old branch: #{e}")
      end
    end

    # Delete old branch
    begin
      Gitlab.delete_branch(project.id, old_branch.name)
      @logger.debug("Deleted old branch")
    rescue StandardError => e
      @logger.error("Error deleting old branch: #{e}")
    end
  end
end