global 1.1.0 → 2.0.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
2
  SHA256:
3
- metadata.gz: b01380c2ead8dd05766d2d01dff1fbc24aff74ab22d6cdca72b6d5bcf92409e8
4
- data.tar.gz: 596fd34a00183fca92f01cab9e6a0214275036abc93accea2f88f4646a764448
3
+ metadata.gz: d82e24b3a7c94f65e370d1b16142e028d3acf1ce3fe8064e9e9fcb9e4683d46e
4
+ data.tar.gz: 809e1b6ac4e2f0ada443202b1d80ec7d663488515f682079cd07bc02335983c4
5
5
  SHA512:
6
- metadata.gz: 6fa1a2e2ebc3092e3b61a4c2ce7104db18947c1fb1a9a73b5cfe2bceecfb575485c9cf426a841f63f72b08db84cee51d0fec3eb7d4f4db629d3d9b3edde13252
7
- data.tar.gz: fee130c0b00643657da8f8bc191a86c111e80a8da40ac1b62c0d34765d775e70ac7393078213425987af1378bcaac02a8f245dc66804aa4b094a2f1f393653fb
6
+ metadata.gz: b290b4951da9d199d64ec8a27bdf630be5691ec1af0829d31e01872c1260893e2a3626fcc55a70f9ac816192279fbf04a4a2823dd770127808bd63b62ad8016d
7
+ data.tar.gz: afa4586a51919a0d483dbcd01e5fd027cd6a79aebaea070c544c53f4838ccbbece9312536d40ed475adf1cc207ef7864937639baa60de7bab1918de3a081944a
@@ -1,3 +1,7 @@
1
+ Metrics/MethodLength:
2
+ Enabled: true
3
+ Max: 11
4
+
1
5
  Layout/EmptyLinesAroundBlockBody:
2
6
  Enabled: false
3
7
 
@@ -29,10 +33,16 @@ Layout/MultilineMethodCallIndentation:
29
33
  Enabled: true
30
34
  EnforcedStyle: indented
31
35
 
32
- Layout/AlignHash:
36
+ Layout/HashAlignment:
33
37
  Enabled: true
34
38
  EnforcedLastArgumentHashStyle: always_ignore
35
39
 
40
+ Lint/RaiseException:
41
+ Enabled: true
42
+
43
+ Lint/StructNewOverride:
44
+ Enabled: true
45
+
36
46
  Style/RaiseArgs:
37
47
  EnforcedStyle: compact
38
48
 
@@ -43,12 +53,21 @@ Style/FrozenStringLiteralComment:
43
53
  Enabled: true
44
54
  EnforcedStyle: always
45
55
 
56
+ Style/HashEachMethods:
57
+ Enabled: true
58
+
59
+ Style/HashTransformKeys:
60
+ Enabled: true
61
+
62
+ Style/HashTransformValues:
63
+ Enabled: true
64
+
46
65
  Style/RegexpLiteral:
47
66
  Enabled: true
48
67
  EnforcedStyle: slashes
49
68
  AllowInnerSlashes: false
50
69
 
51
- Layout/IndentHash:
70
+ Layout/FirstHashElementIndentation:
52
71
  EnforcedStyle: consistent
53
72
 
54
73
  Style/Documentation:
@@ -56,36 +75,36 @@ Style/Documentation:
56
75
 
57
76
  Style/SafeNavigation:
58
77
  Enabled: true
59
- Whitelist:
78
+ AllowedMethods:
60
79
  - present?
61
80
  - blank?
62
81
  - presence
63
82
 
64
83
  Lint/AmbiguousBlockAssociation:
65
84
  Exclude:
66
- - 'spec/**/*'
85
+ - "spec/**/*"
67
86
 
68
87
  Naming/PredicateName:
69
88
  Exclude:
70
- - 'spec/**/*'
89
+ - "spec/**/*"
71
90
 
72
91
  Style/NumericPredicate:
73
92
  Exclude:
74
- - 'spec/**/*'
93
+ - "spec/**/*"
75
94
 
76
95
  Metrics/BlockLength:
77
96
  Exclude:
78
- - 'spec/**/*'
97
+ - "spec/**/*"
79
98
 
80
- Metrics/LineLength:
99
+ Layout/LineLength:
81
100
  Max: 120
82
101
  Exclude:
83
- - 'spec/**/*'
102
+ - "spec/**/*"
84
103
 
85
104
  Metrics/AbcSize:
86
105
  Max: 22
87
106
  Exclude:
