knapsack_pro 8.2.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +0 -36
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +5 -5
- data/lib/knapsack_pro/repository_adapters/git_adapter.rb +6 -21
- data/lib/knapsack_pro/runners/spinach_runner.rb +2 -5
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/tasks/queue/cucumber.rake +1 -1
- data/lib/tasks/queue/minitest.rake +1 -1
- data/lib/tasks/queue/rspec.rake +1 -1
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +11 -30
- data/spec/knapsack_pro/runners/spinach_runner_spec.rb +2 -6
- metadata +2 -3
- data/distroless/Dockerfile +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 154cc1aaba977644e5f9dd5298e594ba4e6bbc4a67ec1edf1caac2aaf3d21ebb
|
4
|
+
data.tar.gz: 11a7acd42b97cd0e2d0075733e0a34ebcc5677f1cbd2e5342cccb2745405cadd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 733e3fc942afe5ba74bc1b689ac9255bba46e28ddfdd60a826a0946f68a9c208d139786c2ff32319885adbe1c1a0e0696d9f63c5dc1a916b6b5a4072af3e9de8
|
7
|
+
data.tar.gz: 5769bf6874b3b93a1349268688d0304015da91072d9661852b034e937628f1be51d17a4e96a9124713fc6a730f953257989ba4613c6d5246de6ac8ec332c21e7
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
### UNRELEASED
|
4
4
|
|
5
|
+
### 8.3.0
|
6
|
+
|
7
|
+
* Revert to 8.1.3 because of [the issue #301](https://github.com/KnapsackPro/knapsack_pro-ruby/issues/301)
|
8
|
+
|
9
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/302
|
10
|
+
|
11
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.2.0...v8.3.0
|
12
|
+
|
5
13
|
### 8.2.0
|
6
14
|
|
7
15
|
* Avoid needing a shell to support Distroless Container Images (in most cases)
|
data/README.md
CHANGED
@@ -72,42 +72,6 @@ bin/test
|
|
72
72
|
|
73
73
|
Scripted tests can be found in the [Rails App With Knapsack Pro repository](https://github.com/KnapsackPro/rails-app-with-knapsack_pro/blob/master/bin/knapsack_pro_all.rb).
|
74
74
|
|
75
|
-
### Distroless Container Images
|
76
|
-
|
77
|
-
Ensure that Knapsack Pro is written in a way that supports Distroless Container Images. Avoid using a shell when calling methods like [`Kernel.system`](https://rubyapi.org/3.4/o/kernel#method-i-system) or [`Kernel.exec`](https://rubyapi.org/3.4/o/kernel#method-i-exec).
|
78
|
-
|
79
|
-
✅ Good - shell is not required
|
80
|
-
|
81
|
-
```ruby
|
82
|
-
cmd = 'bundle exec rake knapsack_pro:something'
|
83
|
-
Kernel.system({ 'RAILS_ENV' => 'test' }, cmd)
|
84
|
-
|
85
|
-
cmd = ['bundle', 'exec', 'rake', 'knapsack_pro:example']
|
86
|
-
Kernel.system({ 'RAILS_ENV' => 'test' }, *cmd)
|
87
|
-
```
|
88
|
-
|
89
|
-
⛔️ Bad - shell is required
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
# Avoid embedding environment variables in the command string
|
93
|
-
cmd = 'RAILS_ENV=test bundle exec rake knapsack_pro:something'
|
94
|
-
Kernel.system(cmd)
|
95
|
-
|
96
|
-
# Avoid output redirection
|
97
|
-
cmd = 'program 2>/dev/null'
|
98
|
-
Kernel.system(cmd)
|
99
|
-
|
100
|
-
# Avoid using the pipe operator
|
101
|
-
cmd = 'program1 | program2'
|
102
|
-
Kernel.system(cmd)
|
103
|
-
```
|
104
|
-
|
105
|
-
Use [Dockerfile](distroless/Dockerfile) to test if the code requires a shell:
|
106
|
-
|
107
|
-
```bash
|
108
|
-
docker build -t test -f distroless/Dockerfile . && docker run --rm -it test
|
109
|
-
```
|
110
|
-
|
111
75
|
### Publishing
|
112
76
|
|
113
77
|
1. Move the changes listed in the `UNRELEASED` section of the `CHANGELOG.md` to the proper version
|
@@ -24,14 +24,14 @@ module KnapsackPro
|
|
24
24
|
KnapsackPro.logger.info("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing #{slow_test_files.size} slow test files.")
|
25
25
|
|
26
26
|
# generate the RSpec JSON report in a separate process to not pollute the RSpec state
|
27
|
-
envs = {'RACK_ENV' => 'test', 'RAILS_ENV' => 'test'}
|
28
27
|
cmd = [
|
28
|
+
'RACK_ENV=test',
|
29
|
+
'RAILS_ENV=test',
|
29
30
|
KnapsackPro::Config::Env.rspec_test_example_detector_prefix,
|
30
|
-
'rake knapsack_pro:rspec_test_example_detector'
|
31
|
+
'rake knapsack_pro:rspec_test_example_detector',
|
31
32
|
].join(' ')
|
32
|
-
unless Kernel.system(
|
33
|
-
|
34
|
-
raise "Could not generate JSON report for RSpec. Rake task failed when running #{inline_cmd}"
|
33
|
+
unless Kernel.system(cmd)
|
34
|
+
raise "Could not generate JSON report for RSpec. Rake task failed when running #{cmd}"
|
35
35
|
end
|
36
36
|
|
37
37
|
# read the JSON report
|
@@ -44,41 +44,26 @@ module KnapsackPro
|
|
44
44
|
|
45
45
|
def git_commit_authors
|
46
46
|
if KnapsackPro::Config::Env.ci? && shallow_repository?
|
47
|
-
command = 'git fetch --shallow-since "one month ago" --quiet'
|
47
|
+
command = 'git fetch --shallow-since "one month ago" --quiet 2>/dev/null'
|
48
48
|
begin
|
49
49
|
Timeout.timeout(5) do
|
50
|
-
|
50
|
+
`#{command}`
|
51
51
|
end
|
52
52
|
rescue Timeout::Error
|
53
53
|
KnapsackPro.logger.debug("Skip the `#{command}` command because it took too long.")
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
Kernel.system('git log --since "one month ago"', out: log_w, err: File::NULL)
|
59
|
-
log_w.close
|
60
|
-
IO.pipe do |shortlog_r, shortlog_w|
|
61
|
-
Kernel.system('git shortlog --summary --email', in: log_r, out: shortlog_w, err: File::NULL)
|
62
|
-
shortlog_w.close
|
63
|
-
shortlog_r.read
|
64
|
-
end
|
65
|
-
end
|
57
|
+
`git log --since "one month ago" 2>/dev/null | git shortlog --summary --email 2>/dev/null`
|
66
58
|
end
|
67
59
|
|
68
60
|
def git_build_author
|
69
|
-
|
70
|
-
Kernel.system('git log --format="%aN <%aE>" -1', out: w, err: File::NULL)
|
71
|
-
w.close
|
72
|
-
r.read
|
73
|
-
end
|
61
|
+
`git log --format="%aN <%aE>" -1 2>/dev/null`
|
74
62
|
end
|
75
63
|
|
76
64
|
def shallow_repository?
|
77
|
-
|
78
|
-
|
79
|
-
w.close
|
80
|
-
r.read.strip == 'true'
|
81
|
-
end
|
65
|
+
result = `git rev-parse --is-shallow-repository 2>/dev/null`
|
66
|
+
result.strip == 'true'
|
82
67
|
end
|
83
68
|
|
84
69
|
def working_dir
|
@@ -15,12 +15,9 @@ module KnapsackPro
|
|
15
15
|
|
16
16
|
KnapsackPro.tracker.set_prerun_tests(runner.test_file_paths)
|
17
17
|
|
18
|
-
cmd = %Q[bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
|
18
|
+
cmd = %Q[KNAPSACK_PRO_REGULAR_MODE_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=#{ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']} bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
|
19
19
|
|
20
|
-
Kernel.exec(
|
21
|
-
'KNAPSACK_PRO_REGULAR_MODE_ENABLED' => 'true',
|
22
|
-
'KNAPSACK_PRO_TEST_SUITE_TOKEN' => ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']
|
23
|
-
}, cmd)
|
20
|
+
Kernel.exec(cmd)
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -5,7 +5,7 @@ require 'knapsack_pro'
|
|
5
5
|
namespace :knapsack_pro do
|
6
6
|
namespace :queue do
|
7
7
|
task :cucumber, [:cucumber_args] do |_, args|
|
8
|
-
Kernel.exec(
|
8
|
+
Kernel.exec("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:cucumber_go[#{args[:cucumber_args]}]'")
|
9
9
|
end
|
10
10
|
|
11
11
|
task :cucumber_go, [:cucumber_args] do |_, args|
|
@@ -5,7 +5,7 @@ require 'knapsack_pro'
|
|
5
5
|
namespace :knapsack_pro do
|
6
6
|
namespace :queue do
|
7
7
|
task :minitest, [:minitest_args] do |_, args|
|
8
|
-
Kernel.exec(
|
8
|
+
Kernel.exec("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:minitest_go[#{args[:minitest_args]}]'")
|
9
9
|
end
|
10
10
|
|
11
11
|
task :minitest_go, [:minitest_args] do |_, args|
|
data/lib/tasks/queue/rspec.rake
CHANGED
@@ -5,7 +5,7 @@ require 'knapsack_pro'
|
|
5
5
|
namespace :knapsack_pro do
|
6
6
|
namespace :queue do
|
7
7
|
task :rspec, [:rspec_args] do |_, args|
|
8
|
-
Kernel.exec(
|
8
|
+
Kernel.exec("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
|
9
9
|
end
|
10
10
|
|
11
11
|
task :rspec_go, [:rspec_args] do |_, args|
|
@@ -57,36 +57,19 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
57
57
|
|
58
58
|
subject { described_class.test_file_cases_for(slow_test_files) }
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
allow(logger).to receive(:info)
|
65
|
-
|
66
|
-
cmd = 'bundle exec rake knapsack_pro:rspec_test_example_detector'
|
67
|
-
env = { 'RACK_ENV' => 'test', 'RAILS_ENV' => 'test' }
|
68
|
-
expect(Kernel).to receive(:system).with(env, cmd).and_return(true)
|
69
|
-
|
70
|
-
rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
|
71
|
-
expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
|
72
|
-
|
73
|
-
test_file_example_paths = double
|
74
|
-
expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
|
75
|
-
|
76
|
-
expect(subject).to eq test_file_example_paths
|
60
|
+
before do
|
61
|
+
logger = instance_double(Logger)
|
62
|
+
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
63
|
+
expect(logger).to receive(:info).with("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing 5 slow test files.")
|
77
64
|
|
78
|
-
|
79
|
-
|
65
|
+
cmd = 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector'
|
66
|
+
expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
|
80
67
|
end
|
81
68
|
|
82
|
-
context 'when
|
83
|
-
|
84
|
-
stub_const('ENV', { 'KNAPSACK_PRO_RSPEC_TEST_EXAMPLE_DETECTOR_PREFIX' => 'CUSTOM_ENV_VAR=123 bundle exec' })
|
85
|
-
|
86
|
-
cmd = 'CUSTOM_ENV_VAR=123 bundle exec rake knapsack_pro:rspec_test_example_detector'
|
87
|
-
env = { 'RACK_ENV' => 'test', 'RAILS_ENV' => 'test' }
|
88
|
-
expect(Kernel).to receive(:system).with(env, cmd).and_return(true)
|
69
|
+
context 'when the rake task to detect RSpec test examples succeeded' do
|
70
|
+
let(:cmd_result) { true }
|
89
71
|
|
72
|
+
it 'returns test example paths for slow test files' do
|
90
73
|
rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
|
91
74
|
expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
|
92
75
|
|
@@ -98,11 +81,9 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
98
81
|
end
|
99
82
|
|
100
83
|
context 'when the rake task to detect RSpec test examples failed' do
|
101
|
-
|
102
|
-
cmd = 'bundle exec rake knapsack_pro:rspec_test_example_detector'
|
103
|
-
env = { 'RACK_ENV' => 'test', 'RAILS_ENV' => 'test' }
|
104
|
-
expect(Kernel).to receive(:system).with(env, cmd).and_return(false)
|
84
|
+
let(:cmd_result) { false }
|
105
85
|
|
86
|
+
it do
|
106
87
|
expect { subject }.to raise_error(RuntimeError, 'Could not generate JSON report for RSpec. Rake task failed when running RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector')
|
107
88
|
end
|
108
89
|
end
|
@@ -19,8 +19,8 @@ describe KnapsackPro::Runners::SpinachRunner do
|
|
19
19
|
|
20
20
|
context 'when test files were returned by Knapsack Pro API' do
|
21
21
|
let(:test_file_paths) { ['features/a.feature', 'features/b.feature'] }
|
22
|
-
let(:test_dir) { 'fake-test-dir' }
|
23
22
|
let(:stringify_test_file_paths) { test_file_paths.join(' ') }
|
23
|
+
let(:test_dir) { 'fake-test-dir' }
|
24
24
|
let(:runner) do
|
25
25
|
instance_double(described_class,
|
26
26
|
test_dir: test_dir,
|
@@ -28,7 +28,6 @@ describe KnapsackPro::Runners::SpinachRunner do
|
|
28
28
|
stringify_test_file_paths: stringify_test_file_paths,
|
29
29
|
test_files_to_execute_exist?: true)
|
30
30
|
end
|
31
|
-
let(:child_status) { double }
|
32
31
|
|
33
32
|
it do
|
34
33
|
expect(KnapsackPro::Adapters::SpinachAdapter).to receive(:verify_bind_method_called)
|
@@ -37,10 +36,7 @@ describe KnapsackPro::Runners::SpinachRunner do
|
|
37
36
|
expect(KnapsackPro).to receive(:tracker).and_return(tracker)
|
38
37
|
expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
|
39
38
|
|
40
|
-
expect(Kernel).to receive(:exec).with(
|
41
|
-
{ 'KNAPSACK_PRO_REGULAR_MODE_ENABLED' => 'true', 'KNAPSACK_PRO_TEST_SUITE_TOKEN' => 'spinach-token' },
|
42
|
-
'bundle exec spinach --custom-arg --features_path fake-test-dir -- features/a.feature features/b.feature'
|
43
|
-
)
|
39
|
+
expect(Kernel).to receive(:exec).with('KNAPSACK_PRO_REGULAR_MODE_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=spinach-token bundle exec spinach --custom-arg --features_path fake-test-dir -- features/a.feature features/b.feature')
|
44
40
|
|
45
41
|
subject
|
46
42
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knapsack_pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.
|
4
|
+
version: 8.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-05-
|
10
|
+
date: 2025-05-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rake
|
@@ -216,7 +216,6 @@ files:
|
|
216
216
|
- Rakefile
|
217
217
|
- bin/knapsack_pro
|
218
218
|
- bin/test
|
219
|
-
- distroless/Dockerfile
|
220
219
|
- knapsack_pro.gemspec
|
221
220
|
- lib/knapsack_pro.rb
|
222
221
|
- lib/knapsack_pro/adapters/base_adapter.rb
|
data/distroless/Dockerfile
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
FROM cgr.dev/chainguard/ruby:latest-dev AS builder
|
2
|
-
|
3
|
-
WORKDIR /build
|
4
|
-
RUN <<RUN
|
5
|
-
cat <<GEMFILE > Gemfile
|
6
|
-
source "https://rubygems.org"
|
7
|
-
GEMFILE
|
8
|
-
|
9
|
-
gem install bundler
|
10
|
-
bundle config set --local path vendor/bundle
|
11
|
-
bundle install
|
12
|
-
RUN
|
13
|
-
|
14
|
-
RUN <<RUN
|
15
|
-
cat <<RAKEFILE > Rakefile
|
16
|
-
RAKEFILE
|
17
|
-
|
18
|
-
mkdir bin
|
19
|
-
cat <<CI > bin/ci
|
20
|
-
ENV['PATH'] =+ "#{Gem.user_dir}/bin"
|
21
|
-
require 'bundler/setup'
|
22
|
-
|
23
|
-
success = Kernel.system({ 'RAILS_ENV' => 'test' }, 'bundle --version') # ✅
|
24
|
-
raise "The command failed!" unless success
|
25
|
-
|
26
|
-
success = Kernel.system({ 'RAILS_ENV' => 'test' }, 'bundle --version 2>/dev/null') # ⛔️
|
27
|
-
raise "The command failed!" unless success
|
28
|
-
|
29
|
-
CI
|
30
|
-
RUN
|
31
|
-
|
32
|
-
FROM cgr.dev/chainguard/ruby:latest
|
33
|
-
|
34
|
-
WORKDIR /app
|
35
|
-
COPY --from=builder /home/nonroot/.local /home/nonroot/.local
|
36
|
-
COPY --from=builder /build /app
|
37
|
-
CMD ["bin/ci"]
|