rails_app_version 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []