github-pages-health-check 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0dbdf2a06e0dd18317636a5ba612d2a9981265b7
4
- data.tar.gz: 1bab87a2e891996ec1bd64bfe5ba1160c3e5fb01
3
+ metadata.gz: a5c72a3c5e782d9a27d272b02043fa00e0e103a2
4
+ data.tar.gz: 635f03b9715d8c2865c8ccea3f7b530d69d47597
5
5
  SHA512:
6
- metadata.gz: c0d9742f1de9b2b73fa4c46bacbfa3f684e68b1a9695da15e91541d0a6a3fc5359676b83ea69f06fb5e63836d3a94bb3ff736e74d2269083057413555f684da0
7
- data.tar.gz: a21cc8495ef9e39e7f7e8991c9e4a831df5f86b6dcfbbe8ca6af67d9a5f67e94e192b0c7f8da36308796d365c46af0f9bf0610a5f08a2e88f2899b41cfb6d5f3
6
+ metadata.gz: a07681c650945cbc8a924967d1fc53d57d8cb72c5a80d1cbd90dd9b25fe060e04fef795797c51104f06217ccfcfa65784a352607d8e3c90f9c04486566004cca
7
+ data.tar.gz: 002eb4f6d72eea2fd1db10d12083690ef8a4ce8f5587f5a049bee52fec6af7bb057b0878dc32df1d7e629f8b661846e724239a5c1e24182e084dd14ac462788b
data/.rubocop.yml CHANGED
@@ -17,13 +17,14 @@
17
17
  #
18
18
 
19
19
  AllCops:
20
+ TargetRubyVersion: 2.4
20
21
  Exclude:
21
22
  - 'bin/**/*'
22
23
  - 'script/**/*'
23
24
  - 'vendor/**/*'
24
25
  - 'test-site/**/*'
25
26
 
26
- Lint/EndAlignment:
27
+ Layout/EndAlignment:
27
28
  Severity: error
28
29
 
29
30
  Lint/UnreachableCode:
@@ -119,9 +120,6 @@ Style/PercentLiteralDelimiters:
119
120
  '%W': '()'
120
121
  '%x': '()'
121
122
 
122
- AllCops:
123
- TargetRubyVersion: 2.2
124
-
125
123
  Style/Documentation:
126
124
  Enabled: false
127
125
 
@@ -149,3 +147,10 @@ Style/DoubleNegation:
149
147
  Layout/EmptyLineAfterMagicComment:
150
148
  Exclude:
