github-pages-health-check 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -4
- data/github-pages-health-check.gemspec +2 -2
- data/lib/github-pages-health-check.rb +5 -5
- data/lib/github-pages-health-check/caa.rb +50 -0
- data/lib/github-pages-health-check/cdn.rb +1 -1
- data/lib/github-pages-health-check/checkable.rb +1 -1
- data/lib/github-pages-health-check/domain.rb +30 -13
- data/lib/github-pages-health-check/error.rb +3 -3
- data/lib/github-pages-health-check/errors.rb +1 -1
- data/lib/github-pages-health-check/errors/build_error.rb +1 -1
- data/lib/github-pages-health-check/errors/deprecated_ip_error.rb +1 -1
- data/lib/github-pages-health-check/errors/invalid_a_record_error.rb +1 -1
- data/lib/github-pages-health-check/errors/invalid_cname_error.rb +1 -1
- data/lib/github-pages-health-check/errors/invalid_dns_error.rb +1 -1
- data/lib/github-pages-health-check/errors/invalid_domain_error.rb +1 -1
- data/lib/github-pages-health-check/errors/not_served_by_pages_error.rb +1 -1
- data/lib/github-pages-health-check/printer.rb +1 -1
- data/lib/github-pages-health-check/repository.rb +3 -3
- data/lib/github-pages-health-check/site.rb +1 -1
- data/lib/github-pages-health-check/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5c72a3c5e782d9a27d272b02043fa00e0e103a2
|
4
|
+
data.tar.gz: 635f03b9715d8c2865c8ccea3f7b530d69d47597
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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("
|
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("
|
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 "
|
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"
|
38
|
-
URL = "https://github.com/github/pages-health-check"
|
39
|
-
USER_AGENT = "Mozilla/5.0 (compatible; #{HUMAN_NAME}/#{VERSION}; +#{URL})"
|
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
|
@@ -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.
|
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
|
-
|
230
|
-
|
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 ||=
|
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.
|
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.
|
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.
|
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.
|
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.
|
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?(
|
399
|
-
LEGACY_IP_ADDRESSES.include?(
|
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"
|
7
|
-
DOCUMENTATION_PATH = "/categories/github-pages-basics/"
|
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
|
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
|
@@ -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/"
|
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/"
|
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/"
|
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/"
|
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/"
|
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/"
|
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/"
|
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"
|
@@ -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
|
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
|
48
|
+
last_build&.duration
|
49
49
|
end
|
50
50
|
|
51
51
|
def last_built
|
52
|
-
last_build
|
52
|
+
last_build&.updated_at
|
53
53
|
end
|
54
54
|
|
55
55
|
def domain
|
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
|
+
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-
|
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:
|
28
|
+
name: dnsruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
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: '
|
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
|