88
- - 'spec/**/*'
107
+ - "spec/**/*"
89
108
 
90
109
  Style/ModuleFunction:
91
110
  EnforcedStyle: extend_self
@@ -1 +1 @@
1
- 2.5.1
1
+ 2.6.6
@@ -1,27 +1,21 @@
1
1
  language: ruby
2
+ os: linux
3
+ dist: bionic
2
4
 
3
5
  cache:
4
6
  bundler: true
5
7
 
6
8
  rvm:
7
- - 2.2
8
- - 2.3
9
9
  - 2.4
10
10
  - 2.5
11
- - jruby-19mode
11
+ - 2.6
12
+ - 2.7
12
13
  - ruby-head
13
14
  - jruby-head
14
15
 
15
16
  notifications:
16
17
  email: false
17
18
 
18
- sudo: false
19
-
20
- branches:
21
- only:
22
- - master
23
- - development
24
-
25
19
  matrix:
26
20
  allow_failures:
27
21
  - rvm: ruby-head
@@ -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/README.md CHANGED
@@ -1,6 +1,8 @@
1
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)
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,41 +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"
18
- > Global.yaml_whitelist_classes = [] # optional configuration
22
+ > Global.backend(:filesystem, environment: "YOUR_ENV_HERE", directory: "PATH_TO_DIRECTORY_WITH_FILES")
19
23
  ```
20
24
 
21
25
  Or you can use `configure` block:
22
26
 
23
27
  ```ruby
24
28
  Global.configure do |config|
25
- config.environment = "YOUR_ENV_HERE"
26
- config.config_directory = "PATH_TO_DIRECTORY_WITH_FILES"
27
- config.yaml_whitelist_classes = [] # optional configuration
29
+ config.backend :filesystem, environment: "YOUR_ENV_HERE", directory: "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'
28
33
  end
29
34
  ```
30
35
 
31
- 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:
32
43
 
33
44
  ```ruby
34
45
  Global.configure do |config|
35
- config.environment = Rails.env.to_s
36
- config.config_directory = Rails.root.join('config/global').to_s
37
- config.yaml_whitelist_classes = [] # optional configuration
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' } }
38
48
  end
49
+
50
+ Global.credentials.hostname # => 'api.com'
51
+ Global.credentials.username # => 'xxx'
52
+ Global.credentials.password # => 'yyy'
39
53
  ```
40
54
 
55
+ For Rails, put initialization into `config/initializers/global.rb`.
56
+
57
+ There are some sensible defaults, check your backend class for documentation.
58
+
59
+ ```ruby
60
+ Global.configure do |config|
61
+ config.backend :filesystem
62
+ end
63
+ ```
64
+
65
+ ### Filesystem storage
66
+
41
67
  The `yaml_whitelist_classes` configuration allows you to deserialize other classes from your `.yml`
42
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
+
43
77
  ## Usage
44
78
 
45
- ### General
79
+ ### Filesystem
46
80
 
47
- Config file `config/global/hosts.yml`:
81
+ For file `config/global/hosts.yml`:
48
82
 
49
83
  ```yml
50
84
  test:
@@ -84,9 +118,11 @@ Global.validations.regexp.email === 'mail@example.com'
84
118
  => true
85
119
  ```
86
120
 
87
- ### Namespacing
121
+ #### Per-environment sections
122
+
123
+ You can define environment sections at the top level of every individual YAML file
88
124
 
89
- Config file `config/global/web/basic_auth.yml` with:
125
+ For example, having a config file `config/global/web/basic_auth.yml` with:
90
126
 
91
127
  ```yml
92
128
  test:
@@ -100,7 +136,7 @@ production:
100
136
  password: supersecret
101
137
  ```
102
138
 
103
- After that in development environment we have:
139
+ You get the correct configuration in development
104
140
 
105
141
  ```ruby
106
142
  > Global.web.basic_auth
@@ -109,7 +145,7 @@ After that in development environment we have:
109
145
  => "development_user"
110
146
  ```
111
147
 
112
- ### Default section
148
+ #### Default section
113
149
 
114
150
  Config file example:
115
151
 
@@ -124,9 +160,10 @@ production:
124
160
 
125
161
  Data from the default section is used until it's overridden in a specific environment.
126
162
 
127
- ### Nested configurations
163
+ #### Nested configurations
128
164
 
129
165
  Config file `global/nested.yml` with:
166
+
130
167
  ```yml
131
168
  test:
132
169
  group:
