This repository has been archived by the owner on Oct 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathconfigure_repo.rb
173 lines (150 loc) · 4.64 KB
/
configure_repo.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
require "base64"
require "yaml"
class ConfigureRepo
attr_reader :repo, :client
def initialize(repo, client, overrides = nil)
@repo = repo
@client = client
@overrides = overrides || {}
end
def configure!
puts "Updating #{repo[:full_name]}"
update_repo_settings
protect_default_branch
protect_gh_pages_branch
update_webhooks
enable_vulnerability_alerts
enable_automated_security_fixes
puts "√ #{repo[:full_name]}"
rescue Octokit::NotFound => e
puts "Could not find #{repo[:full_name]}. Possibly the govuk-ci user doesn't have admin access to this repo."
end
private
attr_reader :overrides
def update_repo_settings
client.edit_repository(
repo[:full_name],
allow_merge_commit: true,
allow_squash_merge: overrides.fetch("allow_squash_merge", false),
allow_rebase_merge: false,
delete_branch_on_merge: true,
)
end
def protect_default_branch
config = {
enforce_admins: true,
required_status_checks: required_status_checks,
required_pull_request_reviews: {
dismiss_stale_reviews: false,
}
}
if overrides["need_production_access_to_merge"]
config.merge!(
restrictions: { users: [], teams: %w[gov-uk-production-admin gov-uk-production-deploy] }
)
end
client.protect_branch(repo[:full_name], repo[:default_branch], config)
end
def protect_gh_pages_branch
# https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection
config = {
enforce_admins: nil,
required_status_checks: nil,
required_pull_request_reviews: nil,
}
client.protect_branch(repo[:full_name], "gh-pages", config)
rescue Octokit::NotFound => e
# no gh-pages branch exists. Continue.
end
def update_webhooks
existing_webhooks = client.hooks(repo[:full_name])
# GitHub Trello Poster
if existing_webhooks.map(&:config).map(&:url).include?("https://govuk-github-trello-poster.herokuapp.com/payload")
puts "√ GitHub Trello Poster webhook exists"
else
puts "Creating GitHub Trello Poster webhook"
client.create_hook(
repo[:full_name],
"web",
{
url: "https://govuk-github-trello-poster.herokuapp.com/payload",
content_type: "json",
},
{
events: ["pull_request"],
active: true,
}
)
end
# Jenkins CI
if jenkinsfile_exists?
if existing_webhooks.map(&:config).map(&:url).include?("https://ci.integration.publishing.service.gov.uk/github-webhook/")
puts "√ Jenkins CI webhook exists"
else
puts "Creating Jenkins CI webhook"
client.create_hook(
repo[:full_name],
"web",
{
url: "https://ci.integration.publishing.service.gov.uk/github-webhook/",
content_type: "json",
},
{
events: ["push"],
active: true,
}
)
end
end
end
def required_status_checks
return nil unless jenkinsfile_exists? || !github_actions_test_job_name.nil?
enforce_jenkins_checks = jenkinsfile_exists? && !overrides.dig("required_status_checks", "ignore_jenkins")
{
strict: overrides.fetch("up_to_date_branches", false),
contexts: [
enforce_jenkins_checks ? "continuous-integration/jenkins/branch" : nil,
github_actions_test_job_name,
*overrides
.fetch("required_status_checks", {})
.fetch("additional_contexts", [])
].compact
}
end
def jenkinsfile
@jenkinsfile ||= begin
client.contents(repo[:full_name], path: "Jenkinsfile")
rescue Octokit::NotFound
nil
end
end
def jenkinsfile_exists?
!jenkinsfile.nil?
end
def jenkinsfile_content
return nil unless jenkinsfile_exists?
raise "Unknown encoding" unless jenkinsfile.encoding == "base64"
Base64.decode64(jenkinsfile.content)
end
def github_actions
@github_actions ||= begin
encoded_content = client.contents(repo[:full_name], path: ".github/workflows/ci.yml").content
decoded_content = Base64.decode64(encoded_content)
YAML.load(decoded_content)
rescue Octokit::NotFound
nil
end
end
def github_actions_test_job_name
test_job = github_actions&.dig("jobs", "test")
unless test_job.nil?
test_job.fetch("name", "test")
end
end
def enable_vulnerability_alerts
client.enable_vulnerability_alerts(repo[:full_name])
end
def enable_automated_security_fixes
client.put("https://api.github.com/repos/#{repo[:full_name]}/automated-security-fixes", accept: "application/vnd.github+json")
end
end