rails_app_version 1.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de1ff73be83ef61042e2e2baddd1b94805f4f41a8ce2f1a021802ccad42c2323
4
- data.tar.gz: a410eac1d9ac536a352f8d3158bf1e5bf6b872aa1fced4c2c152db4adc71d840
3
+ metadata.gz: f0113f2ae9ce34c5fcbb45f7d55c02345cba3783b2ea2591006bd373191b48ea
4
+ data.tar.gz: 3892b19123b2c479f92a3479f4bcc17ce5a96aa146e9cae8997cd8d1d36ef31f
5
5
  SHA512:
6
- metadata.gz: f1cfbe373f72deb414e9bbe6900e690552da4f8f5a68ca7d1df286bb553556a1e16c28f162b6098a7027cdcf7ac1a6d3126bfe986449834049d7a64716b29eb4
7
- data.tar.gz: c09bae51fe6e6ee8e714cc04ef3b4f5558f2618ece745423bab6248372ab10de8e45d5d92b8aaac2dee94c75727b9b667e7bf0f13b7e00672a25655ecdfe73c8
6
+ metadata.gz: 927b60eb8ddeae0e19ece3f442cc81fb09a68e879f96a5e9cb70a487215432c9324fd1c938ea81ae062d77001901af9755bf9649ed60d77fc87f2c6d5285196a
7
+ data.tar.gz: e71614418c799ad88bfb4039463070a2e025d11baf47c68e29e51ffcba0b7ff4a329630cc8018579e95ff2ee651ba7ef6bacb8024f5061e4d5bd981009a2825f
data/README.md CHANGED
@@ -1,45 +1,231 @@
1
1
  # Rails AppVersion
2
2
 
3
- Rails AppVersion is a Ruby on Rails engine designed to easily manage and access your application's version and environment information.
3
+ Rails AppVersion provides an opinionated version and environment management for your Rails applications. By exposing
4
+ version and environment information throughout your application, it enables better error tracking, debugging, and
5
+ deployment management.
4
6
 
5
- It allows for a seamless integration of versioning within your Rails application, providing a straightforward way to access the current application version and environment without hardcoding these values.
7
+ ## Why Use Rails AppVersion?
6
8
 
7
- This gem is exclusively build for Rails applications and is compatible with Rails 7.0 and above.
9
+ Version and environment tracking are important for modern web applications, particularly when debugging issues in
10
+ production. Rails AppVersion helps you:
8
11
 
9
- ## Usage
10
- How to use my plugin.
12
+ - Track errors with version context in error reporting services
13
+ - Identify which version of your application is running in each environment
14
+ - Cache bust assets between versions
15
+ - Verify deployment success across environments
16
+ - Avoid homegrown version management solutions
17
+
18
+ ### Error Reporting Integration Example
19
+
20
+ ```ruby
21
+ Sentry.init do |config|
22
+ config.release = Rails.application.version.to_s
23
+ config.environment = Rails.application.env
24
+ end
25
+ ```
26
+
27
+ ### Cache Management Example
28
+
29
+ ```ruby
30
+
31
+ class AssetManifest
32
+ def asset_path(path)
33
+ "/assets/#{path}?v=#{Rails.application.version.to_cache_key}"
34
+ end
35
+ end
36
+
37
+ # Or in your controller
38
+
39
+ def index
40
+ Rails.cache.fetch("index-page#{Rails.application.version.to_cache_key}") do
41
+ render :index
42
+ end
43
+ end
44
+ ```
11
45
 
12
46
  ## Installation
47
+
13
48
  Add this line to your application's Gemfile:
14
49
 
15
50
  ```ruby
16
51
  gem "rails_app_version"
17
52
  ```
18
53
 
