Enable protected branches for all GitHub repositories

By: Ian Winter


  • ruby
  • github

We recently decided, for safety reasons and ensuring solid reviews, protecting our master branches in GitHub was something we should be doing. Having looked into it, a few quick clicks later our core repositories were done. The challenge came down the line when we needed to easily turn them all on. With >100 repositories that would be somewhat of an arduous point and click task so I knocked up a crude and basic script to do it for me.

Reference Articles

For reference a few pages on GitHub’s site are useful:

Note from API documentation

It should be noted that in the API documentation it states that protected branch API calls are in Developer Preview so you’ll notice the extra part from the docs to enable this:

-H "Accept: application/vnd.github.loki-preview+json"

The Script

require "json"
require "logger"

LOGGER = Logger.new(STDOUT)

def run(cmd)
  LOGGER.debug("Running: #{cmd}")
  output = `#{cmd}`
  raise "Error: #{$?}" unless $?.success?

def repos(page = 1, list = [])
  cmd = %Q{curl -s -H "Authorization: bearer #{BEARER_TOKEN}" https://api.github.com/orgs/#{ORGANIZATION}/repos?page=#{page}}
  data = JSON.parse(run(cmd))
  repos(page + 1, list) unless data.empty?

repos.each do |repo|
  cmd = %Q{curl -s -X PUT -H "Authorization: bearer #{BEARER_TOKEN}" -H "Accept: application/vnd.github.loki-preview+json" --data '{"required_status_checks":{"include_admins":true,"strict":true,"contexts":[]},"required_pull_request_reviews":{"include_admins":true},"restrictions":null}' https://api.github.com/repos/#{ORGANIZATION}/#{repo["name"]}/branches/master/protection}

Update: Nov. 2017

Since writing this post, the API for protected branches is no longer in Developer Preview. Additionally some of the options have moved around in the JSON you need to send.

Most of the original script is fine, but, the API section at the end needs to be updated. We’ve also added the dismiss_stale_reviews option which ensures if any commits are pushed after an approval they are also checked.

repos.each do |repo|
  cmd = %Q{curl -s -X PUT -H "Authorization: bearer #{BEARER_TOKEN}" --data '{"required_status_checks":{"strict":true,"contexts":[]},"enforce_admins": true,"required_pull_request_reviews":{"dismiss_stale_reviews": true},"restrictions":null}' https://api.github.com/repos/#{ORGANIZATION}/#{repo["name"]}/branches/master/protection}

About the Author

Ian Winter

Ian Winter is Head of Technical Operations for Venntro. He manages a team of four engineers who provide 24/7/365 support and are responsible for over 120 physical, virtual, storage and network devices.