knapsack_pro 8.1.2 → 8.2.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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +11 -13
  3. data/CHANGELOG.md +18 -2
  4. data/README.md +36 -0
  5. data/distroless/Dockerfile +37 -0
  6. data/knapsack_pro.gemspec +1 -1
  7. data/lib/knapsack_pro/adapters/rspec_adapter.rb +5 -5
  8. data/lib/knapsack_pro/repository_adapters/git_adapter.rb +21 -6
  9. data/lib/knapsack_pro/runners/spinach_runner.rb +5 -3
  10. data/lib/knapsack_pro/version.rb +1 -1
  11. data/lib/tasks/queue/cucumber.rake +1 -1
  12. data/lib/tasks/queue/minitest.rake +1 -1
  13. data/lib/tasks/queue/rspec.rake +1 -1
  14. data/spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml +1 -1
  15. data/spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml +1 -1
  16. data/spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/invalid_test_suite_token.yml +1 -1
  17. data/spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/success.yml +1 -1
  18. data/spec/integration/api/build_distributions_subset_spec.rb +1 -1
  19. data/spec/integration/api/build_subsets_create_spec.rb +1 -1
  20. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +30 -11
  21. data/spec/knapsack_pro/config/ci/app_veyor_spec.rb +2 -2
  22. data/spec/knapsack_pro/config/ci/cirrus_ci_spec.rb +2 -2
  23. data/spec/knapsack_pro/config/ci/codeship_spec.rb +2 -2
  24. data/spec/knapsack_pro/config/ci/heroku_spec.rb +2 -2
  25. data/spec/knapsack_pro/config/ci/semaphore2_spec.rb +3 -3
  26. data/spec/knapsack_pro/config/ci/semaphore_spec.rb +2 -2
  27. data/spec/knapsack_pro/config/ci/travis_spec.rb +2 -2
  28. data/spec/knapsack_pro/config/env_spec.rb +7 -7
  29. data/spec/knapsack_pro/repository_adapters/git_adapter_spec.rb +1 -1
  30. data/spec/knapsack_pro/runners/spinach_runner_spec.rb +7 -30
  31. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cb3592a7a5f0e3f69138e53d5659954e0e84190ad84380d823e776268d4e900
4
- data.tar.gz: b40c96cebfb9c4446998291b01c435f6e29cd937a51848593510ed633e56b14b
3
+ metadata.gz: 5d8372acfe13485ea86eeb30fdd524624cfbe05a374e4c6671048f898ecb5e94
4
+ data.tar.gz: 56df068506c0271ee9b55e92a7659dd1176bbfd7eef716f17f5ac9e67cd003cd
5
5
  SHA512:
6
- metadata.gz: 8308e34071c72b055335ded1422bb49762c600fffbc86f83a54911dde1cc23db59e472233bd53c1ec558fbf612c11b537587e241774dd8824d14e6665fd914e8
7
- data.tar.gz: 35829c1ba92de81be2d7b3f5bd428b9fb2a66a8ad3da940f21e196b02b7962ce13f0c453f27c85c3acfce681223b3a83145baf2b26ef12b10a66dcf67f0d9fa3
6
+ metadata.gz: ac7bff173d40c9c83aa0d1a1053890d216e4939970af363415a5462264bd7c07fd95afe5e61c00930669f3f1b6ccee678762763bb6b5066b2923db7307afc48c
7
+ data.tar.gz: 27488c936d5cea663853d319a4564476568abe774ecaa91a2eb7f83e168ac4c1221091fb6969ac4b44d383673a30c4b141591051ba81987f95af75fb066c95bb
data/.circleci/config.yml CHANGED
@@ -6,8 +6,8 @@ commands:
6
6
  - checkout
7
7
  - restore_cache:
8
8
  keys:
9
- - v1-bundler-ruby-{{ checksum "knapsack_pro.gemspec" }}
10
- - v1-bundler-ruby-
9
+ - v1-bundler-ruby-{{ checksum "knapsack_pro.gemspec" }}
10
+ - v1-bundler-ruby-
11
11
  - run:
12
12
  command: |
13
13
  bundle config set --local path './vendor/bundle'
@@ -37,10 +37,10 @@ commands:
37
37
  fi
38
38
  - restore_cache:
39
39
  keys:
40
- - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
41
- - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-
42
- - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-
43
- - v1-bundler-rails-
40
+ - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
41
+ - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-
42
+ - v1-bundler-rails-{{ checksum "Gemfile.lock" }}-
43
+ - v1-bundler-rails-
44
44
  - run:
45
45
  working_directory: << parameters.path >>
46
46
  command: |
@@ -57,7 +57,7 @@ jobs:
57
57
  working_directory: ~/knapsack_pro-ruby
58
58
  resource_class: small
59
59
  docker:
60
- - image: cimg/ruby:3.3
60
+ - image: cimg/ruby:3.4
61
61
  steps:
62
62
  - setup_knapsack_pro_ruby
63
63
  - run: gem install rubocop
@@ -88,10 +88,10 @@ jobs:
88
88
  fi
89
89
  - restore_cache:
90
90
  keys:
91
- - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
92
- - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-
93
- - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-
94
- - v1-bundler-gem-
91
+ - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
92
+ - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-
93
+ - v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-
94
+ - v1-bundler-gem-
95
95
  - run:
96
96
  command: |
97
97
  bundle config set --local path './vendor/bundle'
@@ -357,7 +357,6 @@ jobs:
357
357
  KNAPSACK_PRO_ENDPOINT: https://api-staging.knapsackpro.com
358
358
  KNAPSACK_PRO_TEST_SUITE_TOKEN_MINITEST: $KNAPSACK_PRO_TEST_SUITE_TOKEN_MINITEST
359
359
  KNAPSACK_PRO_RSPEC_DISABLED: true
360
- EXTRA_TEST_FILES_DELAY: 10
361
360
  - image: cimg/postgres:14.7
362
361
  environment:
363
362
  POSTGRES_DB: rails-app-with-knapsack_pro_test
@@ -404,7 +403,6 @@ jobs:
404
403
  KNAPSACK_PRO_ENDPOINT: https://api-staging.knapsackpro.com
405
404
  KNAPSACK_PRO_TEST_SUITE_TOKEN_MINITEST: $KNAPSACK_PRO_TEST_SUITE_TOKEN_MINITEST
406
405
  KNAPSACK_PRO_RSPEC_DISABLED: true
407
- EXTRA_TEST_FILES_DELAY: 10
408
406
  - image: cimg/postgres:14.7
409
407
  environment:
410
408
  POSTGRES_DB: rails-app-with-knapsack_pro_test
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ### UNRELEASED
4
+
5
+ ### 8.2.0
6
+
7
+ * Avoid needing a shell to support Distroless Container Images (in most cases)
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/299
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.1.3...v8.2.0
12
+
13
+ ### 8.1.3
14
+
15
+ * Update `changelog_uri` in gemspec
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.1.2...v8.1.3
18
+
3
19
  ### 8.1.2
4
20
 
5
21
  * Allow running RSpec with `--force-color` (and the default Split by Test Examples)
@@ -792,7 +808,7 @@ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v3.3.0...v3.3.1
792
808
 
793
809
  ### 3.3.0
794
810
 
795
- * Show a JSON report file content when RSpec fails during a dry run
811
+ * Show a JSON report file content when RSpec fails during a dry run
796
812
 
797
813
  https://github.com/KnapsackPro/knapsack_pro-ruby/pull/172
798
814
 
@@ -873,7 +889,7 @@ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.18.0...v2.18.1
873
889
 
874
890
  ### 2.18.0
875
891
 
876
- * Do not allow to use the RSpec tag option together with the RSpec split by test examples feature in knapsack_pro gem in Regular Mode
892
+ * Do not allow to use the RSpec tag option together with the RSpec split by test examples feature in knapsack_pro gem in Regular Mode
877
893
 
878
894
  https://github.com/KnapsackPro/knapsack_pro-ruby/pull/148
879
895
 
data/README.md CHANGED
@@ -72,6 +72,42 @@ 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
+
75
111
  ### Publishing
76
112
 
77
113
  1. Move the changes listed in the `UNRELEASED` section of the `CHANGELOG.md` to the proper version
