on_container 0.0.9 → 0.0.14

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: 0b3faf030bfb28175d373fcaf06d219b8e89eae377a881e0655b0ea71a4248d9
4
- data.tar.gz: 4b0a1a13bfea4e50a199b92caf15cf8c53361e03f4312057a0c10f7e33fa8e8a
3
+ metadata.gz: 9375ce2312b71fcf2711319eb18e58c1e08bfef053edd28bc05e22c9dfeba543
4
+ data.tar.gz: '078fa6d17b8586ebdccdfd033983969a6818df32aedfb22d8a0c4d40dd6e274f'
5
5
  SHA512:
6
- metadata.gz: ff47344c4ca8270ffc7b3aebc028aecc7bc1858bcb50016301c65c21e2ec94dfe0b4a334d18e7c4fa5722f319fd14c72808246094d707dcae15c3f5e8625d9e9
7
- data.tar.gz: 166f0b25ea8db2af892eeeabffe15d96419d57688f9f6531d5f6fb88f7b7a9b6551a00e5049264cf6245eff9566bfa270404cd1af58fec6315593cc8b5a8fcb2
6
+ metadata.gz: 6d76eb51ac0bfbfd78518c711cd627ee9c24b69b44995f4e2728268d12d414422bdbde4881bd95b0962b640d4a1d635cd141632cfa0d2130be3f5b47de57eb88
7
+ data.tar.gz: f7b57e656c49b8435e4434156fee713cbc2af2fdc508371aa290276dd8e1511f50eefe077727a0648092e9f03e5e1fb63fbc2f1abb030bc7192e017d7c948ad9
data/README.md CHANGED
@@ -52,7 +52,7 @@ end if command_requires_setup?
52
52
  execute_given_or_default_command
53
53
  ```
54
54
 
55
- ### Loading secrets into environment variables, and inserting credentials into URL environment variables
55
+ ### Loading secrets into environment variables
56
56
 
57
57
  When using Docker Swarm, the secrets are loaded as files mounted into the container's filesystem.
58
58
 
@@ -65,11 +65,58 @@ For our Rails example app, we added the following line to the `config/boot.rb` f
65
65
 
66
66
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
67
67
 
68
- require 'on_container/load_env_secrets' # Load secrets injected by Kubernetes/Swarm
69
-
70
68
  require 'bundler/setup' # Set up gems listed in the Gemfile.
71
69
  require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
70
+
71
+ # Load swarm/gcp secrets to ENV:
72
+ require 'on_container/load_env_secrets'
73
+ ```
74
+
75
+ #### Loading Google Cloud Secret Manager secrets into ENV
76
+
77
+ If you require loading YAML data stored at [Google Cloud Secret Manager](https://cloud.google.com/secret-manager),
78
+ you will require the following steps:
79
+
80
+ 1. Install the `google-cloud-secret_manager` gem
81
+
82
+ On your gemfile:
83
+
84
+ ```ruby
85
+ # Read secrets from Google Cloud Secret Manager
86
+ gem 'google-cloud-secret_manager', '~> 1.0'
87
+ ```
88
+
89
+ 2. Require it at `config/boot.rb`
90
+
91
+ On `config/boot`, right before requiring `on_container/load_env_secrets`:
92
+
93
+ ```ruby
94
+ # Require Google Cloud Secret Manager to enable 'on_container/load_env_secrets'
95
+ # loading secrets from GCP to ENV:
96
+ require 'google/cloud/secret_manager'
97
+
98
+ # Load swarm/gcp secrets to ENV:
99
+ require 'on_container/load_env_secrets'
100
+ ```
101
+
102
+ 3. Make sure your app has google cloud credentials configured, and have access
103
+ to the secrets your'e planning to use.
104
+
105
+ 4. Configure any number of environment variables ending with
106
+ `_GOOGLE_CLOUD_SECRET`, each containing the secret you want to load. In the
107
+ following example, the command to deploy an image into Google Cloud Run:
108
+
109
+ ```bash
110
+ gcloud run deploy my-demo-app \
111
+ --platform "managed" \
112
+ --region us-central1 \
113
+ --allow-unauthenticated \
114
+ --set-env-vars A_GOOGLE_CLOUD_SECRET=my-super-secret \
115
+ --set-env-vars ANOTHER_GOOGLE_CLOUD_SECRET=project/another-project/secrets/another-secret/versions/1 \
116
+ --service-account=my-demo-service-account@google-cloud \
117
+ --image gcr.io/my-demo-project/my-demo-app:latest
72
118
  ```
119
+ #### Inserting credentials into URL environment variables
73
120
 
74
121
  The `on_container/load_env_secrets` also merges any credential available in environment variables into any matching
75
122
  `_URL` environment variable. For example, consider the following environment variables:
@@ -96,7 +143,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
96
143
 
97
144
  ## Contributing
98
145
 
99
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/on_container. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/on_container/blob/master/CODE_OF_CONDUCT.md).
146
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/on_container. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/on_container/blob/main/CODE_OF_CONDUCT.md).
100
147
 