19
- And then execute:
54
+ Then execute:
55
+
20
56
  ```bash
21
- $ bundle
57
+ $ bundle install
58
+ $ rails app:version:config # Copies the default configuration file
59
+ $ echo "1.0.0" > VERSION # Create initial version file
60
+ ```
61
+
62
+ ## Version Management
63
+
64
+ Rails AppVersion supports two methods for managing your application's version:
65
+
66
+ ### Recommended: Using a VERSION File
67
+
68
+ The recommended approach is to maintain a `VERSION` file in your application's root directory. This file should contain
69
+ only the version number:
70
+
71
+ ```plaintext
72
+ 1.2.3
73
+ ```
74
+
75
+ This approach offers several advantages:
76
+
77
+ - Clear version history in source control
78
+ - Easy automated updates during deployment
79
+ - Separation of version from configuration
80
+ - Compatibility with CI/CD pipelines
81
+
82
+ ### Alternative: Configuration in YAML
83
+
84
+ While not recommended for production applications, you can also specify the version directly in the configuration file.
85
+ The default configuration file is located at `config/app_version.yml`:
86
+
87
+ ```yaml
88
+ shared:
89
+ # Attempts to read from VERSION file, falls back to '0.0.0'
90
+ version: <%= Rails.root.join('VERSION').read.strip rescue '0.0.0' %>
91
+ # Attempts to read from REVISION file, then tries git commit hash, finally falls back to '0'
92
+ revision: <%= Rails.root.join('REVISION').read.strip rescue (`git rev-parse HEAD`.strip rescue '0') %>
93
+ show_revision: <%= Rails.env.local? %>
94
+ environment: <%= ENV.fetch('RAILS_APP_ENV', Rails.env) %>
95
+ ```
96
+
97
+ You can customize this configuration for different environments, though we recommend maintaining version information in
98
+ the VERSION file:
99
+
100
+ ```yaml
101
+ shared:
102
+ # Not recommended: hardcoding version in YAML
103
+ version: '1.2.3'
104
+ environment: production
105
+
106
+ development:
107
+ environment: local
108
+ show_revision: true
109
+
110
+ staging:
111
+ environment: staging
112
+ ```
113
+
114
+ ## Usage
115
+
116
+ ### Accessing Version Information
117
+
118
+ ```ruby
119
+ # Get the current version
120
+ Rails.application.version.to_s # => "1.2.3"
121
+
122
+ # Check version components
123
+ Rails.application.version.major # => 1
124
+ Rails.application.version.minor # => 2
125
+ Rails.application.version.patch # => 3
126
+
127
+ # Check version status
128
+ Rails.application.version.production_ready? # => true
129
+ Rails.application.version.prerelease? # => false
130
+
131
+ # Get a cache-friendly version string
132
+ Rails.application.version.to_cache_key # => "1-2-3"
133
+ ```
134
+
135
+ ## Version Headers Middleware
136
+
137
+ Rails AppVersion includes an optional middleware that adds version and environment information to HTTP response headers.
138
+ This is particularly useful in staging and pre-production environments to verify deployment success and track which version
139
+ of the application is serving requests.
140
+
141
+ ### Configuring the Middleware
142
+
143
+ Enable and configure the middleware in your `config/app_version.yml`:
144
+
145
+ ```yaml
146
+ development:
147
+ middleware:
148
+ enabled: false
149
+
150
+ staging:
151
+ middleware:
152
+ enabled: true
153
+ options:
154
+ version_header: X-Staging-Version
155
+ environment_header: X-Staging-Environment
22
156
  ```
23
157
 
24
- ## Usage:
25
- After adding the gem, you can access the application version and environment information anywhere in your Rails application.
158
+ ### Manual Middleware Configuration
159
+
160
+ You can also add the middleware manually in your application configuration:
161
+
26
162
  ```ruby
27
- Rails.application.version # => "1.0.0"
163
+ # config/application.rb or config/environments/staging.rb
164
+ config.middleware.use RailsAppVersion::AppInfoMiddleware, {
165
+ version_header: 'X-Custom-Version',
166
+ environment_header: 'X-Custom-Environment'
167
+ }
168
+ ```
169
+
170
+ The middleware will add the following headers to each response:
171
+
172
+ - X-App-Version: Current application version, optionally including revision (e.g., "1.2.3" or "1.2.3 (abc123de)")
173
+ - X-App-Environment: Current environment (e.g., "staging")
174
+
175
+ When `show_revision` is enabled, the version header will include the first 8 characters of the git revision in
176
+ parentheses. This provides a quick way to verify both the version and the specific deployment in a single header.
177
+
178
+ This makes it easy for developers to verify which version is deployed and running in each environment, particularly
179
+ useful during deployments and debugging.
180
+
181
+ ### Environment Management
182
+
183
+ ```ruby
184
+ # Get the current environment
28
185
  Rails.application.env # => "staging"
186
+
187
+ # Environment checks
188
+ Rails.application.env.production? # => false
189
+ Rails.application.env.staging? # => true
29
190
  ```
