global 0.2.2 → 2.1.0

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
- SHA1:
3
- metadata.gz: ff7ffaa8d2e0f5e244d2a8afbe0d8e938cea9244
4
- data.tar.gz: 8153165733bd12e6c4673c39abdbb16b706a7fc6
2
+ SHA256:
3
+ metadata.gz: 0da470ddbf97c73984898898bbada287d1fef733da1059016dbe7021a6b4e55a
4
+ data.tar.gz: b5cf15fb7e5a9e4e9cb7b30a0bf1265a374693d6f1423b95940976c9beeca3f0
5
5
  SHA512:
6
- metadata.gz: efa24df45cb25c916773f4ff7c1dcc0621421016f567a54af18f77bae41a9242e9dd9a5f5bf942db4db8e133f0b17d971fed83de28fd787cf301859d035b5d61
7
- data.tar.gz: 01156ae25535c3d559da859c6717feb59c07510291e23306920e722d35bf3c8c112b789c61d633ec7dc1d019f9ee36380c9889c56b1c7a5e990a2b79930363ff
6
+ metadata.gz: cbd030fd6ced5e6e3f0d47d75d14f59e16a69411814b1432f0bf66fb03444950006a87b86eed155f758c4a5535eb6e8d9d870edbecdc26c9a66b2a9230384e82
7
+ data.tar.gz: b99c7b6c92c33324834ad7fd92c75606a9abddbe7d8fe0fbe22b344013000a49073ece171b8063713b370d2c6526c6c0eee928584c90317e5592034506bc3790
@@ -0,0 +1,24 @@
1
+ name: Runs linter and tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ linters_and_tests:
7
+ runs-on: ${{ matrix.os }}-latest
8
+ continue-on-error: ${{ matrix.experimental == true }}
9
+ name: Linter and tests on ${{ matrix.os }}-ruby-${{ matrix.ruby-version }}
10
+ strategy:
11
+ matrix:
12
+ os: [ubuntu, macos]
13
+ ruby-version: ['3.1', '3.0', '2.7', '2.6', '2.5']
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby-version }}
21
+ bundler-cache: true
22
+
23
+ - name: Runs linter and tests
24
+ run: bundle exec rake
data/.rubocop.yml ADDED
@@ -0,0 +1,110 @@
1
+ Metrics/MethodLength:
2
+ Enabled: true
3
+ Max: 11
4
+
5
+ Layout/EmptyLinesAroundBlockBody:
6
+ Enabled: false
7
+
8
+ Layout/SpaceInsideBlockBraces:
9
+ Enabled: true
10
+ EnforcedStyle: space
11
+ EnforcedStyleForEmptyBraces: no_space
12
+ SpaceBeforeBlockParameters: true
13
+
14
+ Layout/SpaceBeforeBlockBraces:
15
+ Enabled: true
16
+ EnforcedStyle: space
17
+ EnforcedStyleForEmptyBraces: space
18
+
19
+ Layout/SpaceInsideHashLiteralBraces:
20
+ Enabled: true
21
+ EnforcedStyle: compact
22
+ EnforcedStyleForEmptyBraces: no_space
23
+
24
+ Layout/EmptyLinesAroundClassBody:
25
+ Enabled: true
26
+ EnforcedStyle: empty_lines_except_namespace
27
+
28
+ Layout/EmptyLinesAroundModuleBody:
29
+ Enabled: true
30
+ EnforcedStyle: empty_lines_except_namespace
31
+
32
+ Layout/MultilineMethodCallIndentation:
33
+ Enabled: true
34
+ EnforcedStyle: indented
35
+
36
+ Layout/HashAlignment:
37
+ Enabled: true
38
+ EnforcedLastArgumentHashStyle: always_ignore
39
+
40
+ Lint/RaiseException:
41
+ Enabled: true
42
+
43
+ Lint/StructNewOverride:
44
+ Enabled: true
45
+
46
+ Style/RaiseArgs:
47
+ EnforcedStyle: compact
48
+
49
+ Style/YodaCondition:
50
+ Enabled: false
51
+
52
+ Style/FrozenStringLiteralComment:
53
+ Enabled: true
54
+ EnforcedStyle: always
55
+
56
+ Style/HashEachMethods:
57
+ Enabled: true
58
+
59
+ Style/HashTransformKeys:
60
+ Enabled: true
61
+
62
+ Style/HashTransformValues:
63
+ Enabled: true
64
+
65
+ Style/RegexpLiteral:
66
+ Enabled: true
67
+ EnforcedStyle: slashes
68
+ AllowInnerSlashes: false
69
+
70
+ Layout/FirstHashElementIndentation:
71
+ EnforcedStyle: consistent
72
+
73
+ Style/Documentation:
74
+ Enabled: false
75
+
76
+ Style/SafeNavigation:
77
+ Enabled: true
78
+ AllowedMethods:
79
+ - present?
80
+ - blank?
81
+ - presence
82
+
83
+ Lint/AmbiguousBlockAssociation:
84
+ Exclude:
85
+ - "spec/**/*"
86
+
87
+ Naming/PredicateName:
88
+ Exclude:
89
+ - "spec/**/*"
90
+
91
+ Style/NumericPredicate:
92
+ Exclude:
93
+ - "spec/**/*"
94
+
95
+ Metrics/BlockLength:
96
+ Exclude:
97
+ - "spec/**/*"
98
+
99
+ Layout/LineLength:
100
+ Max: 120
101
+ Exclude:
102
+ - "spec/**/*"
103
+
104
+ Metrics/AbcSize:
105
+ Max: 22
106
+ Exclude:
107
+ - "spec/**/*"
108
+
109
+ Style/ModuleFunction:
110
+ EnforcedStyle: extend_self
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.1
1
+ 2.6.6
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at leopard.not.a@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,9 +1,6 @@
1
- source "http://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in global.gemspec
4
6
  gemspec
