github-pages-health-check 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/.rubocop.yml +157 -0
- data/.travis.yml +2 -1
- data/Gemfile +1 -0
- data/github-pages-health-check.gemspec +3 -1
- data/lib/github-pages-health-check.rb +16 -11
- data/lib/github-pages-health-check/cdn.rb +1 -0
- data/lib/github-pages-health-check/cdns/cloudflare.rb +1 -0
- data/lib/github-pages-health-check/cdns/fastly.rb +1 -0
- data/lib/github-pages-health-check/checkable.rb +7 -7
- data/lib/github-pages-health-check/domain.rb +58 -33
- data/lib/github-pages-health-check/error.rb +10 -5
- data/lib/github-pages-health-check/errors.rb +1 -0
- data/lib/github-pages-health-check/errors/build_error.rb +2 -1
- data/lib/github-pages-health-check/errors/deprecated_ip_error.rb +1 -0
- 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 -0
- data/lib/github-pages-health-check/errors/invalid_repository_error.rb +1 -0
- data/lib/github-pages-health-check/errors/missing_access_token_error.rb +1 -0
- data/lib/github-pages-health-check/errors/not_served_by_pages_error.rb +1 -0
- data/lib/github-pages-health-check/printer.rb +35 -17
- data/lib/github-pages-health-check/repository.rb +9 -9
- data/lib/github-pages-health-check/site.rb +5 -5
- data/lib/github-pages-health-check/version.rb +2 -1
- data/script/check +1 -0
- data/script/test +4 -0
- data/script/update-cdn-ips +8 -7
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a5737c814130d1f5c193ea84af00ef871a4e8cd
|
4
|
+
data.tar.gz: a5e432b41f1e73b6607c5369d01c81736489e1cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04b31d07e1b0bd066a5957194e441ae37fb7964f205b8dd1eb53836276d25657825e8585fb25887b3bceba33179f997c72a3631915bd21ca4cbf6bd3bbb4b3c0
|
7
|
+
data.tar.gz: 2724939af6326eeeb9ae71a8ade4071e584912fb1c535e1f27e462328fb7e95176221fc85f996365cdb3532d9f3f74054cca38ada06dd5536ce54d36cad46174
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--
|
2
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# Ruby linting configuration.
|
2
|
+
# See https://github.com/styleguide/ruby for the Ruby style guide
|
3
|
+
|
4
|
+
# We only worry about two kinds of issues: 'error' and anything less than that.
|
5
|
+
# Error is not about severity, but about taste. Simple style choices that
|
6
|
+
# never have a great excuse to be broken, such as 1.9 JSON-like hash syntax,
|
7
|
+
# are errors. Choices that tend to have good exceptions in practice, such as
|
8
|
+
# line length, are warnings.
|
9
|
+
|
10
|
+
# If you'd like to make changes, a full list of available issues is at
|
11
|
+
# https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
|
12
|
+
#
|
13
|
+
# A list of configurable issues is at:
|
14
|
+
# https://github.com/bbatsov/rubocop/blob/master/config/default.yml
|
15
|
+
#
|
16
|
+
# If you disable a check, document why.
|
17
|
+
|
18
|
+
AllCops:
|
19
|
+
Exclude:
|
20
|
+
- 'bin/**/*'
|
21
|
+
- 'script/**/*'
|
22
|
+
- 'vendor/**/*'
|
23
|
+
- 'test-site/**/*'
|
24
|
+
|
25
|
+
Lint/EndAlignment:
|
26
|
+
Severity: error
|
27
|
+
|
28
|
+
Lint/RescueException:
|
29
|
+
Exclude:
|
30
|
+
- lib/pages_jekyll.rb
|
31
|
+
|
32
|
+
Lint/UnreachableCode:
|
33
|
+
Severity: error
|
34
|
+
|
35
|
+
Lint/AmbiguousRegexpLiteral:
|
36
|
+
Exclude:
|
37
|
+
- 'features/step_definitions/pages_steps.rb'
|
38
|
+
|
39
|
+
Style/StringLiterals:
|
40
|
+
EnforcedStyle: double_quotes
|
41
|
+
Severity: error
|
42
|
+
|
43
|
+
Style/StringLiteralsInInterpolation:
|
44
|
+
EnforcedStyle: double_quotes
|
45
|
+
|
46
|
+
Style/HashSyntax:
|
47
|
+
EnforcedStyle: hash_rockets
|
48
|
+
Severity: error
|
49
|
+
|
50
|
+
Style/AlignHash:
|
51
|
+
SupportedLastArgumentHashStyles: always_ignore
|
52
|
+
|
53
|
+
Style/AlignParameters:
|
54
|
+
Enabled: false # This is usually true, but we often want to roll back to
|
55
|
+
# the start of a line.
|
56
|
+
|
57
|
+
Style/Attr:
|
58
|
+
Enabled: false # We have no styleguide guidance here, and it seems to be
|
59
|
+
# in frequent use.
|
60
|
+
|
61
|
+
Style/ClassAndModuleChildren:
|
62
|
+
Enabled: false # module X<\n>module Y is just as good as module X::Y.
|
63
|
+
|
64
|
+
Style/PercentLiteralDelimiters:
|
65
|
+
PreferredDelimiters:
|
66
|
+
'%w': '{}'
|
67
|
+
'%r': '{}'
|
68
|
+
|
69
|
+
Metrics/LineLength:
|
70
|
+
Max: 90
|
71
|
+
Severity: warning
|
72
|
+
Exclude:
|
73
|
+
- github-pages-health-check.gemspec
|
74
|
+
- lib/github-pages-health-check/errors/*.rb
|
75
|
+
|
76
|
+
Metrics/BlockLength:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Style/MultilineTernaryOperator:
|
80
|
+
Severity: error
|
81
|
+
|
82
|
+
Style/AndOr:
|
83
|
+
Severity: error
|
84
|
+
|
85
|
+
Style/IndentationWidth:
|
86
|
+
Severity: error
|
87
|
+
|
88
|
+
Metrics/MethodLength:
|
89
|
+
CountComments: false # count full line comments?
|
90
|
+
Max: 20
|
91
|
+
Severity: error
|
92
|
+
Exclude:
|
93
|
+
- lib/github-pages-health-check/printer.rb
|
94
|
+
|
95
|
+
Style/Alias:
|
96
|
+
Enabled: false # We have no guidance on alias vs alias_method
|
97
|
+
|
98
|
+
Style/RedundantSelf:
|
99
|
+
Enabled: false # Sometimes a self.field is a bit more clear
|
100
|
+
|
101
|
+
Style/IfUnlessModifier:
|
102
|
+
Enabled: false
|
103
|
+
|
104
|
+
Style/FileName: #Rubocop doesn't like the Git*H*ub namespace
|
105
|
+
Enabled: false
|
106
|
+
|
107
|
+
Metrics/ParameterLists: { Max: 4 }
|
108
|
+
Metrics/AbcSize: { Max: 20 }
|
109
|
+
|
110
|
+
Style/IndentHash: { EnforcedStyle: consistent }
|
111
|
+
Style/SignalException: { EnforcedStyle: only_raise }
|
112
|
+
Style/MultilineMethodCallIndentation: { EnforcedStyle: indented }
|
113
|
+
Style/MultilineOperationIndentation: { EnforcedStyle: indented }
|
114
|
+
Style/FirstParameterIndentation: { EnforcedStyle: consistent }
|
115
|
+
Style/StringLiterals: { EnforcedStyle: double_quotes }
|
116
|
+
Style/IndentArray: { EnforcedStyle: consistent }
|
117
|
+
Style/ExtraSpacing: { AllowForAlignment: true }
|
118
|
+
|
119
|
+
Style/PercentLiteralDelimiters:
|
120
|
+
PreferredDelimiters:
|
121
|
+
'%q': '{}'
|
122
|
+
'%Q': '{}'
|
123
|
+
'%r': '{}'
|
124
|
+
'%s': '()'
|
125
|
+
'%w': '()'
|
126
|
+
'%W': '()'
|
127
|
+
'%x': '()'
|
128
|
+
|
129
|
+
AllCops:
|
130
|
+
TargetRubyVersion: 2.2
|
131
|
+
|
132
|
+
Style/Documentation:
|
133
|
+
Enabled: false
|
134
|
+
|
135
|
+
Metrics/ClassLength:
|
136
|
+
Exclude:
|
137
|
+
- lib/github-pages-health-check/domain.rb
|
138
|
+
|
139
|
+
Metrics/CyclomaticComplexity:
|
140
|
+
Max: 8
|
141
|
+
Exclude:
|
142
|
+
- lib/github-pages-health-check/printer.rb
|
143
|
+
|
144
|
+
Metrics/PerceivedComplexity:
|
145
|
+
Max: 8
|
146
|
+
Exclude:
|
147
|
+
- lib/github-pages-health-check/printer.rb
|
148
|
+
|
149
|
+
Metrics/AbcSize:
|
150
|
+
Exclude:
|
151
|
+
- lib/github-pages-health-check/printer.rb
|
152
|
+
|
153
|
+
Style/DoubleNegation:
|
154
|
+
Enabled: false
|
155
|
+
|
156
|
+
Style/FileName:
|
157
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require File.expand_path("../lib/github-pages-health-check/version", __FILE__)
|
2
3
|
|
3
4
|
Gem::Specification.new do |s|
|
@@ -12,7 +13,7 @@ Gem::Specification.new do |s|
|
|
12
13
|
s.homepage = "https://github.com/github/github-pages-health-check"
|
13
14
|
s.license = "MIT"
|
14
15
|
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
15
|
-
s.require_paths = [
|
16
|
+
s.require_paths = ["lib"]
|
16
17
|
|
17
18
|
s.add_dependency("net-dns", "~> 0.8")
|
18
19
|
s.add_dependency("public_suffix", "~> 2.0")
|
@@ -25,4 +26,5 @@ Gem::Specification.new do |s|
|
|
25
26
|
s.add_development_dependency("gem-release", "~> 0.7")
|
26
27
|
s.add_development_dependency("webmock", "~> 1.21")
|
27
28
|
s.add_development_dependency("dotenv", "~> 1.0")
|
29
|
+
s.add_development_dependency("rubocop", "~> 0.40")
|
28
30
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "net/dns"
|
2
3
|
require "net/dns/resolver"
|
3
4
|
require "addressable/uri"
|
@@ -11,14 +12,13 @@ require "timeout"
|
|
11
12
|
require "octokit"
|
12
13
|
require_relative "github-pages-health-check/version"
|
13
14
|
|
14
|
-
if File.
|
15
|
-
require
|
15
|
+
if File.exist?(File.expand_path("../.env", File.dirname(__FILE__)))
|
16
|
+
require "dotenv"
|
16
17
|
Dotenv.load
|
17
18
|
end
|
18
19
|
|
19
20
|
module GitHubPages
|
20
21
|
module HealthCheck
|
21
|
-
|
22
22
|
autoload :CDN, "github-pages-health-check/cdn"
|
23
23
|
autoload :CloudFlare, "github-pages-health-check/cdns/cloudflare"
|
24
24
|
autoload :Fastly, "github-pages-health-check/cdns/fastly"
|
@@ -33,26 +33,31 @@ module GitHubPages
|
|
33
33
|
# DNS and HTTP timeout, in seconds
|
34
34
|
TIMEOUT = 5
|
35
35
|
|
36
|
+
HUMAN_NAME = "GitHub Pages Health Check".freeze
|
37
|
+
URL = "https://github.com/github/pages-health-check".freeze
|
38
|
+
USER_AGENT = "Mozilla/5.0 (compatible; #{HUMAN_NAME}/#{VERSION}; +#{URL})".freeze
|
39
|
+
|
36
40
|
TYPHOEUS_OPTIONS = {
|
37
|
-
:followlocation
|
38
|
-
:timeout
|
41
|
+
:followlocation => true,
|
42
|
+
:timeout => TIMEOUT,
|
39
43
|
:accept_encoding => "gzip",
|
40
|
-
:method
|
41
|
-
:headers
|
42
|
-
"User-Agent"
|
44
|
+
:method => :head,
|
45
|
+
:headers => {
|
46
|
+
"User-Agent" => USER_AGENT
|
43
47
|
}
|
44
|
-
}
|
48
|
+
}.freeze
|
45
49
|
|
46
50
|
# surpress warn-level feedback due to unsupported record types
|
47
51
|
def self.without_warnings(&block)
|
48
|
-
warn_level
|
52
|
+
warn_level = $VERBOSE
|
53
|
+
$VERBOSE = nil
|
49
54
|
result = block.call
|
50
55
|
$VERBOSE = warn_level
|
51
56
|
result
|
52
57
|
end
|
53
58
|
|
54
59
|
def self.check(repository_or_domain, access_token: nil)
|
55
|
-
Site.new repository_or_domain, access_token
|
60
|
+
Site.new repository_or_domain, :access_token => access_token
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Checkable
|
4
|
-
|
5
5
|
# Array of symbolized methods to be included in the output hash
|
6
|
-
HASH_METHODS = []
|
6
|
+
HASH_METHODS = [].freeze
|
7
7
|
|
8
8
|
def check!
|
9
9
|
raise "Not implemented"
|
10
10
|
end
|
11
|
-
|
11
|
+
alias valid! check!
|
12
12
|
|
13
13
|
# Runs all checks, returns true if valid, otherwise false
|
14
14
|
def valid?
|
@@ -35,11 +35,11 @@ module GitHubPages
|
|
35
35
|
hash
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
39
|
-
|
38
|
+
alias [] to_hash
|
39
|
+
alias to_h to_hash
|
40
40
|
|
41
41
|
def to_json
|
42
|
-
require
|
42
|
+
require "json"
|
43
43
|
to_hash.to_json
|
44
44
|
end
|
45
45
|
|
@@ -50,7 +50,7 @@ module GitHubPages
|
|
50
50
|
def to_s_pretty
|
51
51
|
printer.pretty_print
|
52
52
|
end
|
53
|
-
|
53
|
+
alias pretty_print to_s_pretty
|
54
54
|
|
55
55
|
private
|
56
56
|
|
@@ -1,7 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Domain < Checkable
|
4
|
-
|
5
5
|
attr_reader :host
|
6
6
|
|
7
7
|
LEGACY_IP_ADDRESSES = [
|
@@ -9,15 +9,29 @@ module GitHubPages
|
|
9
9
|
"207.97.227.245",
|
10
10
|
"204.232.175.78",
|
11
11
|
|
12
|
-
#
|
12
|
+
# Aug. 2016 Fastly datacenter deprecation
|
13
13
|
"199.27.73.133",
|
14
|
-
"199.27.76.133"
|
14
|
+
"199.27.76.133",
|
15
|
+
|
16
|
+
# Feb. 2017 Fastly datacenter deprecation
|
17
|
+
"185.31.17.133",
|
18
|
+
"185.31.18.133",
|
19
|
+
"185.31.19.133",
|
20
|
+
"199.27.74.133",
|
21
|
+
"199.27.75.133",
|
22
|
+
"199.27.79.133",
|
23
|
+
"23.235.39.133",
|
24
|
+
"23.235.43.133",
|
25
|
+
"23.235.44.133",
|
26
|
+
"23.235.46.133",
|
27
|
+
"23.235.47.133",
|
28
|
+
"45.32.88.68"
|
15
29
|
].freeze
|
16
30
|
|
17
|
-
CURRENT_IP_ADDRESSES = %w
|
31
|
+
CURRENT_IP_ADDRESSES = %w(
|
18
32
|
192.30.252.153
|
19
33
|
192.30.252.154
|
20
|
-
|
34
|
+
).freeze
|
21
35
|
|
22
36
|
HASH_METHODS = [
|
23
37
|
:host, :uri, :dns_resolves?, :proxied?, :cloudflare_ip?, :fastly_ip?,
|
@@ -38,13 +52,13 @@ module GitHubPages
|
|
38
52
|
|
39
53
|
# Runs all checks, raises an error if invalid
|
40
54
|
def check!
|
41
|
-
raise Errors::InvalidDomainError
|
42
|
-
raise Errors::InvalidDNSError
|
43
|
-
raise Errors::DeprecatedIPError
|
55
|
+
raise Errors::InvalidDomainError, :domain => self unless valid_domain?
|
56
|
+
raise Errors::InvalidDNSError, :domain => self unless dns_resolves?
|
57
|
+
raise Errors::DeprecatedIPError, :domain => self if deprecated_ip?
|
44
58
|
return true if proxied?
|
45
|
-
raise Errors::InvalidARecordError
|
46
|
-
raise Errors::InvalidCNAMEError
|
47
|
-
raise Errors::NotServedByPagesError
|
59
|
+
raise Errors::InvalidARecordError, :domain => self if invalid_a_record?
|
60
|
+
raise Errors::InvalidCNAMEError, :domain => self if invalid_cname?
|
61
|
+
raise Errors::NotServedByPagesError, :domain => self unless served_by_pages?
|
48
62
|
true
|
49
63
|
end
|
50
64
|
|
@@ -72,7 +86,7 @@ module GitHubPages
|
|
72
86
|
# Used as an escape hatch to prevent false positives on DNS checkes
|
73
87
|
def valid_domain?
|
74
88
|
return @valid if defined? @valid
|
75
|
-
@valid = PublicSuffix.valid?(host, default_rule
|
89
|
+
@valid = PublicSuffix.valid?(host, :default_rule => nil)
|
76
90
|
end
|
77
91
|
|
78
92
|
# Is this domain an apex domain, meaning a CNAME would be innapropriate
|
@@ -80,14 +94,14 @@ module GitHubPages
|
|
80
94
|
return @apex_domain if defined?(@apex_domain)
|
81
95
|
return unless valid_domain?
|
82
96
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}
|
88
|
-
rescue Timeout::Error, NoMethodError
|
89
|
-
[]
|
97
|
+
answers = begin
|
98
|
+
Resolv::DNS.open do |dns|
|
99
|
+
dns.timeouts = TIMEOUT
|
100
|
+
dns.getresources(absolute_domain, Resolv::DNS::Resource::IN::NS)
|
90
101
|
end
|
102
|
+
rescue Timeout::Error, NoMethodError
|
103
|
+
[]
|
104
|
+
end
|
91
105
|
|
92
106
|
@apex_domain = answers.any?
|
93
107
|
end
|
@@ -136,7 +150,7 @@ module GitHubPages
|
|
136
150
|
|
137
151
|
# Is this domain owned by GitHub?
|
138
152
|
def github_domain?
|
139
|
-
!!host.
|
153
|
+
!!host.downcase.end_with?("github.com")
|
140
154
|
end
|
141
155
|
|
142
156
|
# Is the host our Fastly CNAME?
|
@@ -158,13 +172,17 @@ module GitHubPages
|
|
158
172
|
#
|
159
173
|
# This can be:
|
160
174
|
# 1. A Cloudflare-owned IP address
|
161
|
-
# 2. A site that returns GitHub.com server headers, but
|
162
|
-
#
|
175
|
+
# 2. A site that returns GitHub.com server headers, but
|
176
|
+
# isn't CNAME'd to a GitHub domain
|
177
|
+
# 3. A site that returns GitHub.com server headers, but
|
178
|
+
# isn't CNAME'd to a GitHub IP
|
163
179
|
def proxied?
|
164
180
|
return unless dns?
|
165
181
|
return true if cloudflare_ip?
|
166
|
-
return false if pointed_to_github_pages_ip?
|
167
|
-
return false if
|
182
|
+
return false if pointed_to_github_pages_ip?
|
183
|
+
return false if cname_to_github_user_domain?
|
184
|
+
return false if cname_to_pages_dot_github_dot_com?
|
185
|
+
return false if cname_to_fastly? || fastly_ip?
|
168
186
|
served_by_pages?
|
169
187
|
end
|
170
188
|
|
@@ -192,13 +210,15 @@ module GitHubPages
|
|
192
210
|
def dns?
|
193
211
|
!(dns.nil? || dns.empty?)
|
194
212
|
end
|
195
|
-
|
213
|
+
alias dns_resolves? dns?
|
196
214
|
|
197
215
|
# Does this domain have *any* A record that points to the legacy IPs?
|
198
216
|
def old_ip_address?
|
217
|
+
return unless dns?
|
218
|
+
|
199
219
|
dns.any? do |answer|
|
200
|
-
answer.
|
201
|
-
end
|
220
|
+
answer.is_a?(Net::DNS::RR::A) && legacy_ip?(answer.address.to_s)
|
221
|
+
end
|
202
222
|
end
|
203
223
|
|
204
224
|
# Is this domain's first response an A record?
|
@@ -236,11 +256,11 @@ module GitHubPages
|
|
236
256
|
return true if response.headers["Server"] == "GitHub.com"
|
237
257
|
|
238
258
|
# Typhoeus mangles the case of the header, compare insensitively
|
239
|
-
response.headers.any? { |k,
|
259
|
+
response.headers.any? { |k, _v| k =~ /X-GitHub-Request-Id/i }
|
240
260
|
end
|
241
261
|
end
|
242
262
|
|
243
|
-
def uri(overrides={})
|
263
|
+
def uri(overrides = {})
|
244
264
|
options = { :host => host, :scheme => scheme, :path => "/" }
|
245
265
|
options = options.merge(overrides)
|
246
266
|
Addressable::URI.new(options).normalize.to_s
|
@@ -283,13 +303,13 @@ module GitHubPages
|
|
283
303
|
|
284
304
|
# The domain's response to HTTP requests, without following redirects
|
285
305
|
def http_response
|
286
|
-
options = TYPHOEUS_OPTIONS.merge(:followlocation => false
|
306
|
+
options = TYPHOEUS_OPTIONS.merge(:followlocation => false)
|
287
307
|
@http_response ||= Typhoeus.head(uri(:scheme => "http"), options)
|
288
308
|
end
|
289
309
|
|
290
310
|
# The domain's response to HTTPS requests, without following redirects
|
291
311
|
def https_response
|
292
|
-
options = TYPHOEUS_OPTIONS.merge(:followlocation => false
|
312
|
+
options = TYPHOEUS_OPTIONS.merge(:followlocation => false)
|
293
313
|
@https_response ||= Typhoeus.head(uri(:scheme => "https"), options)
|
294
314
|
end
|
295
315
|
|
@@ -310,13 +330,14 @@ module GitHubPages
|
|
310
330
|
# Return the hostname.
|
311
331
|
def normalize_host(domain)
|
312
332
|
domain = domain.strip.chomp(".")
|
313
|
-
host = Addressable::URI.parse(domain).host
|
333
|
+
host = Addressable::URI.parse(domain).host
|
334
|
+
host ||= Addressable::URI.parse("http://#{domain}").host
|
314
335
|
host unless host.to_s.empty?
|
315
336
|
rescue Addressable::URI::InvalidURIError
|
316
337
|
nil
|
317
338
|
end
|
318
339
|
|
319
|
-
# Adjust `domain` so that it won't be searched for with /etc/resolv.conf
|
340
|
+
# Adjust `domain` so that it won't be searched for with /etc/resolv.conf
|
320
341
|
#
|
321
342
|
# GitHubPages::HealthCheck.new("anything.io").absolute_domain
|
322
343
|
# => "anything.io."
|
@@ -335,6 +356,10 @@ module GitHubPages
|
|
335
356
|
answer.class == Net::DNS::RR::A && cdn.controls_ip?(answer.address)
|
336
357
|
end
|
337
358
|
end
|
359
|
+
|
360
|
+
def legacy_ip?(ip)
|
361
|
+
LEGACY_IP_ADDRESSES.include?(ip)
|
362
|
+
end
|
338
363
|
end
|
339
364
|
end
|
340
365
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Error < StandardError
|
4
|
-
DOCUMENTATION_BASE = "https://help.github.com"
|
5
|
-
DOCUMENTATION_PATH = "/categories/github-pages-basics/"
|
5
|
+
DOCUMENTATION_BASE = "https://help.github.com".freeze
|
6
|
+
DOCUMENTATION_PATH = "/categories/github-pages-basics/".freeze
|
6
7
|
LOCAL_ONLY = false # Error is only used when running locally
|
7
8
|
|
8
9
|
attr_reader :repository, :domain
|
@@ -28,17 +29,21 @@ module GitHubPages
|
|
28
29
|
# Error message, with get more info URL appended
|
29
30
|
def message_with_url
|
30
31
|
msg = message.gsub(/\s+/, " ").squeeze(" ").strip
|
31
|
-
msg << "." unless msg =~ /\.$/ #add trailing period if not there
|
32
|
+
msg << "." unless msg =~ /\.$/ # add trailing period if not there
|
32
33
|
"#{msg} #{more_info}"
|
33
34
|
end
|
34
|
-
|
35
|
+
alias message_formatted message_with_url
|
35
36
|
|
36
37
|
def to_s
|
37
|
-
"#{message_with_url} (#{
|
38
|
+
"#{message_with_url} (#{name})".tr("\n", " ").squeeze(" ").strip
|
38
39
|
end
|
39
40
|
|
40
41
|
private
|
41
42
|
|
43
|
+
def name
|
44
|
+
self.class.name.split("::").last
|
45
|
+
end
|
46
|
+
|
42
47
|
def username
|
43
48
|
if repository.nil?
|
44
49
|
"[YOUR USERNAME]"
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
module Errors
|
4
5
|
class BuildError < GitHubPages::HealthCheck::Error
|
5
|
-
DOCUMENTATION_PATH =
|
6
|
+
DOCUMENTATION_PATH = "/articles/troubleshooting-jekyll-builds/".freeze
|
6
7
|
LOCAL_ONLY = true
|
7
8
|
end
|
8
9
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
module Errors
|
4
5
|
class InvalidARecordError < GitHubPages::HealthCheck::Error
|
5
|
-
# rubocop:disable Metrics/LineLength
|
6
6
|
DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
|
7
7
|
|
8
8
|
def message
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
module Errors
|
4
5
|
class InvalidCNAMEError < GitHubPages::HealthCheck::Error
|
5
|
-
# rubocop:disable Metrics/LineLength
|
6
6
|
DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
|
7
7
|
|
8
8
|
def message
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
module Errors
|
4
5
|
class InvalidDNSError < GitHubPages::HealthCheck::Error
|
5
|
-
# rubocop:disable Metrics/LineLength
|
6
6
|
DOCUMENTATION_PATH = "/articles/setting-up-a-custom-domain-with-github-pages/".freeze
|
7
7
|
|
8
8
|
def message
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Printer
|
4
5
|
PRETTY_LEFT_WIDTH = 11
|
5
|
-
PRETTY_JOINER = " | "
|
6
|
+
PRETTY_JOINER = " | ".freeze
|
6
7
|
|
7
8
|
attr_reader :health_check
|
8
9
|
|
@@ -11,7 +12,7 @@ module GitHubPages
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def simple_string
|
14
|
-
require
|
15
|
+
require "yaml"
|
15
16
|
hash = health_check.to_hash
|
16
17
|
hash[:reason] = hash[:reason].to_s if hash[:reason]
|
17
18
|
hash.to_yaml.sub(/\A---\n/, "").gsub(/^:/, "")
|
@@ -22,32 +23,49 @@ module GitHubPages
|
|
22
23
|
output = StringIO.new
|
23
24
|
|
24
25
|
# Header
|
25
|
-
output.puts new_line "Domain",
|
26
|
-
output.puts
|
26
|
+
output.puts new_line "Domain", (values[:uri]).to_s
|
27
|
+
output.puts "-" * (PRETTY_LEFT_WIDTH + 1) + "|" + "-" * 50
|
27
28
|
|
28
|
-
output.puts new_line "DNS", "does not resolve"
|
29
|
+
output.puts new_line "DNS", "does not resolve" unless values[:dns_resolves?]
|
29
30
|
|
30
31
|
# Valid?
|
31
|
-
output.write new_line "State",
|
32
|
-
output.puts " - is #{"NOT "
|
32
|
+
output.write new_line "State", (values[:valid?] ? "valid" : "invalid").to_s
|
33
|
+
output.puts " - is #{"NOT " unless values[:served_by_pages?]}served by Pages"
|
33
34
|
|
34
35
|
# What's wrong?
|
35
|
-
output.puts new_line "Reason",
|
36
|
-
|
37
|
-
|
36
|
+
output.puts new_line "Reason", (values[:reason]).to_s unless values[:valid?]
|
37
|
+
|
38
|
+
if values[:pointed_to_github_user_domain?]
|
39
|
+
output.puts new_line nil, "pointed to user domain"
|
40
|
+
end
|
41
|
+
|
42
|
+
if values[:pointed_to_github_pages_ip?]
|
43
|
+
output.puts new_line nil, "pointed to pages IP"
|
44
|
+
end
|
38
45
|
|
39
46
|
# DNS Record info
|
40
|
-
|
41
|
-
|
47
|
+
record_type = if values[:a_record?]
|
48
|
+
"A"
|
49
|
+
elsif values[:cname_record?]
|
50
|
+
"CNAME"
|
51
|
+
else
|
52
|
+
"other"
|
53
|
+
end
|
54
|
+
output.write new_line "Record Type", record_type
|
55
|
+
should_be = values[:should_be_a_record?] ? "A record" : "CNAME"
|
56
|
+
output.puts ", should be #{should_be}"
|
42
57
|
|
43
58
|
ip_problems = []
|
44
|
-
ip_problems << "not apex domain"
|
45
|
-
ip_problems << "invalid domain"
|
59
|
+
ip_problems << "not apex domain" unless values[:apex_domain?]
|
60
|
+
ip_problems << "invalid domain" unless values[:valid_domain?]
|
46
61
|
ip_problems << "old ip address used" if values[:old_ip_address?]
|
47
|
-
|
62
|
+
|
63
|
+
ip_problems_string = !ip_problems.empty? ? ip_problems.join(", ") : "none"
|
64
|
+
output.puts new_line "IP Problems", ip_problems_string
|
48
65
|
|
49
66
|
if values[:proxied?]
|
50
|
-
|
67
|
+
proxy = values[:cloudflare_ip?] ? "CloudFlare" : "unknown"
|
68
|
+
output.puts new_line "Proxied", "yes, through #{proxy}"
|
51
69
|
end
|
52
70
|
|
53
71
|
output.puts new_line "Domain", "*.github.com/io domain" if values[:pages_domain?]
|
@@ -56,7 +74,7 @@ module GitHubPages
|
|
56
74
|
end
|
57
75
|
|
58
76
|
def new_line(left = nil, right = nil)
|
59
|
-
if left
|
77
|
+
if left && right
|
60
78
|
ljust(left) + PRETTY_JOINER + right
|
61
79
|
elsif left
|
62
80
|
ljust(left)
|
@@ -1,13 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Repository < Checkable
|
4
|
-
|
5
5
|
attr_reader :name, :owner
|
6
6
|
|
7
7
|
REPO_REGEX = %r{\A[a-z0-9_\-]+/[a-z0-9_\-\.]+\z}i
|
8
8
|
|
9
9
|
HASH_METHODS = [
|
10
|
-
:name_with_owner, :built?, :last_built,
|
10
|
+
:name_with_owner, :built?, :last_built, :build_duration, :build_error
|
11
11
|
].freeze
|
12
12
|
|
13
13
|
def initialize(name_with_owner, access_token: nil)
|
@@ -21,12 +21,12 @@ module GitHubPages
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def name_with_owner
|
24
|
-
@name_with_owner ||= [owner,name].join("/")
|
24
|
+
@name_with_owner ||= [owner, name].join("/")
|
25
25
|
end
|
26
|
-
|
26
|
+
alias nwo name_with_owner
|
27
27
|
|
28
28
|
def check!
|
29
|
-
raise Errors::BuildError.new(repository
|
29
|
+
raise Errors::BuildError.new(:repository => self), build_error unless built?
|
30
30
|
true
|
31
31
|
end
|
32
32
|
|
@@ -41,14 +41,14 @@ module GitHubPages
|
|
41
41
|
def build_error
|
42
42
|
last_build.error["message"] unless built?
|
43
43
|
end
|
44
|
-
|
44
|
+
alias reason build_error
|
45
45
|
|
46
46
|
def build_duration
|
47
|
-
last_build.duration
|
47
|
+
last_build.duration if last_build
|
48
48
|
end
|
49
49
|
|
50
50
|
def last_built
|
51
|
-
last_build.updated_at
|
51
|
+
last_build.updated_at if last_build
|
52
52
|
end
|
53
53
|
|
54
54
|
def domain
|
@@ -60,7 +60,7 @@ module GitHubPages
|
|
60
60
|
|
61
61
|
def client
|
62
62
|
raise Errors::MissingAccessTokenError if @access_token.nil?
|
63
|
-
@client ||= Octokit::Client.new(access_token
|
63
|
+
@client ||= Octokit::Client.new(:access_token => @access_token)
|
64
64
|
end
|
65
65
|
|
66
66
|
def pages_info
|
@@ -1,11 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GitHubPages
|
2
3
|
module HealthCheck
|
3
4
|
class Site < Checkable
|
4
|
-
|
5
5
|
attr_reader :repository, :domain
|
6
6
|
|
7
7
|
def initialize(repository_or_domain, access_token: nil)
|
8
|
-
@repository = Repository.new(repository_or_domain, access_token
|
8
|
+
@repository = Repository.new(repository_or_domain, :access_token => access_token)
|
9
9
|
@domain = @repository.domain
|
10
10
|
rescue GitHubPages::HealthCheck::Errors::InvalidRepositoryError
|
11
11
|
@repository = nil
|
@@ -13,7 +13,7 @@ module GitHubPages
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def check!
|
16
|
-
[domain, repository].each { |check| check.check!
|
16
|
+
[domain, repository].each { |check| check.check! if check }
|
17
17
|
true
|
18
18
|
end
|
19
19
|
|
@@ -24,8 +24,8 @@ module GitHubPages
|
|
24
24
|
hash[:reason] = reason
|
25
25
|
hash
|
26
26
|
end
|
27
|
-
|
28
|
-
|
27
|
+
alias to_h to_hash
|
28
|
+
alias as_json to_hash
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/script/check
CHANGED
data/script/test
CHANGED
data/script/update-cdn-ips
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# / Usage script/update-ips
|
4
|
+
# / updates config/cloudflare-ips.txt and config/fastly-ips.txt
|
4
5
|
|
5
|
-
require
|
6
|
-
require
|
6
|
+
require "open-uri"
|
7
|
+
require "json"
|
7
8
|
|
8
9
|
SOURCES = {
|
9
|
-
cloudflare
|
10
|
-
fastly
|
11
|
-
}
|
10
|
+
:cloudflare => "https://www.cloudflare.com/ips-v4",
|
11
|
+
:fastly => "https://api.fastly.com/public-ip-list"
|
12
|
+
}.freeze
|
12
13
|
|
13
14
|
SOURCES.each do |source, url|
|
14
15
|
file = "config/#{source}-ips.txt"
|
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.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-dns
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '1.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.40'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.40'
|
153
167
|
description: Checks your GitHub Pages site for commons DNS configuration issues.
|
154
168
|
email: support@github.com
|
155
169
|
executables: []
|
@@ -158,6 +172,7 @@ extra_rdoc_files: []
|
|
158
172
|
files:
|
159
173
|
- ".gitignore"
|
160
174
|
- ".rspec"
|
175
|
+
- ".rubocop.yml"
|
161
176
|
- ".ruby-version"
|
162
177
|
- ".travis.yml"
|
163
178
|
- Gemfile
|