30
191
 
31
- ## Features
32
- - Easy Configuration: Set up your application version and environment in a simple YAML file.
33
- - Automatic Integration: The engine automatically integrates with your Rails application, making the version and environment information accessible.
34
- - Flexible Usage: Access the application version and environment information anywhere in your Rails application.
192
+ ### Console Integration
193
+
194
+ The gem automatically displays version and environment information when you start a Rails console:
195
+
196
+ ```
197
+ Welcome to the Rails console!
198
+ Ruby version: 3.2.0
199
+ Application environment: staging
200
+ Application version: 1.2.3
201
+ To exit, press `Ctrl + D`.
202
+ ```
203
+
204
+ ## Version Format
205
+
206
+ Rails AppVersion supports several version formats:
207
+
208
+ - Standard versions: "1.2.3" (major.minor.patch)
209
+ - Short versions: "1.2" (major.minor)
210
+ - Pre-release versions: "2.0.0-alpha" (with pre-release identifier)
211
+
212
+ Version strings are parsed according to Semantic Versioning principles and maintain compatibility with `Gem::Version`
213
+ for comparison operations.
35
214
 
36
215
  ## Contributing
37
- Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
38
- 1. Fork the repo
39
- 2. Create your feature branch (git checkout -b my-new-feature)
40
- 3. Commit your changes (git commit -am 'Add some feature')
41
- 4. Push to the branch (git push origin my-new-feature)
42
- 5. Create a new Pull Request
216
+
217
+ We welcome contributions! Here's how you can help:
218
+
219
+ 1. Fork the repository
220
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
221
+ 3. Add tests for your changes
222
+ 4. Make your changes and ensure tests pass
223
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
224
+ 6. Push to the branch (`git push origin my-new-feature`)
225
+ 7. Create a new Pull Request
226
+
227
+ Please ensure your changes include appropriate tests and documentation.
43
228
 
44
229
  ## License
230
+
45
231
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -3,3 +3,8 @@ shared:
3
3
  revision: <%= Rails.root.join('REVISION').read.strip rescue (`git rev-parse HEAD`.strip rescue '0') %>
4
4
  show_revision: <%= Rails.env.local? %>
5
5
  environment: <%= ENV.fetch('RAILS_APP_ENV', Rails.env) %>