101
148
 
102
149
  ## License
@@ -105,4 +152,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
105
152
 
106
153
  ## Code of Conduct
107
154
 
108
- Everyone interacting in the OnContainer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/on_container/blob/master/CODE_OF_CONDUCT.md).
155
+ Everyone interacting in the OnContainer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/on_container/blob/main/CODE_OF_CONDUCT.md).
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnContainer
4
+ module Common
5
+ module Performable
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def perform!(*args, **kargs)
12
+ new(*args, **kargs).perform!
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'on_container/common/performable'
4
+
5
+ module OnContainer
6
+ module Common
7
+ module SafePerformable
8
+ def self.included(base)
9
+ base.include OnContainer::Common::Performable
10
+ base.extend ClassMethods
11
+ end
12
+
13
+ def perform(*args, **kargs)
14
+ perform!(*args, **kargs)
15
+ rescue
16
+ false
17
+ end
18
+
19
+ module ClassMethods
20
+ def perform(*args, **kargs)
21
+ new(*args, **kargs).perform
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -6,10 +6,14 @@ module OnContainer
6
6
  def remove_rails_pidfile
7
7
  system "rm -rf #{File.expand_path('tmp/pids/server.pid')}"
8
8
  end
9
+
10
+ def rails?
11
+ ARGV[0] == 'rails'
12
+ end
9
13
 
10
14
  def rails_server?
11
- ARGV[0] == 'rails' && %w[server s].include?(ARGV[1])
15
+ rails? && %w[server s].include?(ARGV[1])
12
16
  end
13
17
  end
14
18
  end
15
- end
19
+ end
@@ -42,6 +42,12 @@ module OnContainer
42
42
  rails rspec sidekiq hutch puma rake webpack webpack-dev-server
43
43
  ].include?(ARGV[0])
44
44
  end
45
+
46
+ def command_might_require_database?
47
+ %w[
48
+ rails rspec sidekiq hutch puma rake
49
+ ].include?(ARGV[0])
50
+ end
45
51
  end
46
52
  end
47
- end
53
+ end
@@ -1,54 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Reads the specified secret paths (i.e. Docker Secrets) into environment
4
- # variables:
5
-
6
- require 'active_support'
7
- require 'active_support/core_ext/object'
8
-
9
- # Process only a known list of env vars that can filled by reading a file (i.e.
10
- # a docker secret):
11
- Dir["#{ENV.fetch('SECRETS_PATH', '/run/secrets/')}*"].each do |secret_filepath|
12
- next unless File.file?(secret_filepath)
13
-
14
- secret_envvarname = File.basename(secret_filepath, '.*').upcase
15
-
16
- # Skip if variable is already set - already-set variables have precedence over
17
- # the secret files:
18
- next if ENV.key?(secret_envvarname) && ENV[secret_envvarname].present?
19
-
20
- ENV[secret_envvarname] = File.read(secret_filepath).strip
21
- end
22
-
23
- # For each *_URL environment variable where there's also a *_(USER|USERNAME) or
24
- # *_(PASS|PASSWORD), update the URL environment variable with the given
25
- # credentials. For example:
3
+ # This script achieves a list of secret loading & processing:
26
4
  #
27
- # DATABASE_URL: postgres://postgres:5432/demo_production
28
- # DATABASE_USERNAME: lalito
29
- # DATABASE_PASSWORD: lepass
5
+ # 1. Loads secrets from Google Cloud Secret Manager to ENV, if configured.
6
+ # 2. Reads files in a configured Folder, and loads them into ENV variables.
7
+ # 3. Processes "*_URL" env vars, adding their respective "*_USER" and "*_PASS".
30
8
  #
