在组织级别启用 Github 中的分支保护规则

Enable branch protection rules in Github at the Organisation level

是否可以在 Github 中的组织级别启用分支保护规则,以便该组织的所有存储库部分都为应用的分支继承这些规则。现在,为同一组分支在每个回购协议的基础上启用这些相同的规则集真的很麻烦。

您应该尝试使用 Github API 的 update branch protection 端点和某种自动化流程,将分支保护规则应用于您组织中的所有新分支。

PUT /repos/:owner/:repo/branches/:branch/protection

我使用一个简单的 ruby 脚本让它工作,该脚本利用了 GitHub APIs :-

require "json"
require "logger"

LOGGER = Logger.new(STDOUT)

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


def repos(page = 1, list = [])
  cmd = %Q{curl -s --user "user:pwd" https://github_url/api/v3/orgs/org_name/repos?page=#{page}}
  data = JSON.parse(run(cmd))
  list.concat(data)
  repos(page + 1, list) unless data.empty?
  list
end

repos.each do |repo|
  require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://github_url/api/v3/repos/org_name/#{repo["name"]}/branches/master/protection")
request = Net::HTTP::Put.new(uri)
request.basic_auth("user", "pwd")
request["Accept"] = "application/vnd.github.luke-cage-preview+jso"
request.body = JSON.dump({
  "required_status_checks" => {
    "strict" => true,
    "contexts" => [
      "continuous-integration/travis-ci"
    ]
  },
  "enforce_admins" => true,
  "required_pull_request_reviews" => {
    "dismiss_stale_reviews" => true
  },
  "restrictions" => nil
})

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
end

您可以为服务器端 git 挂钩使用集中式解决方案,例如 Datree.io。 它具有如下内置策略:

  1. Enforce branch protection 所有当前的回购协议和未来创建的回购协议 - 防止删除主分支并强制推送。
  2. Enforce pull request flow 所有存储库(包括未来创建的)的默认分支 - 防止在没有拉取请求和检查的情况下直接提交到 master。

该产品主动更改 GitHub 现有存储库的设置,并强制执行未来创建的存储库的设置。

免责声明:我是Datree的联合创始人之一

取自@Ashley 的回答,对其进行了一些更新,稍作更改以反映当前 Github 的 API URL,并使用 GITHUB_ORG 和 [ 添加了自定义=12=]环境变量。

require "json"
require "logger"

$org = ENV["GITHUB_ORG"]
$token = ENV["GITHUB_ACCESS_TOKEN"]

LOGGER = Logger.new(STDOUT)

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


def repos(page = 1, list = [])
  cmd = %Q{curl -s -u dummy:#{$token} https://api.github.com/orgs/#{$org}/repos?page=#{page}}
  data = JSON.parse(run(cmd))
  list.concat(data)
  repos(page + 1, list) unless data.empty?
  list
end

repos.each do |repo|
p(repo["name"])
  require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://api.github.com/repos/#{$org}/#{repo["name"]}/branches/master/protection")
request = Net::HTTP::Put.new(uri)
request.basic_auth("dummy", $token)
request["Accept"] = "application/vnd.github.luke-cage-preview+jso"
request.body = JSON.dump({
  "required_status_checks" => {
    "strict" => true,
    "contexts" => []
  },
  "enforce_admins" => true,
  "required_pull_request_reviews" => {
    "dismiss_stale_reviews" => true
  },
  "restrictions" => nil
})

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
p(response)
end