6
+ middleware:
7
+ enabled: true
8
+ options:
9
+ version_header: X-App-Version
10
+ environment_header: X-App-Environment
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAppVersion
4
+ module AppEnvironment
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def env
9
+ @env ||= railties.find do |railtie|
10
+ railtie.is_a?(RailsAppVersion::Railtie)
11
+ end.env
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAppVersion
4
+ class AppInfoMiddleware
5
+ DEFAULT_OPTIONS = {
6
+ version_header: "X-App-Version",
7
+ environment_header: "X-App-Environment"
8
+ }.freeze
9
+
10
+ def initialize(app, options = {})
11
+ @options = DEFAULT_OPTIONS.merge(options)
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ # Call the next middleware in the chain first
17
+ status, headers, response = @app.call(env)
18
+
19
+ # Add our custom headers to the response
20
+ headers[@options[:version_header]] = Rails.application.version.full
21
+ headers[@options[:environment_header]] = Rails.application.env
22
+
23
+ # Return the modified response
24
+ [ status, headers, response ]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAppVersion
4
+ module AppVersion
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def version
9
+ @version ||= railties.find do |railtie|
10
+ railtie.is_a?(RailsAppVersion::Railtie)
11
+ end.version
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ module RailsAppVersion
2
+ class Railtie < ::Rails::Railtie
3
+ class << self
4
+ def root
5
+ @root ||= Pathname.new(File.expand_path(File.expand_path("../../", __dir__)))
6
+ end
7
+ end
8
+
9
+ attr_reader :app_config, :version, :env
10
+
11
+ rake_tasks do
12
+ namespace :app do
13
+ namespace :version do
14
+ desc "Copy config/app_version.yml to the main app config directory"
15
+ task :config do
16
+ source = Railtie.root.join("config", "app_version.yml")
17
+ destination = Rails.root.join("config", "app_version.yml")
18
+
19
+ FileUtils.cp(source, destination)
20
+
21
+ puts "Installed app_version.yml to #{destination}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # Console
28
+ console do
29
+ # rubocop:disable Rails/Output
30
+ puts "Welcome to the Rails console!"
31
+ puts "Ruby version: #{RUBY_VERSION}"
32
+ puts "Application environment: #{Rails.application.env}"
33
+ puts "Application version: #{Rails.application.version}"
34
+ puts "To exit, press `Ctrl + D`."
35
+ # rubocop:enable Rails/Output
36
+ end
37
+
38
+ initializer "fetch_config" do |app|
39
+ @app_config = begin
40
+ app.config_for(:app_version, env: Rails.env)
41
+ rescue RuntimeError => e # file is not found
42
+ # Load the default configuration from the gem
43
+ require "erb"
44
+ yaml = Railtie.root.join("config", "app_version.yml")
45
+ all_configs = ActiveSupport::ConfigurationFile.parse(yaml).deep_symbolize_keys
46
+ all_configs[:shared]
47
+ end
48
+ @version = RailsAppVersion::Version.create(@app_config[:version], @app_config[:revision])
49
+ @env = ActiveSupport::StringInquirer.new(@app_config.fetch(:environment, Rails.env))
50
+ end
51
+
52
+ initializer "middleware" do |app|
53
+ # Add the middleware to the stack if enabled
54
+ if @app_config.dig(:middleware, :enabled)
55
+ options = @app_config.dig(:middleware, :options) || {}
56
+ app.middleware.insert_before Rails::Rack::Logger, RailsAppVersion::AppInfoMiddleware, **options
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,5 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAppVersion
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.1"
5
+
6
+ class Version < Gem::Version
7
+ attr_reader :major, :minor, :patch, :pre, :revision
8
+
9
+ def self.create(version_string, revision = nil)
10
+ new(version_string).tap { |v| v.set_revision(revision) }
11
+ end
12
+
13
+ def set_revision(revision)
14
+ @revision = revision
15
+ end
16
+
17
+ def full
18
+ return to_s unless revision
19
+ "#{self} (#{short_revision})"
20
+ end
21
+
22
+ def to_cache_key
23
+ parts = [ major, minor ]
24
+ parts << patch if has_patch?
25
+ parts << pre if prerelease?
26
+ parts.join("-")
27
+ end
28
+
29
+ def short_revision
30
+ revision&.slice(0, 8)
31
+ end
32
+
33
+ def prerelease?
34
+ !@pre.nil?
35
+ end
36
+
37
+ def production_ready?
38
+ !prerelease? && major.positive?
39
+ end
40
+
41
+ def has_patch?
42
+ !@patch.nil?
43
+ end
44
+
45
+ protected
46
+
47
+ def initialize(version)
48
+ super
49
+ parse_version(version)
50
+ end
51
+
52
+ private
53
+
54
+ def parse_version(version_string)
55
+ if version_string.nil? || version_string.empty?
56
+ raise ArgumentError, "Version string cannot be nil or empty"
57
+ end
58
+
59
+ parts = version_string.split(".")
60
+ pre_parts = parts.last.split("-")
61
+
62
+ if pre_parts.length > 1
63
+ parts[-1] = pre_parts[0]
64
+ @pre = pre_parts[1]
65
+ end
66
+
67
+ @major = parts[0].to_i
68
+ @minor = parts[1]&.to_i || 0
69
+ @patch = parts[2]&.to_i
70
+ end
71
+ end
5
72
  end
@@ -3,88 +3,16 @@
3
3
  require "rails"
4
4
  require "rails/application"
5
5
  require "rails_app_version/version"
6
+ require "rails_app_version/railtie"
7
+ require "rails_app_version/app_version"
8
+ require "rails_app_version/app_environment"
9
+ require "rails_app_version/version"
6
10
  require "action_controller/railtie"
7
11
 
8
12
  module RailsAppVersion