31
- # Results in the following updated DATABASE_URL:
32
- # DATABASE_URL = postgres://lalito:lepass@postgres:5432/demo_production
33
- require 'uri' if (url_keys = ENV.keys.select { |key| key =~ /_URL/ }).any?
34
-
35
- url_keys.each do |url_key|
36
- credential_pattern_string = url_key.gsub('_URL', '_(USER(NAME)?|PASS(WORD)?)')
37
- credential_pattern = Regexp.new "\\A#{credential_pattern_string}\\z"
38
- credential_keys = ENV.keys.select { |key| key =~ credential_pattern }
39
- next unless credential_keys.any?
40
-
41
- uri = URI(ENV[url_key])
42
-
43
- credential_keys.each do |credential_key|
44
- credential_value = URI.encode_www_form_component ENV[credential_key]
45
- case credential_key
46
- when /USER/ then uri.user = credential_value
47
- when /PASS/ then uri.password = credential_value
48
- end
49
- end
50
-
51
- ENV[url_key] = uri.to_s
52
- end
9
+ # - See https://github.com/IcaliaLabs/on-container-for-ruby#loading-secrets-into-environment-variables
53
10
 
54
- # STDERR.puts ENV.inspect
11
+ require 'on_container/secrets/env_loader'
12
+ OnContainer::Secrets::EnvLoader.perform!
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'on_container/common/safe_performable'
4
+ require 'on_container/secrets/google_cloud/env_loader'
5
+ require 'on_container/secrets/mounted_files/env_loader'
6
+ require 'on_container/secrets/url_variable_processor'
7
+
8
+ module OnContainer
9
+ module Secrets
10
+ #= EnvLoader
11
+ #
12
+ # Reads the specified secret paths (i.e. Docker Secrets) into environment
13
+ # variables:
14
+ class EnvLoader
15
+ include OnContainer::Common::SafePerformable
16
+
17
+ def perform!
18
+ load_secrets_from_google_cloud if google_cloud_secrets?
19
+ load_secrets_from_mounted_files
20
+ process_url_variables
21
+ true
22
+ end
23
+
24
+ private
25
+
26
+ def google_cloud_secrets?
27
+ OnContainer::Secrets::GoogleCloud::EnvLoader.secret_manager?
28
+ end
29
+
30
+ def load_secrets_from_google_cloud
31
+ OnContainer::Secrets::GoogleCloud::EnvLoader.perform!
32
+ end
33
+
34
+ def load_secrets_from_mounted_files
35
+ OnContainer::Secrets::MountedFiles::EnvLoader.perform!
36
+ end
37
+
38
+ def process_url_variables
39
+ OnContainer::Secrets::UrlVariableProcessor.perform!
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "on_container/secrets/google_cloud/fetcher"
4
+
5
+ module OnContainer
6
+ module Secrets
7
+ module GoogleCloud
8
+ class EnvLoader < ServiceBase
9
+ ENV_KEY_SUFIX = '_GOOGLE_CLOUD_SECRET'
10
+
11
+ def env_keys
12
+ @env_keys ||= ENV.keys.select do |key|
13
+ key.end_with?(ENV_KEY_SUFIX)
14
+ end.sort
15
+ end
16
+
17
+ def env_keys?
18
+ env_keys.any?
19
+ end
20
+
21
+ def self.secret_manager?
22
+ defined?(Google::Cloud::SecretManager) == 'constant'
23
+ end
24
+
25
+ def secret_manager?
26
+ self.class.secret_manager?
27
+ end
28
+
29
+ def perform!
30
+ return unless env_keys? && secret_manager?
31
+
32
+ env_keys.each do |key|
33
+ ENV.merge! Fetcher.perform! ENV[key], client: client
34
+ end
35
+
36
+ true
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'on_container/secrets/google_cloud/service_base'
5
+
6
+ module OnContainer
7
+ module Secrets
8
+ module GoogleCloud
9
+ class Fetcher < ServiceBase
10
+ PROJECT_PATTERN = %r{\Aprojects\/(\w+)\/.*}.freeze
11
+ SECRET_NAME_PATTERN = %r{secrets\/([\w-]+)\/?}.freeze
12
+ SECRET_VERSION_PATTERN = %r{versions\/(\d+|latest)\z}.freeze
13
+
14
+ attr_reader :project, :secret_name, :secret_version
15
+
16
+ def initialize(given_key, client: nil)
17
+ @client = client
18
+ @project = extract_project given_key
19
+ @secret_version = extract_secret_version given_key
20
+ @secret_name = extract_secret_name given_key
21
+ end
22
+
23
+ def perform!
24
+ # Build the resource name of the secret version.
25
+ name = client.secret_version_path project: @project,
26
+ secret: @secret_name,
27
+ secret_version: @secret_version
28
+
29
+ version = client.access_secret_version name: name
30
+
31
+ YAML.load version.payload.data
32
+ end
33
+
34
+ protected
35
+
36
+ def default_project
37
+ ENV['GOOGLE_CLOUD_PROJECT']
38
+ end
39
+
40
+ def extract_project(given_key)
41
+ match = given_key.match(PROJECT_PATTERN)
42
+ return default_project unless match
43
+
44
+ match.captures.first
45
+ end
46
+
47
+ def extract_secret_version(given_key)
48
+ match = given_key.match(SECRET_VERSION_PATTERN)
49
+ return 'latest' unless match
50
+
51
+ match.captures.first
52
+ end
53
+
54
+ def extract_secret_name(given_key)
55
+ given_key
56
+ .sub("projects/#{@project}/secrets/", '')
57
+ .sub("/versions/#{@secret_version}", '')
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "on_container/common/safe_performable"
4
+
5
+ module OnContainer
6
+ module Secrets
7
+ module GoogleCloud
8
+ class ServiceBase
9
+ include OnContainer::Common::SafePerformable
10
+
11
+ attr_reader :client
12
+
13
+ def client
14
+ @client ||= Google::Cloud::SecretManager.secret_manager_service
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext/object'
5
+ require 'on_container/common/safe_performable'
6
+
7
+ module OnContainer
8
+ module Secrets
9
+ module MountedFiles
10
+ class EnvLoader
11
+ include OnContainer::Common::SafePerformable
12
+
13
+ def perform!
14
+ setup_secrets_path
15
+ scan_secrets_path_for_files
16
+ load_secret_files_to_env_vars
17
+ end
18
+
19
+ def secrets_path
20
+ @secrets_path ||= ENV.fetch('SECRETS_PATH', '/run/secrets')
21
+ end
22
+
23
+ def secret_mounted_file_paths
24
+ @secret_mounted_file_paths ||= Dir["#{secrets_path}/**/*"]
25
+ .map { |path| Pathname.new(path) }
26
+ .select(&:file?)
27
+ end
28
+
29
+ private
30
+
31
+ alias setup_secrets_path secrets_path
32
+ alias scan_secrets_path_for_files secret_mounted_file_paths
33
+
34
+ def load_secret_files_to_env_vars
35
+ return if @already_loaded
36
+
37
+ secret_mounted_file_paths
38
+ .each { |file_path| load_secret_file_to_env_var(file_path) }
39
+
40
+ @already_loaded = true
41
+ end
42
+
43
+ def load_secret_file_to_env_var(file_path)
44
+ env_var_name = file_path.basename('.*').to_s.upcase
45
+
46
+ # Skip if variable is already set - already-set variables have
47
+ # precedence over the secret files:
48
+ return if ENV.key?(env_var_name) && ENV[env_var_name].present?
49
+
50
+ contents = file_path.read.strip
51
+
52
+ # TODO: Do not load if content has null bytes
53
+ ENV[env_var_name] = file_path.read.strip
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'on_container/common/safe_performable'
4
+
5
+ module OnContainer
6
+ module Secrets
7
+ #= UrlVariableProcessor
8
+ #
9
+ # For each *_URL environment variable where there's also a *_(USER|USERNAME)
10
+ # or *_(PASS|PASSWORD), updates the URL environment variable with the given
11
+ # credentials. For example:
12
+ #
13
+ # DATABASE_URL: postgres://postgres:5432/demo_production
14
+ # DATABASE_USERNAME: lalito
15
+ # DATABASE_PASSWORD: lepass
16
+ #
17
+ # Results in the following updated DATABASE_URL:
18
+ # DATABASE_URL = postgres://lalito:lepass@postgres:5432/demo_production
19
+ class UrlVariableProcessor
20
+ include OnContainer::Common::SafePerformable
21
+
22
+ def perform!
23
+ require_uri_module if url_keys?
24
+ process_credential_keys
25
+ end
26
+
27
+ def url_keys
28
+ @url_keys ||= ENV.keys.select { |key| key =~ /_URL/ }
29
+ end
30
+
31
+ def url_keys?
32
+ url_keys.any?
33
+ end
34
+
35
+ private
36
+
37
+ def process_credential_keys
38
+ url_keys.each { |url_key| process_credential_keys_for(url_key) }
39
+ end
40
+
41
+ def require_uri_module
42
+ require 'uri'
43
+ end
44
+
45
+ def credential_keys_for(url_key)
46
+ credential_pattern_string = url_key
47
+ .gsub('_URL', '_(USER(NAME)?|PASS(WORD)?)')
48
+
49
+ credential_pattern = Regexp.new "\\A#{credential_pattern_string}\\z"
50
+ ENV.keys.select { |key| key =~ credential_pattern }
51
+ end
52
+
53
+ def process_credential_keys_for(url_key)
54
+ return unless (credential_keys = credential_keys_for(url_key)).any?
55
+
56
+ uri = URI(ENV[url_key])
57
+
58
+ # Reverse sorting will place "*_USER" before "*_PASS":
59
+ credential_keys.sort.reverse.each do |credential_key|
60
+ credential_value = URI.encode_www_form_component ENV[credential_key]
61
+ case credential_key
62
+ when /USER/ then uri.user = credential_value
63
+ when /PASS/ then uri.password = credential_value
64
+ end
65
+ end
66
+
67
+ ENV[url_key] = uri.to_s
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnContainer
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.14'
5
5
  end