151
149
  - script/*
150
+
151
+ Style/FrozenStringLiteralComment:
152
+ Enabled: true
153
+ Severity: error
154
+
155
+ Gemspec/RequiredRubyVersion:
156
+ Enabled: false
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path("../lib/github-pages-health-check/version", __FILE__)
3
+ require File.expand_path("lib/github-pages-health-check/version", __dir__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.required_ruby_version = ">= 2.2.0"
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.require_paths = ["lib"]
18
18
 
19
19
  s.add_dependency("addressable", "~> 2.3")
20
- s.add_dependency("net-dns", "~> 0.8")
20
+ s.add_dependency("dnsruby", "~> 1.60")
21
21
  s.add_dependency("octokit", "~> 4.0")
22
22
  s.add_dependency("public_suffix", "~> 2.0")
23
23
  s.add_dependency("typhoeus", "~> 1.3")
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/dns"
4
- require "net/dns/resolver"
3
+ require "dnsruby"
5
4
  require "addressable/uri"
6
5
  require "ipaddr"
7
6
  require "public_suffix"
@@ -25,6 +24,7 @@ module GitHubPages
25
24
  autoload :Fastly, "github-pages-health-check/cdns/fastly"
26
25
  autoload :Error, "github-pages-health-check/error"
27
26
  autoload :Errors, "github-pages-health-check/errors"
27
+ autoload :CAA, "github-pages-health-check/caa"
28
28
  autoload :Checkable, "github-pages-health-check/checkable"
29
29
  autoload :Domain, "github-pages-health-check/domain"
30
30
  autoload :Repository, "github-pages-health-check/repository"
@@ -34,9 +34,9 @@ module GitHubPages
34
34
  # DNS and HTTP timeout, in seconds
35
35
  TIMEOUT = 5
36
36
 
37
- HUMAN_NAME = "GitHub Pages Health Check".freeze
38
- URL = "https://github.com/github/pages-health-check".freeze
39
- USER_AGENT = "Mozilla/5.0 (compatible; #{HUMAN_NAME}/#{VERSION}; +#{URL})".freeze
37
+ HUMAN_NAME = "GitHub Pages Health Check"
38
+ URL = "https://github.com/github/pages-health-check"
39
+ USER_AGENT = "Mozilla/5.0 (compatible; #{HUMAN_NAME}/#{VERSION}; +#{URL})"
40
40
 
41
41
  TYPHOEUS_OPTIONS = {
42
42
  :followlocation => true,
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dnsruby"
4
+ require "public_suffix"
5
+
6
+ module GitHubPages
7
+ module HealthCheck
8
+ class CAA
9
+ attr_reader :host
10
+ attr_reader :error
11
+
12
+ def initialize(host)
13
+ @host = host
14
+ end
15
+
16
+ def errored?
17
+ records # load the records first
18
+ !error.nil?
19
+ end
20
+
21
+ def lets_encrypt_allowed?
22
+ return false if errored?
23
+ return true unless records_present?
24
+ records.any? { |r| r.property_value == "letsencrypt.org" }
25
+ end
26
+
27
+ def records_present?
28
+ return false if errored?
29
+ records && !records.empty?
30
+ end
31
+
32
+ def records
33
+ @records ||= (get_caa_records(host) | get_caa_records(PublicSuffix.domain(host)))
34
+ end
35
+
36
+ def get_caa_records(domain)
37
+ resolver = Dnsruby::Resolver.new
38
+ resolver.retry_times = 2
39
+ resolver.query_timeout = 2
40
+ nspack = begin
41
+ resolver.query(domain, "CAA", "IN")
42
+ rescue StandardError => e
43
+ @error = e
44
+ return []
45
+ end
46
+ nspack.answer.select { |r| r.type == "CAA" && r.property_tag == "issue" }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -21,7 +21,7 @@ module GitHubPages
21
21
 
22
22
  # Internal: Does this CDN control this address?
23
23
  def controls_ip?(address)
24
- ranges.any? { |range| range.include?(address) }
24
+ ranges.any? { |range| range.include?(address.to_s) }
25
25
  end
26
26
 
27
27
  private
@@ -28,7 +28,7 @@ module GitHubPages
28
28
  end
29
29
 
30
30
  def to_hash
31
- @hash ||= begin
31
+ @to_hash ||= begin
32
32
  hash = {}
33
33
  self.class::HASH_METHODS.each do |method|
34
34
  hash[method] = public_send(method)
@@ -78,6 +78,7 @@ module GitHubPages
78
78
  cname_to_github_user_domain? cname_to_pages_dot_github_dot_com?
79
79
  cname_to_fastly? pointed_to_github_pages_ip? pages_domain?
80
80
  served_by_pages? valid_domain? https? enforces_https? https_error
81
+ https_eligible? caa_error
81
82
  ].freeze
82
83
 
83
84
  def initialize(host)
@@ -151,7 +152,7 @@ module GitHubPages
151
152
 
152
153
  # Is the domain's first response an A record to a valid GitHub Pages IP?
153
154
  def pointed_to_github_pages_ip?
154
- a_record? && CURRENT_IP_ADDRESSES.include?(dns.first.value)
155
+ a_record? && CURRENT_IP_ADDRESSES.include?(dns.first.address.to_s)
155
156
  end
156
157
 
157
158
  # Is the domain's first response a CNAME to a pages domain?
@@ -226,10 +227,8 @@ module GitHubPages
226
227
  return unless valid_domain?
227
228
  @dns = Timeout.timeout(TIMEOUT) do
228
229
  GitHubPages::HealthCheck.without_warnings do
229
- unless host.nil?
230
- resolver.search(absolute_domain, Net::DNS::A).answer +
231
- resolver.search(absolute_domain, Net::DNS::MX).answer
232
- end
230
+ next if host.nil?
231
+ resolver.query(absolute_domain, Dnsruby::Types::ANY).answer
233
232
  end
234
233
  end
235
234
  rescue StandardError
@@ -237,7 +236,10 @@ module GitHubPages
237
236
  end
238
237
 
239
238
  def resolver
240
- @resolver ||= Net::DNS::Resolver.new
239
+ @resolver ||= Dnsruby::Resolver.new
240
+ @resolver.retry_times = 2
241
+ @resolver.query_timeout = 2
242
+ @resolver
241
243
  end
242
244
 
243
245
  # Are we even able to get the DNS record?
@@ -251,14 +253,14 @@ module GitHubPages
251
253
  return unless dns?
252
254
 
253
255
  dns.any? do |answer|
254
- answer.is_a?(Net::DNS::RR::A) && legacy_ip?(answer.address.to_s)
256
+ answer.type == Dnsruby::Types::A && legacy_ip?(answer.address.to_s)
255
257
  end
256
258
  end
257
259
 
258
260
  # Is this domain's first response an A record?
259
261
  def a_record?
260
262
  return unless dns?
261
- dns.first.class == Net::DNS::RR::A
263
+ dns.first.type == Dnsruby::Types::A
262
264
  end
263
265
 
264
266
  # Is this domain's first response a CNAME record?
@@ -272,13 +274,13 @@ module GitHubPages
272
274
  # The domain to which this domain's CNAME resolves
273
275
  # Returns nil if the domain is not a CNAME
274
276
  def cname
275
- return unless dns.first.class == Net::DNS::RR::CNAME
277
+ return unless dns.first.type == Dnsruby::Types::CNAME
276
278
  @cname ||= Domain.new(dns.first.cname.to_s)
277
279
  end
278
280
 
279
281
  def mx_records_present?
280
282
  return unless dns?
281
- dns.any? { |answer| answer.class == Net::DNS::RR::MX }
283
+ dns.any? { |answer| answer.type == Dnsruby::Types::MX }
282
284
  end
283
285
 
284
286
  def served_by_pages?
@@ -318,8 +320,23 @@ module GitHubPages
318
320
  redirect.scheme == "https" && redirect.host == host
319
321
  end
320
322
 
323
+ # Can an HTTPS certificate be issued for this domain?
324
+ def https_eligible?
325
+ (cname_to_github_user_domain? || fastly_ip?) && caa.lets_encrypt_allowed?
326
+ end
327
+
328
+ # Any errors querying CAA records
329
+ def caa_error
330
+ return nil if caa.error.nil?
331
+ caa.error.class.name
332
+ end
333
+
321
334
  private
322
335
 
336
+ def caa
337
+ @caa ||= GitHubPages::HealthCheck::CAA.new(absolute_domain)
338
+ end
339
+
323
340
  # The domain's response to HTTP(S) requests, following redirects
324
341
  def response
325
342
  return @response if defined? @response
@@ -387,7 +404,7 @@ module GitHubPages
387
404
  def cdn_ip?(cdn)
388
405
  return unless dns?
389
406
 
390
- a_records = dns.select { |answer| answer.class == Net::DNS::RR::A }
407
+ a_records = dns.select { |answer| answer.type == Dnsruby::Types::A }
391
408
  return false if !a_records || a_records.empty?
392
409
 
393
410
  a_records.all? do |answer|
@@ -395,8 +412,8 @@ module GitHubPages
395
412
  end
396
413
  end
397
414
 
398
- def legacy_ip?(ip)
399
- LEGACY_IP_ADDRESSES.include?(ip)
415
+ def legacy_ip?(ip_addr)
416
+ LEGACY_IP_ADDRESSES.include?(ip_addr)
400
417
  end
401
418
  end
402
419
  end
@@ -3,8 +3,8 @@
3
3
  module GitHubPages
4
4
  module HealthCheck
5
5
  class Error < StandardError
6
- DOCUMENTATION_BASE = "https://help.github.com".freeze
7
- DOCUMENTATION_PATH = "/categories/github-pages-basics/".freeze
6
+ DOCUMENTATION_BASE = "https://help.github.com"
7
+ DOCUMENTATION_PATH = "/categories/github-pages-basics/"
8
8
  LOCAL_ONLY = false # Error is only used when running locally
9
9
 
10
10
  attr_reader :repository, :domain
@@ -30,7 +30,7 @@ module GitHubPages
30
30
  # Error message, with get more info URL appended
31
31
  def message_with_url
32
32
  msg = message.gsub(/\s+/, " ").squeeze(" ").strip
33
- msg << "." unless msg =~ /\.$/ # add trailing period if not there
33
+ msg << "." unless msg.match?(/\.$/) # add trailing period if not there
34
34
  "#{msg} #{more_info}"
35
35
  end
36
36
  alias message_formatted message_with_url
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Dir[File.expand_path("../errors/*_error.rb", __FILE__)].each do |f|
3
+ Dir[File.expand_path("errors/*_error.rb", __dir__)].each do |f|
4
4
  require f
5
5
  end
6
6
 
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class BuildError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/troubleshooting-jekyll-builds/".freeze
7
+ DOCUMENTATION_PATH = "/articles/troubleshooting-jekyll-builds/"
8
8
  LOCAL_ONLY = true
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class DeprecatedIPError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  <<-MSG
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class InvalidARecordError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  <<-MSG
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class InvalidCNAMEError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  <<-MSG
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class InvalidDNSError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  "Domain's DNS record could not be retrieved"
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class InvalidDomainError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  "Domain is not a valid domain"
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  module Errors
6
6
  class NotServedByPagesError < GitHubPages::HealthCheck::Error
7
- DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
7
+ DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/"
8
8
 
9
9
  def message
10
10
  "Domain does not resolve to the GitHub Pages server"
@@ -4,7 +4,7 @@ module GitHubPages
4
4
  module HealthCheck
5
5
  class Printer
6
6
  PRETTY_LEFT_WIDTH = 11
7
- PRETTY_JOINER = " | ".freeze
7
+ PRETTY_JOINER = " | "
8
8
 
9
9
  attr_reader :health_check
10
10
 
@@ -12,7 +12,7 @@ module GitHubPages
12
12
  ].freeze
13
13
 
14
14
  def initialize(name_with_owner, access_token: nil)
15
- unless name_with_owner =~ REPO_REGEX
15
+ unless name_with_owner.match?(REPO_REGEX)
16
16
  raise Errors::InvalidRepositoryError
17
17
  end
18
18
  parts = name_with_owner.split("/")
@@ -45,11 +45,11 @@ module GitHubPages
45
45
  alias reason build_error
46
46
 
47
47
  def build_duration
48
- last_build.duration if last_build
48
+ last_build&.duration
49
49
  end
50
50
 
51
51
  def last_built
52
- last_build.updated_at if last_build
52
+ last_build&.updated_at
53
53
  end
54
54
 
55
55
  def domain
@@ -14,7 +14,7 @@ module GitHubPages
14
14
  end
15
15
 
16
16
  def check!
17
- [domain, repository].each { |check| check.check! if check }
17
+ [domain, repository].each { |check| check&.check! }
18
18
  true
19
19
  end
20
20
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitHubPages
4
4
  module HealthCheck
5
- VERSION = "1.4.0".freeze
5
+ VERSION = "1.5.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github-pages-health-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-16 00:00:00.000000000 Z
11
+ date: 2018-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: net-dns
28
+ name: dnsruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.8'
33
+ version: '1.60'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.8'
40
+ version: '1.60'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: octokit
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -182,6 +182,7 @@ files:
182
182
  - config/fastly-ips.txt
183
183
  - github-pages-health-check.gemspec
184
184
  - lib/github-pages-health-check.rb
185
+ - lib/github-pages-health-check/caa.rb
185
186
  - lib/github-pages-health-check/cdn.rb
186
187
  - lib/github-pages-health-check/cdns/cloudflare.rb
187
188
  - lib/github-pages-health-check/cdns/fastly.rb