From 24dbb9672aad8d382b83020d2ced8f9f5d831392 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Fri, 19 Sep 2025 21:24:14 +0200 Subject: [PATCH 01/14] CI: List existing modules --- spec/integration/apply_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/integration/apply_spec.rb b/spec/integration/apply_spec.rb index aad2c2e9..2872875e 100644 --- a/spec/integration/apply_spec.rb +++ b/spec/integration/apply_spec.rb @@ -34,7 +34,8 @@ # The following are run with both *nix and Windows targets. shared_examples 'agentful tests' do |targets| - it 'runs a ruby task' do + it 'lists all modules & runs a ruby task' do + run_cli_json(%w[module show], project: project) results = run_cli_json(%W[task run basic::ruby_task -t #{targets}], project: project) results['items'].each do |result| From 4b45fb73fc7a9ba8cb8d570fe30532b7c950749b Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Fri, 19 Sep 2025 22:22:08 +0200 Subject: [PATCH 02/14] CI: Add Debugging to Windows integration tests --- .github/workflows/windows.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 47a516b7..da49631b 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -43,6 +43,10 @@ jobs: - name: Install modules if: steps.modules.outputs.cache-hit != 'true' run: bundle exec r10k puppetfile install + - name: Output powershell version + run: $PSVersionTable + - name: List trusted WSMan hosts + run: Get-Item WSMan:\localhost\Client\TrustedHosts - uses: ./.github/actions/windows_agent_setup - name: Run tests run: bundle exec rake ci:windows:integration From b072a3edc3a53387e70414316d1d9562b1ff7446 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Fri, 19 Sep 2025 23:45:35 +0200 Subject: [PATCH 03/14] CI: Output WinRM state --- .github/workflows/windows.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index da49631b..f6a5c2d0 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -47,6 +47,8 @@ jobs: run: $PSVersionTable - name: List trusted WSMan hosts run: Get-Item WSMan:\localhost\Client\TrustedHosts + - name: Output WinRM logs + run: winrm enumerate winrm/config/listener - uses: ./.github/actions/windows_agent_setup - name: Run tests run: bundle exec rake ci:windows:integration From 59822142a1db51ccfc4717633294f44274018469 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Fri, 19 Sep 2025 23:48:16 +0200 Subject: [PATCH 04/14] CI: Verify that WSMan works --- .github/workflows/windows.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index f6a5c2d0..7254a347 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -49,6 +49,8 @@ jobs: run: Get-Item WSMan:\localhost\Client\TrustedHosts - name: Output WinRM logs run: winrm enumerate winrm/config/listener + - name: Test WSMan connection + run: Test-WSMan localhost - uses: ./.github/actions/windows_agent_setup - name: Run tests run: bundle exec rake ci:windows:integration From a99baf7f06e2105451577cc7268aa29de47dc0f8 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Sat, 20 Sep 2025 00:03:05 +0200 Subject: [PATCH 05/14] Windows CI: Allow WinRM Access from localhost --- scripts/ci.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci.ps1 b/scripts/ci.ps1 index 85cdff43..d3935f95 100644 --- a/scripts/ci.ps1 +++ b/scripts/ci.ps1 @@ -76,7 +76,7 @@ function Grant-WinRMHttpsAccess($certThumbprint) $winRMArgs = @{ ResourceURI = 'winrm/config/Listener' SelectorSet = @{ Address = '*'; Transport = 'HTTPS'; } - ValueSet = @{ Hostname = 'boltserver'; CertificateThumbprint = $certThumbprint } + ValueSet = @{ Hostname = 'localhost'; CertificateThumbprint = $certThumbprint } } $instance = Set-WSManInstance @winRMArgs Write-Information ($instance | Format-List | Out-String) From d91f85b00ed39a1c8948b4a17030a79360e10639 Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Sat, 20 Sep 2025 00:45:37 +0200 Subject: [PATCH 06/14] Back to boltserver --- scripts/ci.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci.ps1 b/scripts/ci.ps1 index d3935f95..85cdff43 100644 --- a/scripts/ci.ps1 +++ b/scripts/ci.ps1 @@ -76,7 +76,7 @@ function Grant-WinRMHttpsAccess($certThumbprint) $winRMArgs = @{ ResourceURI = 'winrm/config/Listener' SelectorSet = @{ Address = '*'; Transport = 'HTTPS'; } - ValueSet = @{ Hostname = 'localhost'; CertificateThumbprint = $certThumbprint } + ValueSet = @{ Hostname = 'boltserver'; CertificateThumbprint = $certThumbprint } } $instance = Set-WSManInstance @winRMArgs Write-Information ($instance | Format-List | Out-String) From e41244d592abdb56fc91eddb831f3c81f907589d Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Sat, 20 Sep 2025 00:56:56 +0200 Subject: [PATCH 07/14] Test no-ssl-verify --- spec/integration/lookup_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index cfef94d1..52c1e81a 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -145,7 +145,7 @@ let(:uri) { 'localhost' } it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do - result = run_cli_json(cli_command + %W[-t #{uri}]) + result = run_cli_json(cli_command + %W[-t #{uri} --no-ssl-verify]) expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end From 6013e798af901235c33443af159b7e3d15494fb7 Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Sat, 20 Sep 2025 01:07:50 +0200 Subject: [PATCH 08/14] Debug output --- spec/integration/lookup_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index 52c1e81a..f2f880b8 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -145,7 +145,7 @@ let(:uri) { 'localhost' } it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do - result = run_cli_json(cli_command + %W[-t #{uri} --no-ssl-verify]) + result = run_cli_json(cli_command + %W[-t #{uri} --log-level debug]) expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end From 1dc785e60afc50320fad8b42c6b68811cf8121cc Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Sat, 20 Sep 2025 01:21:27 +0200 Subject: [PATCH 09/14] verbose --- .github/workflows/windows.yaml | 2 +- spec/integration/lookup_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 7254a347..333334b6 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -53,7 +53,7 @@ jobs: run: Test-WSMan localhost - uses: ./.github/actions/windows_agent_setup - name: Run tests - run: bundle exec rake ci:windows:integration + run: bundle exec rake ci:windows:integration --trace -v agentless: name: Agentless diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index f2f880b8..cfef94d1 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -145,7 +145,7 @@ let(:uri) { 'localhost' } it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do - result = run_cli_json(cli_command + %W[-t #{uri} --log-level debug]) + result = run_cli_json(cli_command + %W[-t #{uri}]) expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end From 277986144243dad431d588025465a6e64499450b Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Sat, 20 Sep 2025 01:35:44 +0200 Subject: [PATCH 10/14] More output --- .github/workflows/windows.yaml | 16 ++++++++++++++-- scripts/ci.ps1 | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 333334b6..130b7da5 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -20,7 +20,7 @@ permissions: jobs: integration: name: Integration - runs-on: windows-latest + runs-on: windows-2025 strategy: matrix: ruby: [3.2] @@ -52,8 +52,20 @@ jobs: - name: Test WSMan connection run: Test-WSMan localhost - uses: ./.github/actions/windows_agent_setup - - name: Run tests + - name: Run test run: bundle exec rake ci:windows:integration --trace -v + - name: Sessions + if: always() + run: Get-PSSession + - name: Test WSMan connection + if: always() + run: Test-WSMan localhost + - name: Print EventLog + if: always() + run: winrm enumerate winrm/config/Listener + - name: Print EventLog + if: always() + run: Get-WinEvent -ListLog *winrm* | fl * agentless: name: Agentless diff --git a/scripts/ci.ps1 b/scripts/ci.ps1 index 85cdff43..939f271a 100644 --- a/scripts/ci.ps1 +++ b/scripts/ci.ps1 @@ -155,4 +155,5 @@ Enable-PSRemoting Set-WSManQuickConfig -Force Set-WinRMHostConfiguration Test-WinRMConfiguration @User | Out-Null +winrm enumerate winrm/config/Listener Add-Content -Path $ENV:GITHUB_ENV -Value "BOLT_WINRM_PASSWORD=$pass" From 64101dd93be3818c832626608f584f2f0e19a214 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Mon, 22 Sep 2025 20:27:16 +0200 Subject: [PATCH 11/14] reduce windows tests --- rakelib/tests.rake | 3 +- spec/integration/lookup_spec.rb | 266 -------------------------------- 2 files changed, 1 insertion(+), 268 deletions(-) diff --git a/rakelib/tests.rake b/rakelib/tests.rake index b7e2ae9e..a9cc83c8 100644 --- a/rakelib/tests.rake +++ b/rakelib/tests.rake @@ -131,8 +131,7 @@ begin desc '' RSpec::Core::RakeTask.new(:integration) do |t| - t.pattern = "spec/integration/**/*_spec.rb" - t.exclude_pattern = "spec/integration/transport/*" + t.pattern = "spec/integration/lookup_spec.rb" exclude = %w[apply bash docker puppetdb ssh sudo winrm_agentless] t.rspec_opts = generate_opts(exclude_tags: exclude) end diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index cfef94d1..36504e41 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -24,121 +24,6 @@ %W[plan run #{plan} --project #{project} --hiera-config #{hiera_config}] } - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=environment]) - expect(result).to eq('environment data/common.yaml') - end - - it 'accepts a default value' do - options = { 'default_value' => 'default' }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default') - end - - it 'accepts a default values hash' do - options = { 'default_values_hash' => { 'foo::bar::baz' => 'default' } }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default') - end - - it 'searches the module hierarchy' do - result = run_cli_json(cli_command + %w[key=test::module]) - expect(result).to eq('test::module modules/test/data/common.yaml') - end - - it 'does not search the module hierarchy in a different namespace' do - result = run_cli_json(cli_command + %w[key=foo::namespace]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Function lookup\(\) did not find a value for the name 'foo::namespace'/ - ) - end - - it 'does not search for global keys in the module hierarchy' do - result = run_cli_json(cli_command + %w[key=global]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Function lookup\(\) did not find a value for the name 'global'/ - ) - end - - it 'merges values' do - options = { 'merge' => 'deep' }.to_json - result = run_cli_json(cli_command + %W[key=test::merge options=#{options}]) - expect(result).to match( - 'bolt' => { 'key1' => 'value1', 'key2' => 'value1' }, - 'puppet' => { 'key1' => 'value1' } - ) - end - - context 'with a lambda' do - let(:plan) { 'test::lookup_lambda' } - - it 'returns a value from the lambda' do - result = run_cli_json(cli_command + %w[key=foo::bar::baz]) - expect(result).to eq('foo bar baz lambda') - end - - it 'returns a value from the lambda over the default value' do - options = { 'default_value' => 'default' }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('foo bar baz lambda') - end - - it 'returns a value from the default values hash over the lambda' do - options = { 'default_values_hash' => { 'foo::bar::baz' => 'default values hash' } }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default values hash') - end - end - - context 'when context is not available' do - let(:hiera_config) { File.join(project, 'hiera_interpolations.yaml') } - - it 'returns the default value' do - result = run_cli_json(cli_command + %w[key=test::interpolations]) - expect(result).to eq('test::interpolations data/common.yaml') - end - end - - context 'with a builtin backend' do - # Load pkcs7 keys as environment variables - around(:each) do |example| - env_vars = { - 'BOLT_PKCS7_PUBLIC_KEY' => File.read(File.expand_path('../keys/public_key.pkcs7.pem', project)), - 'BOLT_PKCS7_PRIVATE_KEY' => File.read(File.expand_path('../keys/private_key.pkcs7.pem', project)) - } - - with_env_vars(env_vars) do - example.run - end - end - - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=test::secret]) - expect(result).to eq('test::secret data/secret.eyaml') - end - end - - context 'with a custom backend' do - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=test::custom]) - expect(result).to eq('test::custom data/custom.txt') - end - end - - context 'with a missing backend' do - let(:hiera_config) { File.join(project, 'hiera_missing_backend.yaml') } - - it 'returns an error' do - result = run_cli_json(cli_command + %w[key=test::backends]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Unable to find 'data_hash' function named 'missing_backend'/ - ) - end - end - context 'with plan_hiera' do let(:hiera_config) { File.join(project, 'plan_hiera.yaml') } let(:plan) { 'test::plan_lookup' } @@ -165,155 +50,4 @@ end end end - - context 'command', ssh: true do - include BoltSpec::Conn - - context 'without --plan-hierarchy' do - let(:opts) { %W[--project #{project} --hiera-config #{hiera_config} -t #{target}] } - let(:target) { 'puppet_7_node' } - - around(:each) do |example| - inventory = docker_inventory.merge('vars' => { 'lookup' => 'var' }).to_json - - env_vars = { - 'BOLT_INVENTORY' => inventory, - 'BOLT_PKCS7_PUBLIC_KEY' => File.read(File.expand_path('../keys/public_key.pkcs7.pem', project)), - 'BOLT_PKCS7_PRIVATE_KEY' => File.read(File.expand_path('../keys/private_key.pkcs7.pem', project)) - } - - with_env_vars(env_vars) do - example.run - end - end - - it 'looks up a value' do - result, = run_cli_json(%w[lookup environment] + opts) - expect(result).to include( - 'object' => 'environment', - 'value' => { 'value' => 'environment data/common.yaml' } - ) - end - - context 'with interpolations' do - let(:hiera_config) { File.join(project, 'hiera_interpolations.yaml') } - - it 'looks up a value with facts' do - result, = run_cli_json(%w[lookup os] + opts) - expect(result).to include( - 'object' => 'os', - 'value' => { 'value' => 'os data/os/Ubuntu.yaml' } - ) - end - - it 'looks up a value with vars' do - result, = run_cli_json(%w[lookup var] + opts) - expect(result).to include( - 'object' => 'var', - 'value' => { 'value' => 'var data/var.yaml' } - ) - end - - it 'looks up a value with a trusted fact' do - result, = run_cli_json(%w[lookup certname] + opts) - expect(result).to include( - 'object' => 'certname', - 'value' => { 'value' => 'certname data/puppet_7_node.yaml' } - ) - end - - context 'with plan vars interpolated' do - let(:hiera_config) { File.join(project, 'hiera_plan_var.yaml') } - - it 'looks up a value with plan vars interpolated' do - result = run_cli_json(%w[lookup plan_var plan_var=plan_var] + opts) - expect(result.first['value']['value']).to eq("plan_var data/plan_var.yaml") - end - end - end - - it 'looks up a value in the module hierarchy' do - result, = run_cli_json(%w[lookup test::module] + opts) - expect(result).to include( - 'object' => 'test::module', - 'value' => { 'value' => 'test::module modules/test/data/common.yaml' } - ) - end - - it 'errors with a missing key' do - result, = run_cli_json(%w[lookup fizzbuzz] + opts) - - expect(result.dig('value', '_error', 'msg')).to eq( - "Function lookup() did not find a value for the name 'fizzbuzz'" - ) - end - - it 'looks up a value with a built-in backend' do - result, = run_cli_json(%w[lookup test::secret] + opts) - expect(result).to include( - 'object' => 'test::secret', - 'value' => { 'value' => 'test::secret data/secret.eyaml' } - ) - end - - it 'looks up a value with a custom backend' do - result, = run_cli_json(%w[lookup test::custom] + opts) - expect(result).to include( - 'object' => 'test::custom', - 'value' => { 'value' => 'test::custom data/custom.txt' } - ) - end - - context 'with a missing backend' do - let(:hiera_config) { File.join(project, 'hiera_missing_backend.yaml') } - - it 'returns an error' do - result, = run_cli_json(%w[lookup test::backends] + opts) - expect(result.dig('value', '_error', 'msg')).to match( - /Unable to find 'data_hash' function named 'missing_backend'/ - ) - end - end - - it 'looks up the same value as a plan lookup' do - plan_result = run_cli_json(%W[plan run #{plan} key=environment] + opts) - command_result, = run_cli_json(%w[lookup environment] + opts) - - expect(command_result.dig('value', 'value')).to eq(plan_result) - end - end - - context 'with --plan-hierarchy' do - let(:hiera_config) { File.join(project, 'plan_hiera.yaml') } - let(:opts) { %W[--project #{project} --hiera-config #{hiera_config} --plan-hierarchy] } - - it 'looks up a value' do - result = run_cli_json(%w[lookup pop] + opts) - expect(result).to eq("goes the weasel") - end - - context 'with plan variable interpolations interpolations' do - let(:hiera_config) { File.join(project, 'plan_hiera_var.yaml') } - - it 'looks up a value with vars interpolated' do - result = run_cli_json(%w[lookup var interpolate=var] + opts) - expect(result).to eq("var data/var.yaml") - end - end - - context 'with invalid plan_hierarchy' do - let(:hiera_config) { File.join(project, 'plan_hiera_facts.yaml') } - - it 'returns the default value' do - result = run_cli_json(%w[lookup environment] + opts) - expect(result).to eq("environment data/common.yaml") - end - end - - it 'errors with a missing key' do - expect { run_cli_json(%w[lookup fizzbuzz] + opts) } - .to raise_error(Bolt::PAL::PALError, "Function lookup() did not find a value for the name 'fizzbuzz'") - end - end - end end From 7a616da67e3bb51da0b616b5728bda8e8371ee3c Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Mon, 22 Sep 2025 21:22:43 +0200 Subject: [PATCH 12/14] increase logging --- spec/integration/lookup_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index 36504e41..78fd4517 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -30,7 +30,7 @@ let(:uri) { 'localhost' } it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do - result = run_cli_json(cli_command + %W[-t #{uri}]) + result = run_cli_json(cli_command + %W[-t #{uri} --log-level debug --trace --verbose]) expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end From 3ac3b0fe9a7be7c616db8e4654b301aca4b93036 Mon Sep 17 00:00:00 2001 From: Tim Meusel Date: Mon, 22 Sep 2025 21:32:01 +0200 Subject: [PATCH 13/14] print result --- spec/integration/lookup_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index 78fd4517..d696828e 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -31,6 +31,7 @@ it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do result = run_cli_json(cli_command + %W[-t #{uri} --log-level debug --trace --verbose]) + pp result expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end From 1b50743830e43e8d2faf32b2bb5c0e80dcee6a1d Mon Sep 17 00:00:00 2001 From: Sebastian Rakel Date: Wed, 8 Oct 2025 21:25:46 +0200 Subject: [PATCH 14/14] Install other minitar on windows --- openbolt.gemspec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openbolt.gemspec b/openbolt.gemspec index c8ccbb01..71c99b3f 100644 --- a/openbolt.gemspec +++ b/openbolt.gemspec @@ -52,7 +52,6 @@ Gem::Specification.new do |spec| spec.add_dependency "json", "~> 2.12" spec.add_dependency "jwt", "~> 2.2" spec.add_dependency "logging", "~> 2.2" - spec.add_dependency "minitar", ">= 0.6", "< 2.0" spec.add_dependency "net-scp", ">= 1.2", "< 5.0" spec.add_dependency "net-ssh", ">= 4.0", "< 8.0" spec.add_dependency "net-ssh-krb", "~> 0.5" @@ -71,4 +70,11 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake", ">= 12.0", "< 14" spec.add_development_dependency "rspec", ">= 3.0", "< 4" spec.add_development_dependency 'voxpupuli-rubocop', '~> 4.2.0' + + platform = RUBY_PLATFORM + if platform =~ /mingw|mswin/ + spec.add_dependency('minitar', '~> 0.9') + else + spec.add_dependency "minitar", ">= 0.6", "< 2.0" + end end