data/on_container.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.metadata['homepage_uri'] = spec.homepage
18
18
  spec.metadata['source_code_uri'] = spec.homepage
19
- spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
20
 
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.files = `git ls-files -- lib/* *.md *.gemspec *.txt Rakefile`.split("\n")
@@ -24,5 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.bindir = 'exe'
25
25
  spec.require_paths = ['lib']
26
26
 
27
+ spec.add_runtime_dependency 'activesupport', '>= 4'
27
28
  spec.add_development_dependency 'bundler', '~> 2.1'
28
29
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: on_container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Quintanilla
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-28 00:00:00.000000000 Z
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,8 @@ files:
38
52
  - README.md
39
53
  - Rakefile
40
54
  - lib/on_container.rb
55
+ - lib/on_container/common/performable.rb
56
+ - lib/on_container/common/safe_performable.rb
41
57
  - lib/on_container/dev/active_record_ops.rb
42
58
  - lib/on_container/dev/bundler_ops.rb
43
59
  - lib/on_container/dev/container_command_ops.rb
@@ -47,6 +63,12 @@ files:
47
63
  - lib/on_container/dev/setup_ops.rb
48
64
  - lib/on_container/load_env_secrets.rb
49
65
  - lib/on_container/ops/service_connection_checks.rb
66
+ - lib/on_container/secrets/env_loader.rb
67
+ - lib/on_container/secrets/google_cloud/env_loader.rb
68
+ - lib/on_container/secrets/google_cloud/fetcher.rb
69
+ - lib/on_container/secrets/google_cloud/service_base.rb
70
+ - lib/on_container/secrets/mounted_files/env_loader.rb
71
+ - lib/on_container/secrets/url_variable_processor.rb
50
72
  - lib/on_container/version.rb
51
73
  - on_container.gemspec
52
74
  homepage: https://github.com/IcaliaLabs/on-container-for-ruby
@@ -56,7 +78,7 @@ metadata:
56
78
  allowed_push_host: https://rubygems.org
57
79
  homepage_uri: https://github.com/IcaliaLabs/on-container-for-ruby
58
80
  source_code_uri: https://github.com/IcaliaLabs/on-container-for-ruby
59
- changelog_uri: https://github.com/IcaliaLabs/on-container-for-ruby/blob/master/CHANGELOG.md
81
+ changelog_uri: https://github.com/IcaliaLabs/on-container-for-ruby/blob/main/CHANGELOG.md
60
82
  post_install_message:
61
83
  rdoc_options: []
62
84
  require_paths: