class RooOnRails::Checks::GitHub::BranchProtection

Public Instance Methods

call() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 15
def call
  ensure_status_checks!
  ensure_code_reviews!
  ensure_no_push!
  pass 'branch protection is sufficient'
end
fix() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 22
def fix
  client.protect_branch(
    repo,
    branch,
    options.merge(
      required_status_checks: fixed_required_status_checks,
      required_pull_request_reviews: fixed_pull_request_reviews,
      restrictions: fixed_restrictions,
      enforce_admins: true
    )
  )
end
intro() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 11
def intro
  'Checking if GitHub master branch is protected...'
end

Private Instance Methods

analysis_context() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 109
def analysis_context
  'codeclimate'
end
branch() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 125
def branch
  'master'
end
ci_context() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 103
def ci_context
  if Pathname.new('.travis.yml').exist? then 'continuous-integration/travis-ci'
  else 'ci/circleci'
  end
end
client() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 134
def client
  context.github.api_client
end
coverage_contexts() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 113
def coverage_contexts
  %w(codecov/patch codecov/project)
end
ensure_analysis_status_check!(contexts) click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 53
def ensure_analysis_status_check!(contexts)
  fail! 'no code analysis status check' unless contexts.include?(analysis_context)
end
ensure_ci_status_check!(contexts) click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 49
def ensure_ci_status_check!(contexts)
  fail! 'no continuous integration status check' unless contexts.include?(ci_context)
end
ensure_code_reviews!() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 62
def ensure_code_reviews!
  reviews = protection[:required_pull_request_reviews] || {}
  fail! 'code approvals should be dismissed on push' unless reviews[:dismiss_stale_reviews]

  users = reviews.dig(:dismissal_restrictions, :users)
  teams = reviews.dig(:dismissal_restrictions, :teams)
  fail! 'review dismissal restrictions should be enabled' if users.nil? || teams.nil?
  fail! 'nobody should be allowed to dismiss reviews' if users.any? || teams.any?
end
ensure_coverage_status_check!(contexts) click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 57
def ensure_coverage_status_check!(contexts)
  return if (contexts & coverage_contexts).sort == coverage_contexts.sort
  fail! 'no code coverage status checks'
end
ensure_no_push!() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 72
def ensure_no_push!
  users = protection.dig(:restrictions, :users)
  teams = protection.dig(:restrictions, :teams)
  fail! 'push restrictions should be enabled' if users.nil? || teams.nil?
  fail! 'nobody should be allowed to push to master' if users.any? || teams.any?
end
ensure_status_checks!() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 37
def ensure_status_checks!
  status_checks = protection[:required_status_checks] || {}
  enforce_admins = protection[:enforce_admins]
  fail! 'status checks are not enforced for admins' unless enforce_admins &&
                                                           enforce_admins[:enabled]

  contexts = status_checks[:contexts] || []
  ensure_ci_status_check!(contexts)
  ensure_analysis_status_check!(contexts)
  ensure_coverage_status_check!(contexts)
end
fixed_pull_request_reviews() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 90
def fixed_pull_request_reviews
  reviews = protection[:required_pull_request_reviews] || {}
  reviews.merge(
    dismiss_stale_reviews: true,
    dismissal_restrictions: { users: [], teams: [] }
  )
end
fixed_required_status_checks() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 79
def fixed_required_status_checks
  status_checks = protection[:required_status_checks] || {}
  status_checks.merge(
    contexts: (status_checks[:contexts] || []) | [
      ci_context,
      analysis_context,
      *coverage_contexts
    ]
  )
end
fixed_restrictions() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 98
def fixed_restrictions
  restrictions = protection[:restrictions] || {}
  restrictions.merge(users: [], teams: [])
end
options() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 129
def options
  accept = Octokit::Preview::PREVIEW_TYPES[:branch_protection]
  accept ? { accept: accept } : {}
end
protection() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 117
def protection
  client.branch_protection(repo, branch, options).to_h
end
repo() click to toggle source
# File lib/roo_on_rails/checks/github/branch_protection.rb, line 121
def repo
  "#{context.git_org}/#{context.git_repo}"
end