Skip to content

Commit ec2cb25

Browse files
etewiahclaude
andcommitted
Add version check on application boot
Checks for PWB updates when the Rails server starts and logs the result: - If running latest: "[PWB Version] Running latest version (2.2.0)" - If outdated: "[PWB Version] Update available! Current: X, Latest: Y..." The check runs in a background thread to avoid blocking server startup. Calls the PWB version check API at propertywebbuilder.com. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 7aac0fb commit ec2cb25

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# frozen_string_literal: true
2+
3+
module Pwb
4+
# Service for checking if a newer version of PropertyWebBuilder is available.
5+
#
6+
# Calls the PWB version check API endpoint to compare the current version
7+
# against the latest release.
8+
#
9+
# Usage:
10+
# # Check for updates and log if available
11+
# Pwb::VersionCheckService.check_and_log
12+
#
13+
# # Get version info without logging
14+
# info = Pwb::VersionCheckService.check
15+
# puts info[:latest_version] if info[:update_available]
16+
#
17+
class VersionCheckService
18+
VERSION_CHECK_URL = 'https://propertywebbuilder.com/api_public/v4/version_check'
19+
REQUEST_TIMEOUT = 5 # seconds
20+
21+
class << self
22+
# Check for updates and log a message if a new version is available
23+
#
24+
# @return [Hash, nil] version info hash or nil if check failed
25+
def check_and_log
26+
info = check
27+
return nil unless info
28+
29+
if info[:update_available]
30+
log_update_available(info)
31+
else
32+
Rails.logger.info "[PWB Version] Running latest version (#{Pwb::VERSION})"
33+
end
34+
35+
info
36+
rescue StandardError => e
37+
Rails.logger.debug "[PWB Version] Check failed: #{e.message}"
38+
nil
39+
end
40+
41+
# Check for updates by calling the version check API
42+
#
43+
# @return [Hash, nil] version info hash or nil if check failed
44+
# @example Return value
45+
# {
46+
# incoming_version: "2.1.0",
47+
# latest_version: "2.2.0",
48+
# latest_release_date: "2025-12-21",
49+
# is_latest: false,
50+
# update_available: true,
51+
# versions_behind: 1
52+
# }
53+
def check
54+
response = fetch_version_info
55+
return nil unless response
56+
57+
parse_response(response)
58+
rescue StandardError => e
59+
Rails.logger.debug "[PWB Version] API call failed: #{e.message}"
60+
nil
61+
end
62+
63+
# Get the current PWB version
64+
#
65+
# @return [String] the current version string
66+
def current_version
67+
Pwb::VERSION
68+
end
69+
70+
private
71+
72+
def fetch_version_info
73+
uri = URI("#{VERSION_CHECK_URL}?version=#{current_version}")
74+
75+
http = Net::HTTP.new(uri.host, uri.port)
76+
http.use_ssl = true
77+
http.open_timeout = REQUEST_TIMEOUT
78+
http.read_timeout = REQUEST_TIMEOUT
79+
80+
# Skip strict SSL verification for version check (read-only, non-sensitive)
81+
# This works around OpenSSL 3.6+ CRL verification issues on macOS
82+
# See: config/initializers/ssl_crl_fix.rb
83+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
84+
85+
request = Net::HTTP::Get.new(uri)
86+
request['Accept'] = 'application/json'
87+
request['User-Agent'] = "PropertyWebBuilder/#{current_version}"
88+
89+
response = http.request(request)
90+
91+
return nil unless response.is_a?(Net::HTTPSuccess)
92+
93+
response.body
94+
end
95+
96+
def parse_response(json_string)
97+
data = JSON.parse(json_string, symbolize_names: true)
98+
99+
{
100+
incoming_version: data[:incoming_version],
101+
latest_version: data[:latest_version],
102+
latest_release_date: data[:latest_release_date],
103+
is_latest: data[:is_latest],
104+
is_known_version: data[:is_known_version],
105+
update_available: data[:update_available],
106+
versions_behind: data[:versions_behind]
107+
}
108+
rescue JSON::ParserError => e
109+
Rails.logger.debug "[PWB Version] Failed to parse response: #{e.message}"
110+
nil
111+
end
112+
113+
def log_update_available(info)
114+
message = <<~MSG.squish
115+
[PWB Version] Update available!
116+
Current: #{info[:incoming_version]},
117+
Latest: #{info[:latest_version]}
118+
(#{info[:versions_behind]} version(s) behind,
119+
released #{info[:latest_release_date]}).
120+
Visit https://github.com/etewiah/property_web_builder for upgrade instructions.
121+
MSG
122+
123+
Rails.logger.info message
124+
end
125+
end
126+
end
127+
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
# Check for PWB updates on application boot
4+
#
5+
# This runs asynchronously to avoid slowing down server startup.
6+
# Only runs on first boot (not on Rails console or rake tasks).
7+
8+
Rails.application.config.after_initialize do
9+
# Only check in server context, not in console/rake/test
10+
next unless defined?(Rails::Server) || ENV['PWB_FORCE_VERSION_CHECK']
11+
12+
# Skip in test environment
13+
next if Rails.env.test?
14+
15+
# Run the check in a background thread to avoid blocking boot
16+
Thread.new do
17+
# Small delay to let the server finish initializing
18+
sleep 2
19+
20+
begin
21+
Pwb::VersionCheckService.check_and_log
22+
rescue StandardError => e
23+
Rails.logger.debug "[PWB Version] Startup check failed: #{e.message}"
24+
end
25+
end
26+
end

0 commit comments

Comments
 (0)