@@ -0,0 +1,37 @@
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"]
data/knapsack_pro.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.license = 'MIT'
16
16
  spec.metadata = {
17
17
  'bug_tracker_uri' => 'https://github.com/KnapsackPro/knapsack_pro-ruby/issues',
18
- 'changelog_uri' => 'https://github.com/KnapsackPro/knapsack_pro-ruby/blob/master/CHANGELOG.md',
18
+ 'changelog_uri' => 'https://github.com/KnapsackPro/knapsack_pro-ruby/blob/main/CHANGELOG.md',
19
19
  'documentation_uri' => 'https://docs.knapsackpro.com/knapsack_pro-ruby/guide/',
20
20
  'homepage_uri' => 'https://knapsackpro.com',
21
21
  'source_code_uri' => 'https://github.com/KnapsackPro/knapsack_pro-ruby'
@@ -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'}
27
28
  cmd = [
28
- 'RACK_ENV=test',
29
- 'RAILS_ENV=test',
30
29
  KnapsackPro::Config::Env.rspec_test_example_detector_prefix,
31
- 'rake knapsack_pro:rspec_test_example_detector',
30
+ 'rake knapsack_pro:rspec_test_example_detector'
32
31
  ].join(' ')
33
- unless Kernel.system(cmd)
34
- raise "Could not generate JSON report for RSpec. Rake task failed when running #{cmd}"
32
+ unless Kernel.system(envs, cmd)
33
+ inline_cmd = envs.map { _1.join('=') }.join(' ') + ' ' + cmd
34
+ raise "Could not generate JSON report for RSpec. Rake task failed when running #{inline_cmd}"
35
35
  end
36
36
 
37
37
  # read the JSON report
@@ -44,26 +44,41 @@ 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 2>/dev/null'
47
+ command = 'git fetch --shallow-since "one month ago" --quiet'
48
48
  begin
49
49
  Timeout.timeout(5) do
50
- `#{command}`
50
+ Kernel.system(command, out: File::NULL, err: File::NULL)
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
- `git log --since "one month ago" 2>/dev/null | git shortlog --summary --email 2>/dev/null`
57
+ IO.pipe do |log_r, log_w|
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
58
66
  end
59
67
 
60
68
  def git_build_author
61
- `git log --format="%aN <%aE>" -1 2>/dev/null`
69
+ IO.pipe do |r, w|
70
+ Kernel.system('git log --format="%aN <%aE>" -1', out: w, err: File::NULL)
71
+ w.close
72
+ r.read
73
+ end
62
74
  end
63
75
 
64
76
  def shallow_repository?
65
- result = `git rev-parse --is-shallow-repository 2>/dev/null`
66
- result.strip == 'true'
77
+ IO.pipe do |r, w|
78
+ Kernel.system('git rev-parse --is-shallow-repository', out: w, err: File::NULL)
79
+ w.close
80
+ r.read.strip == 'true'
81
+ end
67
82
  end
68
83
 
69
84
  def working_dir
@@ -15,10 +15,12 @@ module KnapsackPro
15
15
 
16
16
  KnapsackPro.tracker.set_prerun_tests(runner.test_file_paths)
17
17
 
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}]
18
+ cmd = %Q[bundle exec spinach #{args} --features_path #{runner.test_dir} -- #{runner.stringify_test_file_paths}]
19
19
 
20
- Kernel.system(cmd)
21
- Kernel.exit(child_status.exitstatus) unless child_status.exitstatus.zero?
20
+ Kernel.exec({
21
+ 'KNAPSACK_PRO_REGULAR_MODE_ENABLED' => 'true',
22
+ 'KNAPSACK_PRO_TEST_SUITE_TOKEN' => ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN']
23
+ }, cmd)
22
24
  end
23
25
  end
24
26
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '8.1.2'
4
+ VERSION = '8.2.0'
5
5
  end
@@ -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("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:cucumber_go[#{args[:cucumber_args]}]'")
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("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:minitest_go[#{args[:minitest_args]}]'")
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|
@@ -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("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
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|
@@ -5,7 +5,7 @@ http_interactions:
5
5
  uri: http://api.knapsackpro.test:3000/v1/build_distributions/subset
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"fixed_test_suite_split":true,"cache_read_attempt":true,"commit_hash":"abcdefg","branch":"master","node_total":"2","node_index":"1","ci_build_id":"missing-build-id"}'
8
+ string: '{"fixed_test_suite_split":true,"cache_read_attempt":true,"commit_hash":"abcdefg","branch":"main","node_total":"2","node_index":"1","ci_build_id":"missing-build-id"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -5,7 +5,7 @@ http_interactions:
5
5
  uri: http://api.knapsackpro.test:3000/v1/build_distributions/subset
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"fixed_test_suite_split":true,"cache_read_attempt":true,"commit_hash":"abcdefg","branch":"master","node_total":"2","node_index":"1","ci_build_id":"missing-build-id"}'
8
+ string: '{"fixed_test_suite_split":true,"cache_read_attempt":true,"commit_hash":"abcdefg","branch":"main","node_total":"2","node_index":"1","ci_build_id":"missing-build-id"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -5,7 +5,7 @@ http_interactions:
5
5
  uri: http://api.knapsackpro.test:3000/v1/build_subsets
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"commit_hash":"abcdefg","branch":"master","node_total":"2","node_index":"1","test_files":[{"path":"a_spec.rb","time_execution":1.2},{"path":"b_spec.rb","time_execution":0.3}],"test_suite_token":"fake"}'
8
+ string: '{"commit_hash":"abcdefg","branch":"main","node_total":"2","node_index":"1","test_files":[{"path":"a_spec.rb","time_execution":1.2},{"path":"b_spec.rb","time_execution":0.3}]}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -5,7 +5,7 @@ http_interactions:
5
5
  uri: http://api.knapsackpro.test:3000/v1/build_subsets
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"commit_hash":"abcdefg","branch":"master","node_total":"2","node_index":"1","test_files":[{"path":"a_spec.rb","time_execution":1.2},{"path":"b_spec.rb","time_execution":0.3}],"test_suite_token":"3fa64859337f6e56409d49f865d13fd7"}'
8
+ string: '{"commit_hash":"abcdefg","branch":"main","node_total":"2","node_index":"1","test_files":[{"path":"a_spec.rb","time_execution":1.2},{"path":"b_spec.rb","time_execution":0.3}]}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -8,7 +8,7 @@ describe 'Request API /v1/build_distributions/subset' do
8
8
  KnapsackPro::Client::API::V1::BuildDistributions.subset(
9
9
  cache_read_attempt: true,
10
10
  commit_hash: 'abcdefg',
11
- branch: 'master',
11
+ branch: 'main',
12
12
  node_total: '2',
13
13
  node_index: '1',
14
14
  test_files: [
@@ -7,7 +7,7 @@ describe 'Request API /v1/build_subsets' do
7
7
  let(:action) do
8
8
  KnapsackPro::Client::API::V1::BuildSubsets.create(
9
9
  commit_hash: 'abcdefg',
10
- branch: 'master',
10
+ branch: 'main',
11
11
  node_total: '2',
12
12
  node_index: '1',
13
13
  test_files: [
@@ -57,19 +57,36 @@ describe KnapsackPro::Adapters::RSpecAdapter do
57
57
 
58
58
  subject { described_class.test_file_cases_for(slow_test_files) }
59
59
 
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.")
60
+ context 'when the rake task to detect RSpec test examples succeeded' do
61
+ it 'returns test example paths for slow test files' do
62
+ logger = instance_double(Logger)
63
+ allow(KnapsackPro).to receive(:logger).and_return(logger)
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
64
77
 
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)
78
+ expect(logger).to have_received(: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.")
79
+ end
67
80
  end
68
81
 
69
- context 'when the rake task to detect RSpec test examples succeeded' do
70
- let(:cmd_result) { true }
82
+ context 'when KNAPSACK_PRO_RSPEC_TEST_EXAMPLE_DETECTOR_PREFIX is set with a custom environment variable' do
83
+ it 'calls Kernel.system using a single command including ENVs that is passed to a shell (does not work in a distroless environment)' do
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)
71
89
 
72
- it 'returns test example paths for slow test files' do
73
90
  rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
74
91
  expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
75
92
 
@@ -81,9 +98,11 @@ describe KnapsackPro::Adapters::RSpecAdapter do
81
98
  end
82
99
 
83
100
  context 'when the rake task to detect RSpec test examples failed' do
84
- let(:cmd_result) { false }
85
-
86
101
  it do
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)
105
+
87
106
  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')
88
107
  end
89
108
  end
@@ -49,8 +49,8 @@ describe KnapsackPro::Config::CI::AppVeyor do
49
49
  subject { described_class.new.branch }
50
50
 
51
51
  context 'when the environment exists' do
52
- let(:env) { { 'APPVEYOR_REPO_BRANCH' => 'master' } }
53
- it { should eql 'master' }
52
+ let(:env) { { 'APPVEYOR_REPO_BRANCH' => 'main' } }
53
+ it { should eql 'main' }
54
54
  end
55
55
 
56
56
  context "when the environment doesn't exist" do
@@ -63,8 +63,8 @@ describe KnapsackPro::Config::CI::CirrusCI do
63
63
  subject { described_class.new.branch }
64
64
 
65
65
  context 'when the environment exists' do
66
- let(:env) { { 'CIRRUS_BRANCH' => 'master' } }
67
- it { should eql 'master' }
66
+ let(:env) { { 'CIRRUS_BRANCH' => 'main' } }
67
+ it { should eql 'main' }
68
68
  end
69
69
 
70
70
  context "when the environment doesn't exist" do
@@ -49,8 +49,8 @@ describe KnapsackPro::Config::CI::Codeship do
49
49
  subject { described_class.new.branch }
50
50
 
51
51
  context 'when the environment exists' do
52
- let(:env) { { 'CI_BRANCH' => 'master' } }
53
- it { should eql 'master' }
52
+ let(:env) { { 'CI_BRANCH' => 'main' } }
53
+ it { should eql 'main' }
54
54
  end
55
55
 
56
56
  context "when the environment doesn't exist" do
@@ -63,8 +63,8 @@ describe KnapsackPro::Config::CI::Heroku do
63
63
  subject { described_class.new.branch }
64
64
 
65
65
  context 'when the environment exists' do
66
- let(:env) { { 'HEROKU_TEST_RUN_BRANCH' => 'master' } }
67
- it { should eql 'master' }
66
+ let(:env) { { 'HEROKU_TEST_RUN_BRANCH' => 'main' } }
67
+ it { should eql 'main' }
68
68
  end
69
69
 
70
70
  context "when the environment doesn't exist" do
@@ -68,13 +68,13 @@ describe KnapsackPro::Config::CI::Semaphore2 do
68
68
  end
69
69
 
70
70
  context 'when both SEMAPHORE_GIT_WORKING_BRANCH and SEMAPHORE_GIT_BRANCH are set' do
71
- let(:env) { { 'SEMAPHORE_GIT_WORKING_BRANCH' => 'feature', 'SEMAPHORE_GIT_BRANCH' => 'master' } }
71
+ let(:env) { { 'SEMAPHORE_GIT_WORKING_BRANCH' => 'feature', 'SEMAPHORE_GIT_BRANCH' => 'main' } }
72
72
  it { should eql 'feature' }
73
73
  end
74
74
 
75
75
  context 'when SEMAPHORE_GIT_BRANCH is set' do
76
- let(:env) { { 'SEMAPHORE_GIT_BRANCH' => 'master' } }
77
- it { should eql 'master' }
76
+ let(:env) { { 'SEMAPHORE_GIT_BRANCH' => 'main' } }
77
+ it { should eql 'main' }
78
78
  end
79
79
 
80
80
  context "when no ENVs are set" do
@@ -63,8 +63,8 @@ describe KnapsackPro::Config::CI::Semaphore do
63
63
  subject { described_class.new.branch }
64
64
 
65
65
  context 'when the environment exists' do
66
- let(:env) { { 'BRANCH_NAME' => 'master' } }
67
- it { should eql 'master' }
66
+ let(:env) { { 'BRANCH_NAME' => 'main' } }
67
+ it { should eql 'main' }
68
68
  end
69
69
 
70
70
  context "when the environment doesn't exist" do
@@ -49,8 +49,8 @@ describe KnapsackPro::Config::CI::Travis do
49
49
  subject { described_class.new.branch }
50
50
 
51
51
  context 'when the environment exists' do
52
- let(:env) { { 'TRAVIS_BRANCH' => 'master' } }
53
- it { should eql 'master' }
52
+ let(:env) { { 'TRAVIS_BRANCH' => 'main' } }
53
+ it { should eql 'main' }
54
54
  end
55
55
 
56
56
  context "when the environment doesn't exist" do
@@ -313,8 +313,8 @@ describe KnapsackPro::Config::Env do
313
313
 
314
314
  context 'when ENV exists' do
315
315
  context 'when KNAPSACK_PRO_BRANCH has value' do
316
- before { stub_const("ENV", { 'KNAPSACK_PRO_BRANCH' => 'master' }) }
317
- it { should eq 'master' }
316
+ before { stub_const("ENV", { 'KNAPSACK_PRO_BRANCH' => 'main' }) }
317
+ it { should eq 'main' }
318
318
  end
319
319
 
320
320
  context 'when CI environment has value' do
@@ -335,22 +335,22 @@ describe KnapsackPro::Config::Env do
335
335
  end
336
336
 
337
337
  context 'when values are different' do
338
- let(:env_value) { 'master' }
338
+ let(:env_value) { 'main' }
339
339
  let(:ci_value) { 'feature-branch' }
340
340
 
341
- it { should eq 'master' }
341
+ it { should eq 'main' }
342
342
 
343
343
  it 'logs a warning' do
344
344
  expect(logger).to receive(:info).with(
345
- 'You have set the environment variable KNAPSACK_PRO_BRANCH to master which could be automatically determined from the CI environment as feature-branch.'
345
+ 'You have set the environment variable KNAPSACK_PRO_BRANCH to main which could be automatically determined from the CI environment as feature-branch.'
346
346
  )
347
347
  subject
348
348
  end
349
349
  end
350
350
 
351
351
  context 'when values are the same' do
352
- let(:env_value) { 'master' }
353
- let(:ci_value) { 'master' }
352
+ let(:env_value) { 'main' }
353
+ let(:ci_value) { 'main' }
354
354
 
355
355
  it 'does not log a warning' do
356
356
  expect(logger).not_to receive(:info)
@@ -28,7 +28,7 @@ describe KnapsackPro::RepositoryAdapters::GitAdapter do
28
28
  describe '#branches' do
29
29
  subject { described_class.new.branches }
30
30
 
31
- it { expect(subject.include?('master')).to be true }
31
+ it { expect(subject.include?('main')).to be true }
32
32
  it { expect(subject.include?(circle_branch)).to be true } if ENV['CIRCLECI']
33
33
  end
34
34
 
@@ -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(:stringify_test_file_paths) { test_file_paths.join(' ') }
23
22
  let(:test_dir) { 'fake-test-dir' }
23
+ let(:stringify_test_file_paths) { test_file_paths.join(' ') }
24
24
  let(:runner) do
25
25
  instance_double(described_class,
26
26
  test_dir: test_dir,
@@ -30,42 +30,19 @@ describe KnapsackPro::Runners::SpinachRunner do
30
30
  end
31
31
  let(:child_status) { double }
32
32
 
33
- before do
33
+ it do
34
34
  expect(KnapsackPro::Adapters::SpinachAdapter).to receive(:verify_bind_method_called)
35
35
 
36
36
  tracker = instance_double(KnapsackPro::Tracker)
37
37
  expect(KnapsackPro).to receive(:tracker).and_return(tracker)
38
38
  expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
39
39
 
40
- expect(Kernel).to receive(:system).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')
41
-
42
- allow(described_class).to receive(:child_status).and_return(child_status)
43
- end
44
-
45
- after { subject }
46
-
47
- context 'when command exit with success code' do
48
- let(:exitstatus) { 0 }
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
+ )
49
44
 
50
- before do
51
- expect(child_status).to receive(:exitstatus).and_return(exitstatus)
52
- end
53
-
54
- it do
55
- expect(Kernel).not_to receive(:exit)
56
- end
57
- end
58
-
59
- context 'when command exit without success code' do
60
- let(:exitstatus) { 1 }
61
-
62
- before do
63
- expect(child_status).to receive(:exitstatus).twice.and_return(exitstatus)
64
- end
65
-
66
- it do
67
- expect(Kernel).to receive(:exit).with(exitstatus)
68
- end
45
+ subject
69
46
  end
70
47
  end
71
48
 
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.1.2
4
+ version: 8.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-17 00:00:00.000000000 Z
10
+ date: 2025-05-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -216,6 +216,7 @@ files:
216
216
  - Rakefile
217
217
  - bin/knapsack_pro
218
218
  - bin/test
219
+ - distroless/Dockerfile
219
220
  - knapsack_pro.gemspec
220
221
  - lib/knapsack_pro.rb
221
222
  - lib/knapsack_pro/adapters/base_adapter.rb
@@ -410,7 +411,7 @@ licenses:
410
411
  - MIT
411
412
  metadata:
412
413
  bug_tracker_uri: https://github.com/KnapsackPro/knapsack_pro-ruby/issues
413
- changelog_uri: https://github.com/KnapsackPro/knapsack_pro-ruby/blob/master/CHANGELOG.md
414
+ changelog_uri: https://github.com/KnapsackPro/knapsack_pro-ruby/blob/main/CHANGELOG.md
414
415
  documentation_uri: https://docs.knapsackpro.com/knapsack_pro-ruby/guide/
415
416
  homepage_uri: https://knapsackpro.com
416
417
  source_code_uri: https://github.com/KnapsackPro/knapsack_pro-ruby