@@ -146,7 +183,7 @@ Nested options can then be accessed as follows:
146
183
  => "development value"
147
184
  ```
148
185
 
149
- ### Environment files
186
+ #### Environment files
150
187
 
151
188
  Config file `global/aws.yml` with:
152
189
  ```yml
@@ -180,7 +217,7 @@ Provide such configuration on `Global.environment = 'production'` environment:
180
217
 
181
218
  **Warning**: files with dot(s) in name will be skipped by Global (except this env files).
182
219
 
183
- ### ERB support
220
+ #### ERB support
184
221
 
185
222
  Config file `global/file_name.yml` with:
186
223
 
@@ -200,79 +237,185 @@ As a result, in the development environment we have:
200
237
  => 4
201
238
  ```
202
239
 
203
- ### 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
+ #### Configuration examples
256
+
257
+ Backend setup:
204
258
 
205
259
  ```ruby
206
- > Global.reload!
260
+ # in config/environments/development.rb
261
+ # you don't need to go to Parameter Store for dev machines
262
+ Global.backend(:filesystem)
263
+
264
+ # in config/environments/production.rb
265
+ # enterprise grade protection for your secrets
266
+ Global.backend(:aws_parameter_store, app_name: 'my_big_app')
207
267
  ```
208
268
 
209
- ## JavaScript in Rails support
269
+ Create parameters:
210
270
 
211
- ### Configuration
271
+ ```
272
+ /production/my_big_app/basic_auth/username => "bill"
273
+ /production/my_big_app/basic_auth/password => "secret" # make sure to encrypt this one!
274
+ /production/my_big_app/api_endpoint => "https://api.myapp.com"
275
+ ```
276
+
277
+ Get configuration in the app:
212
278
 
213
279
  ```ruby
214
- Global.configure do |config|
215
- config.namespace = "JAVASCRIPT_OBJECT_NAME" # default Global
216
- config.except = ["LIST_OF_FILES_TO_EXCLUDE_ON_FRONT_END"] # default :all
217
- config.only = ["LIST_OF_FILES_TO_INCLUDE_ON_FRONT_END"] # default []
218
- end
280
+ # Encrypted parameters are automatically decrypted:
281
+ > Global.basic_auth.password
282
+ => "secret"
283
+ > Global.api_endpoint
284
+ => "https://api.myapp.com"
219
285
  ```
220
- By default all files are excluded due to security reasons. Don't include files which contain protected information like api keys or credentials.
221
286
 
222
- Require global file in `application.js`:
287
+ ### Google Cloud Secret Manager
223
288
 
224
- ``` js
225
- /*
226
- = require global-js
227
- */
228
- ```
289
+ 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.
290
+ 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.
291
+
292
+ Refer to the [official documentation](https://cloud.google.com/secret-manager/docs) to set up the secret manager.
293
+
294
+ Some steps you will need to follow:
229
295
 
230
- ### Advanced Configuration
296
+ - 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).
231
297
 
232
- In case you need different configurations for different parts of your application, you should create the files manually.
298
+ #### Configuration examples
233
299
 
234
- If your application has `admin` and `application` namespace:
300
+ Backend setup:
235
301
 
236
- ```erb
237
- # app/assets/javascripts/admin/global.js.erb
238
- <%= Global.generate_js(namespace: "AdminSettings", only: %w(admin hosts)) %>
302
+ ```ruby
303
+ # in config/environments/development.rb
304
+ # you don't need to go to Parameter Store for dev machines
305
+ Global.backend(:filesystem)
239
306
 
240
- # app/assets/javascripts/admin.js.coffee
241
- #= require admin/global
307
+ # in config/environments/production.rb
308
+ # enterprise grade protection for your secrets
309
+ Global.backend(:gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example')
242
310
  ```
243
311
 
244
- ```erb
245
- # app/assets/javascripts/application/global.js.erb
246
- <%= Global.generate_js(namespace: "AppSettings", except: %w(admin credentials)) %>
312
+ Create secrets:
247
313
 
248
- # app/assets/javascripts/application.js.coffee
249
- #= require application/global
314
+ ```
315
+ prod-myapp-basic_auth-username => "bill"
316
+ prod-myapp-basic_auth-password => "secret"
317
+ prod-myapp-api_endpoint => "https://api.myapp.com"
250
318
  ```
251
319
 
252
- ### Usage
320
+ Get configuration in the app:
253
321
 
254
- Config file example `global/hosts.yml`:
322
+ ```ruby
323
+ # Encrypted parameters are automatically decrypted:
324
+ > Global.basic_auth.password
325
+ => "secret"
326
+ > Global.api_endpoint
327
+ => "https://api.myapp.com"
328
+ ```
255
329
 
256
- ```yml
257
- development:
258
- web: localhost
259
- api: api.localhost
260
- production:
261
- web: myhost.com
262
- api: api.myhost.com
330
+ ### Reload configuration data
331
+
332
+ ```ruby
333
+ > Global.reload!
263
334
  ```
264
- After that in development environment we have:
265
335
 
266
- ``` js
267
- Global.hosts.web
268
- => "localhost"
336
+ ## Using YAML configuration files with Rails Webpacker
337
+
338
+ If you use the `:filesystem` backend, you can reuse the same configuration files on the frontend:
339
+
340
+ Add [js-yaml](https://www.npmjs.com/package/js-yaml) npm package to `package.json` (use command `yarn add js-yaml`).
341
+
342
+ Then create a file at `config/webpacker/global/index.js` with the following:
343
+
344
+ ```js
345
+ const yaml = require('js-yaml')
346
+ const fs = require('fs')
347
+ const path = require('path')
348
+
349
+ const FILE_ENV_SPLIT = '.'
350
+ const YAML_EXT = '.yml'
351
+
352
+ let globalConfig = {
353
+ environment: null,
354
+ configDirectory: null
355
+ }
356
+
357
+ const globalConfigure = (options = {}) => {
358
+ globalConfig = Object.assign({}, globalConfig, options)
359
+ }
360
+
361
+ const getGlobalConfig = (key) => {
362
+ let config = {}
363
+ const filename = path.join(globalConfig.configDirectory, `${key}${YAML_EXT}`)
364
+ if (fs.existsSync(filename)) {
365
+ const configurations = yaml.safeLoad(fs.readFileSync(filename, 'utf8'))
366
+ config = Object.assign({}, config, configurations['default'] || {})
367
+ config = Object.assign({}, config, configurations[globalConfig.environment] || {})
368
+
369
+ const envFilename = path.join(globalConfig.configDirectory, `${key}${FILE_ENV_SPLIT}${globalConfig.environment}${YAML_EXT}`)
370
+ if (fs.existsSync(envFilename)) {
371
+ const envConfigurations = yaml.safeLoad(fs.readFileSync(envFilename, 'utf8'))
372
+ config = Object.assign({}, config, envConfigurations || {})
373
+ }
374
+ }
375
+ return config
376
+ }
377
+
378
+ module.exports = {
379
+ globalConfigure,
380
+ getGlobalConfig
381
+ }
382
+ ```
383
+
384
+ After this, modify file `config/webpacker/environment.js`:
385
+
386
+ ```js
387
+ const path = require('path')
388
+ const {environment} = require('@rails/webpacker')
389
+ const {globalConfigure, getGlobalConfig} = require('./global')
390
+
391
+ globalConfigure({
392
+ environment: process.env.RAILS_ENV || 'development',
393
+ configDirectory: path.resolve(__dirname, '../global')
394
+ })
395
+
396
+ const sentrySettings = getGlobalConfig('sentry')
397
+
398
+ environment.plugins.prepend('Environment', new webpack.EnvironmentPlugin({
399
+ GLOBAL_SENTRY_ENABLED: sentrySettings.enabled,
400
+ GLOBAL_SENTRY_JS_KEY: sentrySettings.js,
401
+ ...
402
+ }))
403
+
404
+ ...
405
+
406
+ module.exports = environment
269
407
  ```
270
408
 
271
- And in production:
409
+ Now you can use these `process.env` keys in your code:
272
410
 
273
- ``` js
274
- Global.hosts.web
275
- => "myhost.com"
411
+ ```js
412
+ import {init} from '@sentry/browser'
413
+
414
+ if (process.env.GLOBAL_SENTRY_ENABLED) {
415
+ init({
416
+ dsn: process.env.GLOBAL_SENTRY_JS_KEY
417
+ })
418
+ }
276
419
  ```
277
420
 
278
421
  ## Contributing to global
@@ -285,6 +428,12 @@ Global.hosts.web
285
428
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
286
429
  * 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.
287
430
 
288
- ## Copyright
431
+ 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).
432
+
433
+ ## License
434
+
435
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
436
+
437
+ ## Code of Conduct
289
438
 
290
- Copyright (c) Railsware LLC. See LICENSE.txt for further details.
439
+ 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).