9
- class Version < Gem::Version
10
- # This method cache used by Rails.cache.fetch to generate a cache key
11
- def to_cache_key
12
- (to_s).parameterize
13
- end
14
- end
15
- class Railtie < ::Rails::Railtie
16
- attr_reader :app_config, :version, :env
17
-
18
- def root
19
- @root ||= Pathname.new(File.expand_path("..", __dir__))
20
- end
21
-
22
- rake_tasks do
23
- namespace :app do
24
- namespace :version do
25
- desc "Copy config/app_version.yml to the main app config directory"
26
- task :config do
27
- source = RailsAppVersion::Railtie.root.join("config", "app_version.yml")
28
- destination = Rails.root.join("config", "app_version.yml")
29
-
30
- FileUtils.cp(source, destination)
31
-
32
- puts "Installed app_version.yml to #{destination}"
33
- end
34
- end
35
- end
36
- end
37
-
38
- # Console
39
- console do
40
- # rubocop:disable Rails/Output
41
- puts "Welcome to the Rails console!"
42
- puts "Ruby version: #{RUBY_VERSION}"
43
- puts "Application environment: #{Rails.application.env}"
44
- puts "Application version: #{Rails.application.version}"
45
- puts "To exit, press `Ctrl + D`."
46
- # rubocop:enable Rails/Output
47
- end
48
-
49
- initializer "fetch_config" do |app|
50
- @app_config = begin
51
- app.config_for(:app_version, env: Rails.env)
52
- rescue RuntimeError
53
- # Load the default configuration from the gem, if the app does not have one
54
- require "erb"
55
- yaml = Railtie.root.join("config", "app_version.yml")
56
- all_configs = ActiveSupport::ConfigurationFile.parse(yaml).deep_symbolize_keys
57
- all_configs[:shared]
58
- end
59
-
60
- @version = Version.new(@app_config[:version])
61
- @env = ActiveSupport::StringInquirer.new(@app_config[:environment] || Rails.env)
62
- end
63
- end
64
-
65
- module AppVersion
66
- extend ActiveSupport::Concern
67
-
68
- included do
69
- def version
70
- @version ||= railties.find do |railtie|
71
- railtie.is_a?(RailsAppVersion::Railtie)
72
- end.version
73
- end
74
- end
75
- end
76
-
77
- module AppEnvironment
78
- extend ActiveSupport::Concern
13
+ extend ActiveSupport::Autoload
79
14
 
80
- included do
81
- def env
82
- @env ||= railties.find do |railtie|
83
- railtie.is_a?(RailsAppVersion::Railtie)
84
- end.env
85
- end
86
- end
87
- end
15
+ autoload :AppInfoMiddleware
88
16
  end
89
17
 
90
18
  Rails::Application.include RailsAppVersion::AppVersion
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_app_version
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-03 00:00:00.000000000 Z
10
+ date: 2024-12-31 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: railties
@@ -69,6 +68,10 @@ files:
69
68
  - Rakefile
70
69
  - config/app_version.yml
71
70
  - lib/rails_app_version.rb
71
+ - lib/rails_app_version/app_environment.rb
72
+ - lib/rails_app_version/app_info_middleware.rb
73
+ - lib/rails_app_version/app_version.rb
74
+ - lib/rails_app_version/railtie.rb
72
75
  - lib/rails_app_version/version.rb
73
76
  homepage: https://github.com/seuros/rails_app_version
74
77
  licenses: []
@@ -77,7 +80,6 @@ metadata:
77
80
  source_code_uri: https://github.com/seuros/rails_app_version
78
81
  changelog_uri: https://github.com/seuros/rails_app_version/blob/master/CHANGELOG.md
79
82
  rubygems_mfa_required: 'true'
80
- post_install_message:
81
83
  rdoc_options: []
82
84
  require_paths:
83
85
  - lib
@@ -85,15 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
87
  requirements:
86
88
  - - ">="
87
89
  - !ruby/object:Gem::Version
88
- version: 3.1.0
90
+ version: 3.2.0
89
91
  required_rubygems_version: !ruby/object:Gem::Requirement
90
92
  requirements:
91
93
  - - ">="
92
94
  - !ruby/object:Gem::Version
93
95
  version: '0'
94
96
  requirements: []
95
- rubygems_version: 3.5.16
96
- signing_key:
97
+ rubygems_version: 3.6.2
97
98
  specification_version: 4
98
99
  summary: Get the version of your Rails app
99
100
  test_files: []