r10k 3.7.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.mkd +7 -0
- data/CODEOWNERS +1 -1
- data/doc/dynamic-environments/configuration.mkd +25 -0
- data/doc/dynamic-environments/usage.mkd +5 -4
- data/lib/r10k/action/deploy/environment.rb +2 -0
- data/lib/r10k/action/deploy/module.rb +3 -1
- data/lib/r10k/action/runner.rb +33 -0
- data/lib/r10k/cli/deploy.rb +8 -4
- data/lib/r10k/cli/puppetfile.rb +5 -5
- data/lib/r10k/environment/base.rb +7 -0
- data/lib/r10k/environment/with_modules.rb +27 -19
- data/lib/r10k/git.rb +1 -0
- data/lib/r10k/git/rugged/credentials.rb +32 -2
- data/lib/r10k/initializers.rb +1 -0
- data/lib/r10k/module/forge.rb +1 -1
- data/lib/r10k/module/git.rb +16 -3
- data/lib/r10k/puppetfile.rb +14 -16
- data/lib/r10k/settings.rb +12 -1
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +51 -31
- data/spec/fixtures/unit/action/r10k_creds.yaml +9 -0
- data/spec/unit/action/deploy/environment_spec.rb +34 -2
- data/spec/unit/action/deploy/module_spec.rb +29 -3
- data/spec/unit/action/runner_spec.rb +48 -1
- data/spec/unit/environment/git_spec.rb +3 -2
- data/spec/unit/environment/with_modules_spec.rb +74 -0
- data/spec/unit/git/rugged/credentials_spec.rb +68 -1
- data/spec/unit/module/git_spec.rb +55 -0
- data/spec/unit/puppetfile_spec.rb +24 -35
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dddce45b116f972f8efe10ad99c330b60186cfbcdb8747fbab2edc37d8634efb
|
4
|
+
data.tar.gz: 26ac288406c3e4fb3862aa5ca64aba4b7ed102dcc407ba59d364f094b1491480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbe3bd1fbc2ca1f1fee87fb5ce9e613baf9783cd1a728f50e0de65718a50f7321609458a1e60817fee94ec32464b95ebf3ecf32dde5c065ccabe369fdc2c6b0d
|
7
|
+
data.tar.gz: 1d33d1f5772a71c0e6dae7b36730a810b8d2bc59e8ec71a4639b3e4f38a5394396dd62270a63032619c2a3cadeb1e1066a0242e8d9b4b1436933660aec806eab
|
data/CHANGELOG.mkd
CHANGED
@@ -4,6 +4,13 @@ CHANGELOG
|
|
4
4
|
Unreleased
|
5
5
|
----------
|
6
6
|
|
7
|
+
3.8.0
|
8
|
+
-----
|
9
|
+
|
10
|
+
- When a forge module fails name validation the offending name will now be printed in the error message. [#1126](https://github.com/puppetlabs/r10k/pull/1126)
|
11
|
+
- Module ref resolution will now fall back to the normal default branch if the default branch override cannot be resolved. [#1122](https://github.com/puppetlabs/r10k/pull/1122)
|
12
|
+
- Experimental feature change: conflicts between environment-defined modules and Puppetfile-defined modules now default to logging a warning and deploying the environment module version, overriding the Puppetfile. Previously, conflicts would result in an error. The behavior is now configurable via the `module_conflicts` environment setting [#1107](https://github.com/puppetlabs/r10k/pull/1107)
|
13
|
+
|
7
14
|
3.7.0
|
8
15
|
-----
|
9
16
|
|
data/CODEOWNERS
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
* @puppetlabs/puppetserver-maintainers
|
1
|
+
* @puppetlabs/puppetserver-maintainers
|
2
2
|
/docker/ @puppetlabs/pupperware
|
@@ -673,6 +673,31 @@ modules:
|
|
673
673
|
ref: 62d07f2
|
674
674
|
```
|
675
675
|
|
676
|
+
#### Puppetfile module conflicts
|
677
|
+
|
678
|
+
When a module is defined in an environment and also in a Puppetfile, the default behavior is for the environment definition of the module to take precedence, a warning to be logged, and the Puppetfile definition to be ignored. The behavior is configurable to optionally skip the warning, or allow a hard failure instead. Use the `module_conflicts` option in an environment definition to control this.
|
679
|
+
|
680
|
+
Available `module_conflicts` options:
|
681
|
+
|
682
|
+
* `override_and_warn` (default): the version of the module defined by the environment will be used, and the version defined in the Puppetfile will be ignored. A warning will be printed.
|
683
|
+
* `override`: the version of the module defined by the environment will be used, and the version defined in the Puppetfile will be ignored.
|
684
|
+
* `error`: an error will be raised alerting the user to the conflict. The environment will not be deployed.
|
685
|
+
|
686
|
+
```yaml
|
687
|
+
# production.yaml
|
688
|
+
---
|
689
|
+
type: git
|
690
|
+
remote: git@github.com:puppetlabs/control-repo.git
|
691
|
+
ref: 8820892
|
692
|
+
module_conflicts: override_puppetfile_and_warn
|
693
|
+
modules:
|
694
|
+
puppetlabs-stdlib: 6.0.0
|
695
|
+
puppetlabs-concat: 6.1.0
|
696
|
+
reidmv-xampl:
|
697
|
+
git: https://github.com/reidmv/reidmv-xampl.git
|
698
|
+
ref: 62d07f2
|
699
|
+
```
|
700
|
+
|
676
701
|
### Bare Environment Type
|
677
702
|
|
678
703
|
A "control repository" typically contains a hiera.yaml, an environment.conf, a manifests/site.pp file, and a few other things. However, none of these are strictly necessary for an environment to be functional if modules can be deployed to it.
|
@@ -66,11 +66,12 @@ Update a single environment and specify a default branch override:
|
|
66
66
|
|
67
67
|
r10k deploy environment my_working_environment --puppetfile --default-branch-override default_branch_override
|
68
68
|
|
69
|
-
This will update the given environment and update all contained modules,
|
70
|
-
the :default_branch entry in the Puppetfile of each module.
|
69
|
+
This will update the given environment and update all contained modules, overriding
|
70
|
+
the :default_branch entry in the Puppetfile of each module. If the specified override branch is not
|
71
|
+
found, it will fall back to the normal default branch and attempt to use that. This is used primarily to allow
|
71
72
|
automated r10k solutions using the control_branch pattern with a temporary branch deployment to
|
72
|
-
ensure the deployment is pushed to the correct module repository branch. Note that the :default_branch
|
73
|
-
|
73
|
+
ensure the deployment is pushed to the correct module repository branch. Note that the :default_branch and its
|
74
|
+
override are only ever used if the specific desired ref cannot be located.
|
74
75
|
|
75
76
|
### Deploying modules
|
76
77
|
|
data/lib/r10k/action/runner.rb
CHANGED
@@ -55,6 +55,10 @@ module R10K
|
|
55
55
|
newval
|
56
56
|
end
|
57
57
|
|
58
|
+
# Credentials from the CLI override both the global and per-repo
|
59
|
+
# credentials from the config, and so need to be handled specially
|
60
|
+
with_overrides = add_credential_overrides(with_overrides)
|
61
|
+
|
58
62
|
@settings = R10K::Settings.global_settings.evaluate(with_overrides)
|
59
63
|
|
60
64
|
R10K::Initializers::GlobalInitializer.new(@settings).call
|
@@ -92,6 +96,35 @@ module R10K
|
|
92
96
|
|
93
97
|
results
|
94
98
|
end
|
99
|
+
|
100
|
+
def add_credential_overrides(overrides)
|
101
|
+
sshkey_path = @opts[:'private-key']
|
102
|
+
token_path = @opts[:'oauth-token']
|
103
|
+
|
104
|
+
if sshkey_path && token_path
|
105
|
+
raise R10K::Error, "Cannot specify both an SSH key and a token to use with this deploy."
|
106
|
+
end
|
107
|
+
|
108
|
+
if sshkey_path
|
109
|
+
overrides[:git] ||= {}
|
110
|
+
overrides[:git][:private_key] = sshkey_path
|
111
|
+
if repo_settings = overrides[:git][:repositories]
|
112
|
+
repo_settings.each do |repo|
|
113
|
+
repo[:private_key] = sshkey_path
|
114
|
+
end
|
115
|
+
end
|
116
|
+
elsif token_path
|
117
|
+
overrides[:git] ||= {}
|
118
|
+
overrides[:git][:oauth_token] = token_path
|
119
|
+
if repo_settings = overrides[:git][:repositories]
|
120
|
+
repo_settings.each do |repo|
|
121
|
+
repo[:oauth_token] = token_path
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
overrides
|
127
|
+
end
|
95
128
|
end
|
96
129
|
end
|
97
130
|
end
|
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -21,7 +21,7 @@ module R10K::CLI
|
|
21
21
|
(https://puppet.com/docs/puppet/latest/environments_about.html).
|
22
22
|
DESCRIPTION
|
23
23
|
|
24
|
-
|
24
|
+
option nil, :cachedir, 'Specify a cachedir, overriding the value in config', argument: :required
|
25
25
|
flag nil, :'no-force', 'Prevent the overwriting of local module modifications'
|
26
26
|
flag nil, :'generate-types', 'Run `puppet generate types` after updating an environment'
|
27
27
|
option nil, :'puppet-path', 'Path to puppet executable', argument: :required do |value, cmd|
|
@@ -32,6 +32,8 @@ module R10K::CLI
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
option nil, :'puppet-conf', 'Path to puppet.conf', argument: :required
|
35
|
+
option nil, :'private-key', 'Path to SSH key to use when cloning. Only valid with rugged provider', argument: :required
|
36
|
+
option nil, :'oauth-token', 'Path to OAuth token to use when cloning. Only valid with rugged provider', argument: :required
|
35
37
|
|
36
38
|
run do |opts, args, cmd|
|
37
39
|
puts cmd.help(:verbose => opts[:verbose])
|
@@ -62,7 +64,8 @@ scheduled. On subsequent deployments, Puppetfile deployment will default to off.
|
|
62
64
|
DESCRIPTION
|
63
65
|
|
64
66
|
flag :p, :puppetfile, 'Deploy modules from a puppetfile'
|
65
|
-
|
67
|
+
option nil, :'default-branch-override', 'Specify a branchname to override the default branch in the puppetfile',
|
68
|
+
argument: :required
|
66
69
|
|
67
70
|
runner R10K::Action::CriRunner.wrap(R10K::Action::Deploy::Environment)
|
68
71
|
end
|
@@ -82,7 +85,7 @@ It will load the Puppetfile configurations out of all environments, and will
|
|
82
85
|
try to deploy the given module names in all environments.
|
83
86
|
DESCRIPTION
|
84
87
|
|
85
|
-
|
88
|
+
option :e, :environment, 'Update the modules in the given environment', argument: :required
|
86
89
|
|
87
90
|
runner R10K::Action::CriRunner.wrap(R10K::Action::Deploy::Module)
|
88
91
|
end
|
@@ -100,7 +103,8 @@ try to deploy the given module names in all environments.
|
|
100
103
|
flag :p, :puppetfile, 'Display Puppetfile modules'
|
101
104
|
flag nil, :detail, 'Display detailed information'
|
102
105
|
flag nil, :fetch, 'Update available environment lists from all remote sources'
|
103
|
-
|
106
|
+
option nil, :format, 'Display output in a specific format. Valid values: json, yaml. Default: yaml',
|
107
|
+
argument: :required
|
104
108
|
|
105
109
|
runner R10K::Action::CriRunner.wrap(R10K::Action::Deploy::Display)
|
106
110
|
end
|
data/lib/r10k/cli/puppetfile.rb
CHANGED
@@ -30,8 +30,8 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
30
30
|
name 'install'
|
31
31
|
usage 'install'
|
32
32
|
summary 'Install all modules from a Puppetfile'
|
33
|
-
|
34
|
-
|
33
|
+
option nil, :moduledir, 'Path to install modules to', argument: :required
|
34
|
+
option nil, :puppetfile, 'Path to puppetfile', argument: :required
|
35
35
|
flag nil, :force, 'Force locally changed files to be overwritten'
|
36
36
|
runner R10K::Action::Puppetfile::CriRunner.wrap(R10K::Action::Puppetfile::Install)
|
37
37
|
end
|
@@ -45,7 +45,7 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
45
45
|
usage 'check'
|
46
46
|
summary 'Try and load the Puppetfile to verify the syntax is correct.'
|
47
47
|
|
48
|
-
|
48
|
+
option nil, :puppetfile, 'Path to Puppetfile', argument: :required
|
49
49
|
runner R10K::Action::Puppetfile::CriRunner.wrap(R10K::Action::Puppetfile::Check)
|
50
50
|
end
|
51
51
|
end
|
@@ -58,8 +58,8 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
58
58
|
usage 'purge'
|
59
59
|
summary 'Purge unmanaged modules from a Puppetfile managed directory'
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
option nil, :moduledir, 'Path to install modules to', argument: :required
|
62
|
+
option nil, :puppetfile, 'Path to Puppetfile', argument: :required
|
63
63
|
runner R10K::Action::Puppetfile::CriRunner.wrap(R10K::Action::Puppetfile::Purge)
|
64
64
|
end
|
65
65
|
end
|
@@ -103,6 +103,13 @@ class R10K::Environment::Base
|
|
103
103
|
@puppetfile.modules
|
104
104
|
end
|
105
105
|
|
106
|
+
# @return [Array<R10K::Module::Base>] Whether or not the given module
|
107
|
+
# conflicts with any modules already defined in the r10k environment
|
108
|
+
# object.
|
109
|
+
def module_conflicts?(mod)
|
110
|
+
false
|
111
|
+
end
|
112
|
+
|
106
113
|
def accept(visitor)
|
107
114
|
visitor.visit(:environment, self) do
|
108
115
|
puppetfile.accept(visitor)
|
@@ -46,10 +46,33 @@ class R10K::Environment::WithModules < R10K::Environment::Base
|
|
46
46
|
# - The r10k environment object
|
47
47
|
# - A Puppetfile in the environment's content
|
48
48
|
def modules
|
49
|
-
return @modules if
|
49
|
+
return @modules if puppetfile.nil?
|
50
50
|
|
51
|
-
|
52
|
-
@modules +
|
51
|
+
puppetfile.load unless puppetfile.loaded?
|
52
|
+
@modules + puppetfile.modules
|
53
|
+
end
|
54
|
+
|
55
|
+
def module_conflicts?(mod_b)
|
56
|
+
conflict = @modules.any? { |mod_a| mod_a.name == mod_b.name }
|
57
|
+
return false unless conflict
|
58
|
+
|
59
|
+
msg_vars = {src: mod_b.origin, name: mod_b.name}
|
60
|
+
msg_error = _('Environment and %{src} both define the "%{name}" module' % msg_vars)
|
61
|
+
msg_continue = _("#{msg_error}. The %{src} definition will be ignored" % msg_vars)
|
62
|
+
|
63
|
+
case conflict_opt = @options[:module_conflicts]
|
64
|
+
when 'override_and_warn', nil
|
65
|
+
logger.warn msg_continue
|
66
|
+
when 'override'
|
67
|
+
logger.debug msg_continue
|
68
|
+
when 'error'
|
69
|
+
raise R10K::Error, msg_error
|
70
|
+
else
|
71
|
+
raise R10K::Error, _('Unexpected value for `module_conflicts` setting in %{env} ' \
|
72
|
+
'environment: %{val}' % {env: self.name, val: conflict_opt})
|
73
|
+
end
|
74
|
+
|
75
|
+
true
|
53
76
|
end
|
54
77
|
|
55
78
|
def accept(visitor)
|
@@ -59,7 +82,6 @@ class R10K::Environment::WithModules < R10K::Environment::Base
|
|
59
82
|
end
|
60
83
|
|
61
84
|
puppetfile.accept(visitor)
|
62
|
-
validate_no_module_conflicts
|
63
85
|
end
|
64
86
|
end
|
65
87
|
|
@@ -88,26 +110,12 @@ class R10K::Environment::WithModules < R10K::Environment::Base
|
|
88
110
|
@managed_content[install_path] = Array.new unless @managed_content.has_key?(install_path)
|
89
111
|
|
90
112
|
mod = R10K::Module.new(name, install_path, args, self.name)
|
91
|
-
mod.origin =
|
113
|
+
mod.origin = :environment
|
92
114
|
|
93
115
|
@managed_content[install_path] << mod.name
|
94
116
|
@modules << mod
|
95
117
|
end
|
96
118
|
|
97
|
-
def validate_no_module_conflicts
|
98
|
-
@puppetfile.load unless @puppetfile.loaded?
|
99
|
-
conflicts = (@modules + @puppetfile.modules)
|
100
|
-
.group_by { |mod| mod.name }
|
101
|
-
.select { |_, v| v.size > 1 }
|
102
|
-
.map(&:first)
|
103
|
-
unless conflicts.empty?
|
104
|
-
msg = _('Puppetfile cannot contain module names defined by environment %{name}') % {name: self.name}
|
105
|
-
msg += ' '
|
106
|
-
msg += _("Remove the conflicting definitions of the following modules: %{conflicts}" % { conflicts: conflicts.join(' ') })
|
107
|
-
raise R10K::Error.new(msg)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
119
|
include R10K::Util::Purgeable
|
112
120
|
|
113
121
|
# Returns an array of the full paths that can be purged.
|
data/lib/r10k/git.rb
CHANGED
@@ -61,11 +61,41 @@ class R10K::Git::Rugged::Credentials
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def get_plaintext_credentials(url, username_from_url)
|
64
|
-
|
65
|
-
|
64
|
+
per_repo_oauth_token = nil
|
65
|
+
if per_repo_settings = R10K::Git.get_repo_settings(url)
|
66
|
+
per_repo_oauth_token = per_repo_settings[:oauth_token]
|
67
|
+
end
|
68
|
+
|
69
|
+
if token_path = per_repo_oauth_token || R10K::Git.settings[:oauth_token]
|
70
|
+
if token_path == '-'
|
71
|
+
token = $stdin.read.strip
|
72
|
+
logger.debug2 _("Using OAuth token from stdin for URL %{url}") % { url: url }
|
73
|
+
elsif File.readable?(token_path)
|
74
|
+
token = File.read(token_path).strip
|
75
|
+
logger.debug2 _("Using OAuth token from %{token_path} for URL %{url}") % { token_path: token_path, url: url }
|
76
|
+
else
|
77
|
+
raise R10K::Git::GitError, _("%{path} is missing or unreadable, cannot load OAuth token") % { path: token_path }
|
78
|
+
end
|
79
|
+
|
80
|
+
unless valid_token?(token)
|
81
|
+
raise R10K::Git::GitError, _("Supplied OAuth token contains invalid characters.")
|
82
|
+
end
|
83
|
+
|
84
|
+
user = 'x-oauth-token'
|
85
|
+
password = token
|
86
|
+
else
|
87
|
+
user = get_git_username(url, username_from_url)
|
88
|
+
password = URI.parse(url).password || ''
|
89
|
+
end
|
66
90
|
Rugged::Credentials::UserPassword.new(username: user, password: password)
|
67
91
|
end
|
68
92
|
|
93
|
+
# This regex is the only real requirement for OAuth token format,
|
94
|
+
# per https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
|
95
|
+
def valid_token?(token)
|
96
|
+
return token =~ /^[\w\-\.~\+\/]+$/
|
97
|
+
end
|
98
|
+
|
69
99
|
def get_default_credentials(url, username_from_url)
|
70
100
|
Rugged::Credentials::Default.new
|
71
101
|
end
|
data/lib/r10k/initializers.rb
CHANGED
@@ -55,6 +55,7 @@ module R10K
|
|
55
55
|
with_setting(:private_key) { |value| R10K::Git.settings[:private_key] = value }
|
56
56
|
with_setting(:proxy) { |value| R10K::Git.settings[:proxy] = value }
|
57
57
|
with_setting(:repositories) { |value| R10K::Git.settings[:repositories] = value }
|
58
|
+
with_setting(:oauth_token) { |value| R10K::Git.settings[:oauth_token] = value }
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
data/lib/r10k/module/forge.rb
CHANGED
@@ -171,7 +171,7 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
171
171
|
if (match = title.match(/\A(\w+)[-\/](\w+)\Z/))
|
172
172
|
[match[1], match[2]]
|
173
173
|
else
|
174
|
-
raise ArgumentError, _("Forge module names must match 'owner/modulename'")
|
174
|
+
raise ArgumentError, _("Forge module names must match 'owner/modulename', instead got #{title}")
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
data/lib/r10k/module/git.rb
CHANGED
@@ -28,6 +28,11 @@ class R10K::Module::Git < R10K::Module::Base
|
|
28
28
|
# @return [String]
|
29
29
|
attr_reader :default_ref
|
30
30
|
|
31
|
+
# @!attribute [r] default_override_ref
|
32
|
+
# @api private
|
33
|
+
# @return [String]
|
34
|
+
attr_reader :default_override_ref
|
35
|
+
|
31
36
|
def initialize(title, dirname, args, environment=nil)
|
32
37
|
super
|
33
38
|
|
@@ -37,7 +42,7 @@ class R10K::Module::Git < R10K::Module::Base
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def version
|
40
|
-
validate_ref(@desired_ref, @default_ref)
|
45
|
+
validate_ref(@desired_ref, @default_ref, @default_override_ref)
|
41
46
|
end
|
42
47
|
|
43
48
|
def properties
|
@@ -63,9 +68,11 @@ class R10K::Module::Git < R10K::Module::Base
|
|
63
68
|
|
64
69
|
private
|
65
70
|
|
66
|
-
def validate_ref(desired, default)
|
71
|
+
def validate_ref(desired, default, default_override)
|
67
72
|
if desired && desired != :control_branch && @repo.resolve(desired)
|
68
73
|
return desired
|
74
|
+
elsif default_override && @repo.resolve(default_override)
|
75
|
+
return default_override
|
69
76
|
elsif default && @repo.resolve(default)
|
70
77
|
return default
|
71
78
|
else
|
@@ -81,6 +88,11 @@ class R10K::Module::Git < R10K::Module::Base
|
|
81
88
|
msg << "Could not determine desired ref"
|
82
89
|
end
|
83
90
|
|
91
|
+
if default_override
|
92
|
+
msg << "or resolve the default branch override '%{default_override}',"
|
93
|
+
vars[:default_override] = default_override
|
94
|
+
end
|
95
|
+
|
84
96
|
if default
|
85
97
|
msg << "or resolve default ref '%{default}'"
|
86
98
|
vars[:default] = default
|
@@ -94,7 +106,7 @@ class R10K::Module::Git < R10K::Module::Base
|
|
94
106
|
|
95
107
|
def parse_options(options)
|
96
108
|
ref_opts = [:branch, :tag, :commit, :ref]
|
97
|
-
known_opts = [:git, :default_branch] + ref_opts
|
109
|
+
known_opts = [:git, :default_branch, :default_branch_override] + ref_opts
|
98
110
|
|
99
111
|
unhandled = options.keys - known_opts
|
100
112
|
unless unhandled.empty?
|
@@ -105,6 +117,7 @@ class R10K::Module::Git < R10K::Module::Base
|
|
105
117
|
|
106
118
|
@desired_ref = ref_opts.find { |key| break options[key] if options.has_key?(key) } || 'master'
|
107
119
|
@default_ref = options[:default_branch]
|
120
|
+
@default_override_ref = options[:default_branch_override]
|
108
121
|
|
109
122
|
if @desired_ref == :control_branch && @environment && @environment.respond_to?(:ref)
|
110
123
|
@desired_ref = @environment.ref
|