5
-
6
- if RUBY_VERSION < "2.2.2"
7
- # activesupport 5+ requires MRI 2.2.2+
8
- gem "activesupport", "< 5.0.0"
9
- end
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Global [![Build Status](https://travis-ci.org/railsware/global.png)](https://travis-ci.org/railsware/global) [![Code Climate](https://codeclimate.com/github/railsware/global.png)](https://codeclimate.com/github/railsware/global)
1
+ # Global [![Runs linter and tests](https://github.com/railsware/global/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/railsware/global/actions/workflows/tests.yml) [![Code Climate](https://codeclimate.com/github/railsware/global.png)](https://codeclimate.com/github/railsware/global)
2
2
 
3
- The 'global' gem provides accessor methods for your configuration data and share configuration across backend and frontend. The data is stored in yaml files.
3
+ The 'global' gem provides accessor methods for your configuration data and share configuration across backend and frontend.
4
+
5
+ The data can be stored in [YAML](https://yaml.org) files on disk, or in the [AWS SSM Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html).
4
6
 
5
7
  ## Installation
6
8
 
@@ -10,36 +12,73 @@ Add to Gemfile:
10
12
  gem 'global'
11
13
  ```
12
14
 
15
+ Refer to the documentation on your chosen backend class for other dependencies.
16
+
13
17
  ## Configuration
14
18
 
19
+ Refer to the documentation on your chosen backend class for configuration options.
20
+
15
21
  ```ruby
16
- > Global.environment = "YOUR_ENV_HERE"
17
- > Global.config_directory = "PATH_TO_DIRECTORY_WITH_FILES"
22
+ > Global.backend(:filesystem, environment: "YOUR_ENV_HERE", path: "PATH_TO_DIRECTORY_WITH_FILES")
18
23
  ```
19
24
 
20
25
  Or you can use `configure` block:
21
26
 
22
27
  ```ruby
23
28
  Global.configure do |config|
24
- config.environment = "YOUR_ENV_HERE"
25
- config.config_directory = "PATH_TO_DIRECTORY_WITH_FILES"
29
+ config.backend :filesystem, environment: "YOUR_ENV_HERE", path: "PATH_TO_DIRECTORY_WITH_FILES"
30
+ # set up multiple backends and have them merged together:
31
+ config.backend :aws_parameter_store, prefix: '/prod/MyApp/'
32
+ config.backend :gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example'
26
33
  end
27
34
  ```
28
35
 
29
- For rails put initialization into `config/initializers/global.rb`
36
+ ### Using multiple backends
37
+
38
+ Sometimes it is practical to store some configuration data on disk (and perhaps, commit it to source control), but
39
+ keep some other data in a secure remote location. Which is why you can use more than one backend with Global.
40
+
41
+ You can declare as many backends as you want; the configuration trees from the backends are deep-merged together,
42
+ so that the backend declared later overwrites specific keys in the backend declared prior:
43
+
44
+ ```ruby
45
+ Global.configure do |config|
46
+ config.backend :foo # loads tree { credentials: { hostname: 'api.com', username: 'dev', password: 'dev' } }
47
+ config.backend :bar # loads tree { credentials: { username: 'xxx', password: 'yyy' } }
48
+ end
49
+
50
+ Global.credentials.hostname # => 'api.com'
51
+ Global.credentials.username # => 'xxx'
52
+ Global.credentials.password # => 'yyy'
53
+ ```
54
+
55
+ For Rails, put initialization into `config/initializers/global.rb`.
56
+
57
+ There are some sensible defaults, check your backend class for documentation.
30
58
 
31
59
  ```ruby
32
60
  Global.configure do |config|
33
- config.environment = Rails.env.to_s
34
- config.config_directory = Rails.root.join('config/global').to_s
61
+ config.backend :filesystem
35
62
  end
36
63
  ```
37
64
 
65
+ ### Filesystem storage
66
+
67
+ The `yaml_whitelist_classes` configuration allows you to deserialize other classes from your `.yml`
68
+
69
+ ### AWS Parameter Store
70
+
71
+ The `aws_options` configuration allows you to customize the AWS credentials and connection.
72
+
73
+ ### Google Cloud Secret Manager
74
+
75
+ The `gcp_options` configuration allows you to customize the Google Cloud credentials and timeout.
76
+
38
77
  ## Usage
39
78
 
40
- ### General
79
+ ### Filesystem
41
80
 
42
- Config file `config/global/hosts.yml`:
81
+ For file `config/global/hosts.yml`:
43
82
 
44
83
  ```yml
45
84
  test:
@@ -62,9 +101,28 @@ In the development environment we now have:
62
101
  => "api.localhost"
63
102
  ```
64
103
 
65
- ### Namespacing
104
+ #### Deserialize other classes from `.yml`
66
105
 
67
- Config file `config/global/web/basic_auth.yml` with:
106
+ Config file `config/global/validations.yml`:
107
+
108
+ ```yml
109
+ default:
110
+ regexp:
111
+ email: !ruby/regexp /.@.+\../
112
+ ```
113
+
114
+ Ensure that `Regexp` is included in the `yaml_whitelist_classes` array
115
+
116
+ ```ruby
117
+ Global.validations.regexp.email === 'mail@example.com'
118
+ => true
119
+ ```
120
+
121
+ #### Per-environment sections
122
+
123
+ You can define environment sections at the top level of every individual YAML file
124
+
125
+ For example, having a config file `config/global/web/basic_auth.yml` with:
68
126
 
69
127
  ```yml
70
128
  test:
@@ -78,7 +136,7 @@ production:
78
136
  password: supersecret
79
137
  ```
80
138
 
81
- After that in development environment we have:
139
+ You get the correct configuration in development
82
140
 
83
141
  ```ruby
84
142
  > Global.web.basic_auth
@@ -87,7 +145,7 @@ After that in development environment we have:
87
145
  => "development_user"
88
146
  ```
89
147
 
90
- ### Default section
148
+ #### Default section
91
149
 
92
150
  Config file example:
93
151
 
@@ -102,9 +160,10 @@ production:
102
160
 
103
161
  Data from the default section is used until it's overridden in a specific environment.
104
162
 
105
- ### Nested configurations
163
+ #### Nested configurations
106
164
 
107
165
  Config file `global/nested.yml` with:
166
+
108
167
  ```yml
109
168
  test:
110
169
  group:
@@ -124,8 +183,41 @@ Nested options can then be accessed as follows:
124
183
  => "development value"
125
184
  ```
126
185
 
186
+ #### Environment files
187
+
188
+ Config file `global/aws.yml` with:
189
+ ```yml
190
+ :default:
191
+ activated: false
127
192
 
128
- ### ERB support
193
+ staging:
194
+ activated: true
195
+ api_key: 'nothing'
196
+
197
+ ```
198
+
199
+ And file `global/aws.production.yml` with:
200
+ ```yml
201
+ :activated: true
202
+ :api_key: 'some api key'
203
+ :api_secret: 'some secret'
204
+
205
+ ```
206
+
207
+ Provide such configuration on `Global.environment = 'production'` environment:
208
+
209
+ ```ruby
210
+ > Global.aws.activated
211
+ => true
212
+ > Global.aws.api_key
213
+ => 'some api key'
214
+ > Global.aws.api_secret
215
+ => 'some secret'
216
+ ```
217
+
218
+ **Warning**: files with dot(s) in name will be skipped by Global (except this env files).
219
+
220
+ #### ERB support
129
221
 
130
222
  Config file `global/file_name.yml` with:
131
223
 
@@ -145,79 +237,191 @@ As a result, in the development environment we have:
145
237
  => 4
146
238
  ```
147
239
 
148
- ### Reload configuration data
240
+ ### AWS Parameter Store
241
+
242
+ Parameter Store is a secure configuration storage with at-rest encryption. Access is controlled through AWS IAM. You do not need to be hosted on AWS to use Parameter Store.
243
+
244
+ Refer to the [official documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) to set up the store.
245
+
246
+ Some steps you will need to follow:
247
+
248
+ - Allocate an AWS IAM role for your app.
249
+ - Create an IAM user for the role and pass credentials in standard AWS env vars (applications on Fargate get roles automatically).
250
+ - Choose a prefix for the parameters. By default, the prefix is `/environment_name/AppClassName/`. You can change it with backend parameters (prefer to use '/' as separator).
251
+ - Allow the role to read parameters from AWS SSM. Scope access by the prefix that you're going to use.
252
+ - If you will use encrypted parameters: create a KMS key and allow the role to decrypt using the key.
253
+ - Create parameters in Parameter Store. Use encryption for sensitive data like private keys and API credentials.
254
+
255
+ #### Usage with Go
256
+
257
+ You can reuse the same configuration in your Go services. For this, we developed a Go module that loads the same configuration tree into Go structs.
258
+
259
+ See [github.com/railsware/go-global](https://github.com/railsware/go-global) for further instructions.
260
+
261
+ #### Configuration examples
262
+
263
+ Backend setup:
149
264
 
150
265
  ```ruby
151
- > Global.reload!
266
+ # in config/environments/development.rb
267
+ # you don't need to go to Parameter Store for dev machines
268
+ Global.backend(:filesystem)
269
+
270
+ # in config/environments/production.rb
271
+ # enterprise grade protection for your secrets
272
+ Global.backend(:aws_parameter_store, app_name: 'my_big_app')
152
273
  ```
153
274
 
154
- ## JavaScript in Rails support
275
+ Create parameters:
155
276
 
156
- ### Configuration
277
+ ```
278
+ /production/my_big_app/basic_auth/username => "bill"
279
+ /production/my_big_app/basic_auth/password => "secret" # make sure to encrypt this one!
280
+ /production/my_big_app/api_endpoint => "https://api.myapp.com"
281
+ ```
282
+
283
+ Get configuration in the app:
157
284
 
158
285
  ```ruby
159
- Global.configure do |config|
160
- config.namespace = "JAVASCRIPT_OBJECT_NAME" # default Global
161
- config.except = ["LIST_OF_FILES_TO_EXCLUDE_ON_FRONT_END"] # default :all
162
- config.only = ["LIST_OF_FILES_TO_INCLUDE_ON_FRONT_END"] # default []
163
- end
286
+ # Encrypted parameters are automatically decrypted:
287
+ > Global.basic_auth.password
288
+ => "secret"
289
+ > Global.api_endpoint
290
+ => "https://api.myapp.com"
164
291
  ```
165
- By default all files are excluded due to security reasons. Don't include files which contain protected information like api keys or credentials.
166
292
 
167
- Require global file in `application.js`:
293
+ ### Google Cloud Secret Manager
168
294
 
169
- ``` js
170
- /*
171
- = require global-js
172
- */
173
- ```
295
+ Google Cloud Secret Manager allows you to store, manage, and access secrets as binary blobs or text strings. With the appropriate permissions, you can view the contents of the secret.
296
+ Google Cloud Secret Manager works well for storing configuration information such as database passwords, API keys, or TLS certificates needed by an application at runtime.
174
297
 
175
- ### Advanced Configuration
298
+ Refer to the [official documentation](https://cloud.google.com/secret-manager/docs) to set up the secret manager.
176
299
 
177
- In case you need different configurations for different parts of your application, you should create the files manually.
300
+ Some steps you will need to follow:
178
301
 
179
- If your application has `admin` and `application` namespace:
302
+ - Choose a prefix for the secret key name. By default, the prefix is `environment_name-AppClassName-`. You can change it with backend parameters (prefer to use '-' as separator).
180
303
 
181
- ```erb
182
- # app/assets/javascripts/admin/global.js.erb
183
- <%= Global.generate_js(namespace: "AdminSettings", only: %w(admin hosts)) %>
304
+ #### Configuration examples
184
305
 
185
- # app/assets/javascripts/admin.js.coffee
186
- #= require admin/global
187
- ```
306
+ Backend setup:
188
307
 
189
- ```erb
190
- # app/assets/javascripts/application/global.js.erb
191
- <%= Global.generate_js(namespace: "AppSettings", except: %w(admin credentials)) %>
308
+ ```ruby
309
+ # in config/environments/development.rb
310
+ # you don't need to go to Parameter Store for dev machines
311
+ Global.backend(:filesystem)
192
312
 
193
- # app/assets/javascripts/application.js.coffee
194
- #= require application/global
313
+ # in config/environments/production.rb
314
+ # enterprise grade protection for your secrets
315
+ Global.backend(:gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example')
195
316
  ```
196
317
 
197
- ### Usage
318
+ Create secrets:
198
319
 
199
- Config file example `global/hosts.yml`:
320
+ ```
321
+ prod-myapp-basic_auth-username => "bill"
322
+ prod-myapp-basic_auth-password => "secret"
323
+ prod-myapp-api_endpoint => "https://api.myapp.com"
324
+ ```
200
325
 
201
- ```yml
202
- development:
203
- web: localhost
204
- api: api.localhost
205
- production:
206
- web: myhost.com
207
- api: api.myhost.com
326
+ Get configuration in the app:
327
+
328
+ ```ruby
329
+ # Encrypted parameters are automatically decrypted:
330
+ > Global.basic_auth.password
331
+ => "secret"
332
+ > Global.api_endpoint
333
+ => "https://api.myapp.com"
208
334
  ```
209
- After that in development environment we have:
210
335
 
211
- ``` js
212
- Global.hosts.web
213
- => "localhost"
336
+ ### Reload configuration data
337
+
338
+ ```ruby
339
+ > Global.reload!
214
340
  ```
215
341
 
216
- And in production:
342
+ ## Using YAML configuration files with Rails Webpacker
343
+
344
+ If you use the `:filesystem` backend, you can reuse the same configuration files on the frontend:
345
+
346
+ Add [js-yaml](https://www.npmjs.com/package/js-yaml) npm package to `package.json` (use command `yarn add js-yaml`).
347
+
348
+ Then create a file at `config/webpacker/global/index.js` with the following:
349
+
350
+ ```js
351
+ const yaml = require('js-yaml')
352
+ const fs = require('fs')
353
+ const path = require('path')
354
+
355
+ const FILE_ENV_SPLIT = '.'
356
+ const YAML_EXT = '.yml'
217
357
 
218
- ``` js
219
- Global.hosts.web
220
- => "myhost.com"
358
+ let globalConfig = {
359
+ environment: null,
360
+ configDirectory: null
361
+ }
362
+
363
+ const globalConfigure = (options = {}) => {
364
+ globalConfig = Object.assign({}, globalConfig, options)
365
+ }
366
+
367
+ const getGlobalConfig = (key) => {
368
+ let config = {}
369
+ const filename = path.join(globalConfig.configDirectory, `${key}${YAML_EXT}`)
370
+ if (fs.existsSync(filename)) {
371
+ const configurations = yaml.safeLoad(fs.readFileSync(filename, 'utf8'))
372
+ config = Object.assign({}, config, configurations['default'] || {})
373
+ config = Object.assign({}, config, configurations[globalConfig.environment] || {})
374
+
375
+ const envFilename = path.join(globalConfig.configDirectory, `${key}${FILE_ENV_SPLIT}${globalConfig.environment}${YAML_EXT}`)
376
+ if (fs.existsSync(envFilename)) {
377
+ const envConfigurations = yaml.safeLoad(fs.readFileSync(envFilename, 'utf8'))
378
+ config = Object.assign({}, config, envConfigurations || {})
379
+ }
380
+ }
381
+ return config
382
+ }
383
+
384
+ module.exports = {
385
+ globalConfigure,
386
+ getGlobalConfig
387
+ }
388
+ ```
389
+
390
+ After this, modify file `config/webpacker/environment.js`:
391
+
392
+ ```js
393
+ const path = require('path')
394
+ const {environment} = require('@rails/webpacker')
395
+ const {globalConfigure, getGlobalConfig} = require('./global')
396
+
397
+ globalConfigure({
398
+ environment: process.env.RAILS_ENV || 'development',
399
+ configDirectory: path.resolve(__dirname, '../global')
400
+ })
401
+
402
+ const sentrySettings = getGlobalConfig('sentry')
403
+
404
+ environment.plugins.prepend('Environment', new webpack.EnvironmentPlugin({
405
+ GLOBAL_SENTRY_ENABLED: sentrySettings.enabled,
406
+ GLOBAL_SENTRY_JS_KEY: sentrySettings.js,
407
+ ...
408
+ }))
409
+
410
+ ...
411
+
412
+ module.exports = environment
413
+ ```
414
+
415
+ Now you can use these `process.env` keys in your code:
416
+
417
+ ```js
418
+ import {init} from '@sentry/browser'
419
+
420
+ if (process.env.GLOBAL_SENTRY_ENABLED) {
421
+ init({
422
+ dsn: process.env.GLOBAL_SENTRY_JS_KEY
423
+ })
424
+ }
221
425
  ```
222
426
 
223
427
  ## Contributing to global
@@ -230,7 +434,12 @@ Global.hosts.web
230
434
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
231
435
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
232
436
 
233
- ## Copyright
437
+ 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/railsware/global/blob/master/CODE_OF_CONDUCT.md).
438
+
439
+ ## License
440
+
441
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
234
442
 
235
- Copyright (c) Railsware LLC. See LICENSE.txt for further details.
443
+ ## Code of Conduct
236
444
 
445
+ Everyone interacting in the Global project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/railsware/global/blob/master/CODE_OF_CONDUCT.md).