lib/shipit/github_app.rb in shipit-engine-0.29.0 vs lib/shipit/github_app.rb in shipit-engine-0.30.0
- old
+ new
@@ -7,28 +7,40 @@
def from_github(github_response)
new(github_response.token, github_response.expires_at)
end
end
+ attr_reader :expires_at, :refresh_at
+
def to_s
@token
end
def initialize(token, expires_at)
@token = token
@expires_at = expires_at
+
+ # This needs to be lower than the token's lifetime, but higher than the cache expiry setting.
+ @refresh_at = expires_at - GITHUB_TOKEN_REFRESH_WINDOW
end
def blank?
- @expires_at.past?
+ # Old tokens missing @refresh_at may be used upon deploy, so we should auto-correct for now.
+ # TODO: Remove this assignment at a later date.
+ @refresh_at ||= @expires_at - GITHUB_TOKEN_REFRESH_WINDOW
+ @refresh_at.past?
end
end
DOMAIN = 'github.com'.freeze
AuthenticationFailed = Class.new(StandardError)
API_STATUS_ID = 'brv1bkgrwx7q'.freeze
+ GITHUB_EXPECTED_TOKEN_LIFETIME = 60.minutes
+ GITHUB_TOKEN_RAILS_CACHE_LIFETIME = 50.minutes
+ GITHUB_TOKEN_REFRESH_WINDOW = GITHUB_EXPECTED_TOKEN_LIFETIME - GITHUB_TOKEN_RAILS_CACHE_LIFETIME - 2.minutes
+
attr_reader :oauth_teams, :domain, :bot_login
def initialize(config)
super()
@config = (config || {}).with_indifferent_access
@@ -77,17 +89,25 @@
@token = @token.presence || synchronize { @token.presence || fetch_new_token }
@token.to_s
end
def fetch_new_token
- Rails.cache.fetch('github:integration:access-token', expires_in: 50.minutes, race_condition_ttl: 10.minutes) do
+ # Rails can add 5 minutes to the cache entry expiration time when any TTL is provided,
+ # so our TTL setting can be lower, and TTL + expires_in should be lower than the GitHub token expiration.
+ Rails.cache.fetch(
+ 'github:integration:access-token',
+ expires_in: GITHUB_TOKEN_RAILS_CACHE_LIFETIME,
+ race_condition_ttl: 4.minutes,
+ ) do
response = new_client(bearer_token: authentication_payload).create_app_installation_access_token(
installation_id,
accept: 'application/vnd.github.machine-man-preview+json',
)
token = Token.from_github(response)
raise AuthenticationFailed if token.blank?
+ Rails.logger.info("Created GitHub access token ending #{token.to_s[-5..-1]}, expires at #{token.expires_at}"\
+ " and will be refreshed at #{token&.refresh_at}")
token
end
end
def oauth?
@@ -118,15 +138,24 @@
def api_endpoint
url('/api/v3/') if enterprise?
end
+ def web_endpoint
+ url if enterprise?
+ end
+
def enterprise?
domain != DOMAIN
end
def new_client(options = {})
- options.reverse_merge(api_endpoint: api_endpoint) if api_endpoint
+ if enterprise?
+ options = options.reverse_merge(
+ api_endpoint: api_endpoint,
+ web_endpoint: web_endpoint,
+ )
+ end
client = Octokit::Client.new(options)
client.middleware = faraday_stack
client
end