Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,16 @@ The settings in the `shipit.yml` file relate to the different things you can do
* [Custom Tasks](#custom-tasks) (`tasks`)
* [Custom links](#custom-links) (`links`)
* [Review Process](#review-process) (`review.checklist`, `review.monitoring`, `review.checks`)
* [Inherit From](#inherit-from)(`inherit_from`)

All the settings in `shipit.yml` are optional. Most applications can be deployed from Shipit without any configuration.

Also, if your repository is deployed different ways depending on the environment, you can have an alternative `shipit.yml` by including the environment name.

For example for a stack like: `my-org/my-repo/staging`, `shipit.staging.yml` will have priority over `shipit.yml`.

In order to reduce duplication across different environment specific files, you can specify an `inherit_from` key in your relevant `shipit.yml` file. This key expects a string of the file name to inherit from. If this key is specified, a deep-merge will be performed on the file therein, overwriting any duplicated values from the parent. See [Inherit From](#inherit-from)(`inherit_From`) for example.

Lastly, if you override the `app_name` configuration in your Shipit deployment, `yourapp.yml` and `yourapp.staging.yml` will work.

* * *
Expand Down Expand Up @@ -613,6 +616,42 @@ review:
- bundle exec rake db:migrate:status
```

<h3 id="inherit-from">Inherit From</h3>

If the `inherit_from` key is specified, a deep-merge will be performed on the file therein, overwriting any duplicated values from the parent. Keys may be chained across files. Example:

``` yaml
# shipit.production.yml
inherit_from: shipit.staging.yml

machine:
environment:
PUBLIC: true
```

``` yaml
# shipit.staging.yml
inherit_from: shipit.yml

deploy:
override:
- ./some_deployment_process.sh ${PUBLIC}
```

``` yaml
# shipit.yml

machine:
environment:
TEST: true
PUBLIC: false
```

Loading 'shipit.production.yml' would result in:
```rb
{"machine"=>{"environment"=>{"TEST"=>true, "PUBLIC"=>true}}, "deploy"=>{"override"=>["./some_deployment_process.sh ${PUBLIC}"]}}
```

<h3 id="shell-commands-timeout">Shell commands timeout</h3>

All the shell commands can take an optional `timeout` parameter. This is the value in seconds that a command can be inactive before Shipit will terminate the task.
Expand Down
17 changes: 16 additions & 1 deletion app/models/shipit/deploy_spec/file_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def load_config
return { 'deploy' => { 'pre' => [shipit_not_obeying_bare_file_echo_command, 'exit 1'] } }
end

read_config(config_file_path)
config_obj = read_config(config_file_path)
build_config(config_file_path, config_obj)
end

def shipit_file_names_in_priority_order
Expand Down Expand Up @@ -136,6 +137,20 @@ def app_name
@app_name ||= Shipit.app_name.downcase
end

SHIPIT_CONFIG_INHERIT_FROM_KEY = "inherit_from"
def build_config(path, config_obj)
return config_obj if config_obj.blank? || !config_obj.key?(SHIPIT_CONFIG_INHERIT_FROM_KEY)

inherits_from_path = path.dirname.join(config_obj.delete(SHIPIT_CONFIG_INHERIT_FROM_KEY))
if inherits_from_path.exist?
Comment on lines +144 to +145
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: does a non existing path should noop or result in an error?

The problem is kinda always the same though, we don't have a good way of reporting shipit.yml errors, so perhaps nooping is the reasonable thing to do.

inherits_config_obj = read_config(inherits_from_path)
config_obj = inherits_config_obj.deep_merge(config_obj)
path = inherits_from_path
end

build_config(path, config_obj)
end

def read_config(path)
SafeYAML.load(path.read) if path.exist?
end
Expand Down
38 changes: 38 additions & 0 deletions test/models/shipit/deploy_spec/file_system_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,35 @@ class FileSystemTest < ActiveSupport::TestCase
assert loaded_config["deploy"]["pre"].include?('exit 1')
end

test '#load_config builds proper config if inherit_from is present' do
Shipit.expects(:respect_bare_shipit_file?).returns(true).at_least_once
stack = shipit_stacks(:shipit)
deploy_spec = Shipit::DeploySpec::FileSystem.new(Dir.tmpdir, stack)
deploy_spec.expects(:config_file_path).returns(Pathname.new(Dir.tmpdir) + '/shipit_1.yml').at_least_once
deploy_spec.expects(:read_config).returns(SafeYAML.load(deploy_spec_inherit_from_yaml), SafeYAML.load(deploy_spec_yaml)).at_least_once
Pathname.any_instance.stubs(:exist?).returns(true)
loaded_config = deploy_spec.send(:load_config)
assert loaded_config.key?("deploy")
assert loaded_config["deploy"].key?("pre")
assert loaded_config["deploy"]["pre"].include?("test 2")
assert loaded_config["deploy"]["override"].include?("test 11")
assert_not loaded_config.include?(Shipit::DeploySpec::FileSystem::SHIPIT_CONFIG_INHERIT_FROM_KEY)
end

test '#load_config builds valid config if inherit_from path is missing' do
Shipit.expects(:respect_bare_shipit_file?).returns(true).at_least_once
stack = shipit_stacks(:shipit)
deploy_spec = Shipit::DeploySpec::FileSystem.new(Dir.tmpdir, stack)
deploy_spec.expects(:config_file_path).returns(Pathname.new(Dir.tmpdir) + '/shipit_1.yml').at_least_once
deploy_spec.expects(:read_config).returns(SafeYAML.load(deploy_spec_inherit_from_yaml)).at_least_once
Pathname.any_instance.stubs(:exist?).returns(false)
loaded_config = deploy_spec.send(:load_config)
assert loaded_config.key?("deploy")
assert_not loaded_config["deploy"].include?("pre")
assert loaded_config["deploy"]["override"].include?("test 11")
assert_not loaded_config.include?(Shipit::DeploySpec::FileSystem::SHIPIT_CONFIG_INHERIT_FROM_KEY)
end

def deploy_spec_yaml
<<~EOYAML
deploy:
Expand All @@ -73,6 +102,15 @@ def deploy_spec_yaml
EOYAML
end

def deploy_spec_inherit_from_yaml
<<~EOYAML
inherit_from: shipit.yml
deploy:
override:
- test 11
EOYAML
end

def deploy_spec_missing_deploy_yaml
<<~EOYAML
production_platform:
Expand Down