polyrun 2.2.1 → 2.2.3
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 +11 -0
- data/CODE_OF_CONDUCT.md +11 -11
- data/CONTRIBUTING.md +18 -96
- data/README.md +13 -0
- data/SECURITY.md +5 -5
- data/lib/polyrun/reporting/failure_merge.rb +2 -2
- data/lib/polyrun/version.rb +1 -1
- data/lib/polyrun/worker_output.rb +16 -3
- data/polyrun.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 65f2008623ad5bcf9289da8ffb3db95cf07d8261d349978b96ca463b0ff37ea3
|
|
4
|
+
data.tar.gz: a1fabab4fe6cc0f571b09d8f8a73559866730d6a76a0bc09b48f4a0e0631a724
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb24b21418a3804b868f62f72f1d8462b15f4b7ab0a9901e82789fdb0c7eb04a73ece7bd437ae10acc8c4edbffd53e64ae9e648e09376e6d9d7df2789b42be78
|
|
7
|
+
data.tar.gz: f0dd0a2b341c81ce8ea3f10358e06f205a0f7329d5695eb82e49a97e067133fe5b665b444c1b57236740a0e354b9945658f2e1351e54730a358583cc411641fb
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 2.2.3 (2026-08-16)
|
|
4
|
+
|
|
5
|
+
- Fix `merge-failures` `Encoding::CompatibilityError` when JSONL or RSpec JSON contains UTF-8 and the process locale is US-ASCII; read fragments as UTF-8
|
|
6
|
+
- Join worker output forwarders before closing pipe ends so shard logs keep the last bytes after a worker exits
|
|
7
|
+
|
|
8
|
+
## 2.2.2 (2026-07-25)
|
|
9
|
+
|
|
10
|
+
- BREAKING: Require Ruby 3.4 or newer
|
|
11
|
+
- Fix `Process.spawn` for string worker commands so the command is one argv element instead of character-splatted
|
|
12
|
+
- Drain remaining worker pipe output when the forwarder hits `IOError` or `Errno::EPIPE`
|
|
13
|
+
|
|
3
14
|
## 2.2.1 (2026-07-13)
|
|
4
15
|
|
|
5
16
|
- Fix per-example timeout leaving ActiveRecord connection pools in a bad state after `Timeout` interrupts database I/O; disconnect all pools on timeout (adapter-agnostic).
|
data/CODE_OF_CONDUCT.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# Code of Conduct
|
|
2
2
|
|
|
3
|
-
## Our
|
|
3
|
+
## Our Pledge
|
|
4
4
|
|
|
5
|
-
We pledge to make participation in
|
|
5
|
+
We pledge to make participation in our community a harassment-free experience for everyone. We operate on principles of mutual respect, privacy, and authentic engagement. We value substantive contributions and clarity on intentions.
|
|
6
6
|
|
|
7
|
-
## Our
|
|
7
|
+
## Our Standards
|
|
8
8
|
|
|
9
9
|
Examples of behavior that contributes to a positive environment include:
|
|
10
10
|
|
|
11
|
-
- Authenticity:
|
|
12
|
-
- Responsible
|
|
13
|
-
- Gentle
|
|
14
|
-
- Inclusive
|
|
11
|
+
- Authenticity: Engaging with genuine curiosity and admitting uncertainty rather than feigning knowledge.
|
|
12
|
+
- Responsible Innovation: Taking full responsibility for any content or code contributed, whether manually written or generated by automation tools.
|
|
13
|
+
- Gentle Correction: Responding politely to errors. We view mistakes as opportunities for learning, provided they are addressed with humility.
|
|
14
|
+
- Inclusive Language: Using language that welcomes diverse perspectives and respects the privacy and identity of all participants.
|
|
15
15
|
|
|
16
16
|
Examples of unacceptable behavior include:
|
|
17
17
|
|
|
18
|
-
- Harassment:
|
|
19
|
-
- Weaponized
|
|
20
|
-
- Publishing
|
|
18
|
+
- Harassment: Public or private harassment, trolling, or insulting comments.
|
|
19
|
+
- Weaponized Complexity: Using jargon or overwhelming volume (including automated spam) to silence others.
|
|
20
|
+
- Publishing Private Information: Sharing others' data or personal context without explicit permission.
|
|
21
21
|
|
|
22
|
-
## Artificial
|
|
22
|
+
## Artificial Intelligence and Automation
|
|
23
23
|
|
|
24
24
|
In accordance with our commitment to collective awareness:
|
|
25
25
|
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,107 +1,29 @@
|
|
|
1
|
-
# Contributing
|
|
1
|
+
# Contributing Guidelines
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Thank you for your interest in contributing. We value learning over perfection but require rigor and responsibility.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
bundle install
|
|
7
|
-
bundle exec appraisal install
|
|
8
|
-
```
|
|
5
|
+
## The Golden Rule of Automation
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
We welcome the use of AI and automation tools to reduce toil, but you must strictly adhere to the following:
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
bundle exec rake spec
|
|
16
|
-
```
|
|
9
|
+
1. You are the Author: You act as the responsible agent for any code you submit. You must review, debug, and understand every line.
|
|
10
|
+
2. Manage Cognitive Load: Do not submit massive, unreviewed automated dumps. Respect the reviewers' time by annotating complex logic.
|
|
11
|
+
3. Security: Never feed project secrets or private context into public AI models.
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
## How to Contribute
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
### 1. Reporting Issues
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
- Verify Accuracy: Before posting, verify your information. Avoid generalizations.
|
|
18
|
+
- Use Structured Inputs: Use issue templates to provide clear goals, constraints, and reproduction steps. This helps us understand the context immediately.
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
make native-extension
|
|
26
|
-
# or: bundle exec rake native_extension
|
|
27
|
-
```
|
|
20
|
+
### 2. Pull Request Process
|
|
28
21
|
|
|
29
|
-
|
|
22
|
+
- Scope: Keep PRs focused on a single goal.
|
|
23
|
+
- Context: Explain why the change is necessary. Transparency builds trust.
|
|
24
|
+
- Testing: Run all smoke tests and regression checks locally. We prioritize safety first.
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
### 3. Review Process
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# or: ruby benchmark/merge_coverage.rb
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
RSpec performance benchmarks (coverage merge + spec-quality peek; writes `tmp/benchmarks/profile_<sha>.log`):
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
bundle exec rake bench_performance
|
|
42
|
-
# optional: STACKPROF=1 or BENCHMARK_IPS=1 for spec/performance/profiling_spec.rb
|
|
43
|
-
# optional: BENCH_MEMORY=1 bundle exec rspec spec/performance/benchmark_merge_spec.rb spec/performance/benchmark_spec.rb --tag benchmark
|
|
44
|
-
# optional env: BENCH_LINE_COUNT_REPS, BENCH_MEMORY_REPS
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Run the suite under alternate Ruby constraints (see `Appraisals` and `gemfiles/`):
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
bundle exec appraisal ruby32 rspec
|
|
51
|
-
bundle exec appraisal ruby34 rspec
|
|
52
|
-
bundle exec appraisal ruby40 rspec
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Linting
|
|
56
|
-
|
|
57
|
-
[RuboCop](https://rubocop.org/) with [Standard](https://github.com/standardrb/standard) style, plus `rubocop-rspec` and `rubocop-thread_safety`. Project-specific cop tweaks and metric `Exclude` lists live in `.rubocop.yml`.
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
bundle exec rubocop
|
|
61
|
-
bundle exec rubocop -a # safe autocorrect
|
|
62
|
-
bundle exec rake rubocop
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## RBS
|
|
66
|
-
|
|
67
|
-
Type signatures live under `sig/` and ship with the gem. Validate them after changes:
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
bundle exec rake rbs
|
|
71
|
-
# equivalent: bundle exec rbs -I sig validate
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Keep `require "polyrun"` free of RSpec/Minitest: optional wiring stays in `polyrun/rspec`, `polyrun/minitest`, and `polyrun/reporting/rspec_junit` (see README).
|
|
75
|
-
|
|
76
|
-
[Trunk](https://trunk.io/) aggregates RuboCop, YAML, Markdown, shellcheck, and more (see `.trunk/trunk.yaml`):
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
trunk check
|
|
80
|
-
trunk fmt
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
CI runs `rake ci` (RSpec + RuboCop). Optional Trunk workflow: `.github/workflows/trunk.yml`.
|
|
84
|
-
|
|
85
|
-
## Adopting Polyrun in other repos
|
|
86
|
-
|
|
87
|
-
- [docs/SETUP_PROFILE.md](docs/SETUP_PROFILE.md) — agent or human checklist (CI model A vs B, database, prepare).
|
|
88
|
-
- `bundle exec polyrun init --list` — lists starter `polyrun.yml` and `POLYRUN.md` templates (see `examples/templates/README.md`).
|
|
89
|
-
|
|
90
|
-
## Examples
|
|
91
|
-
|
|
92
|
-
Runnable demos live under `examples/`. After changing the gem, smoke them:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
cd examples && ./bin/ci_prepare
|
|
96
|
-
cd examples/simple/simple_demo && RAILS_ENV=test bundle exec rspec
|
|
97
|
-
# optional: complex polyrepo demo (multi-DB + three Vite clients + RSpec E2E)
|
|
98
|
-
# cd examples/complex/polyrepo_demo && RAILS_ENV=test bin/rails db:prepare && bundle exec rspec
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
See `examples/README.md`.
|
|
102
|
-
|
|
103
|
-
## Pull requests
|
|
104
|
-
|
|
105
|
-
- One logical change per PR when possible.
|
|
106
|
-
- Add or update specs for behavior changes.
|
|
107
|
-
- Run `bundle exec rake ci` before pushing.
|
|
28
|
+
- We encourage productive friction. Expect questions about your approach.
|
|
29
|
+
- If a reviewer suggests a change, view it as mutual aid, not criticism.
|
data/README.md
CHANGED
|
@@ -197,6 +197,19 @@ See [`examples/README.md`](examples/README.md) for Rails apps (Capybara, Playwri
|
|
|
197
197
|
|
|
198
198
|
You can replace SimpleCov and simplecov plugins, parallel_tests, and rspec_junit_formatter with Polyrun for those roles. Use `merge-timing`, `report-timing`, and `Data::FactoryCounts` (optionally with `Data::FactoryInstrumentation`) for slow-file and factory metrics. YAML fixture batches and bulk inserts can use `Data::Fixtures` and `ParallelProvisioning` for shard-aware seeding; wire your own `truncate` and `load_seed` in hooks.
|
|
199
199
|
|
|
200
|
+
## Links
|
|
201
|
+
|
|
202
|
+
- [GitHub](https://github.com/amkisko/polyrun.rb)
|
|
203
|
+
- [GitLab](https://gitlab.com/amkisko/polyrun.rb)
|
|
204
|
+
- [RubyGems](https://rubygems.org/gems/polyrun)
|
|
205
|
+
- [Versions Atom](https://rubygems.org/gems/polyrun/versions.atom) (feed id `10936755433440`)
|
|
206
|
+
- [libraries.io](https://libraries.io/rubygems/polyrun)
|
|
207
|
+
- [Deps.dev](https://deps.dev/rubygems/polyrun)
|
|
208
|
+
- [SonarCloud](https://sonarcloud.io/project/overview?id=amkisko_polyrun.rb)
|
|
209
|
+
- [Snyk](https://snyk.io/test/github/amkisko/polyrun.rb)
|
|
210
|
+
- [Codecov](https://app.codecov.io/github/amkisko/polyrun.rb)
|
|
211
|
+
- [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/amkisko/polyrun.rb)
|
|
212
|
+
|
|
200
213
|
## License
|
|
201
214
|
|
|
202
215
|
Released under the [MIT License](LICENSE). Copyright (c) 2026 Andrei Makarov.
|
data/SECURITY.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Reporting a Vulnerability
|
|
4
4
|
|
|
5
|
-
Do not open a public
|
|
5
|
+
Do not open a public issue for security vulnerabilities.
|
|
6
6
|
|
|
7
|
-
Email security details to security@kiskolabs.com
|
|
7
|
+
Email security details to: security@kiskolabs.com
|
|
8
8
|
|
|
9
9
|
Include: description, steps to reproduce, potential impact, and suggested fix (if available).
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ Include: description, steps to reproduce, potential impact, and suggested fix (i
|
|
|
21
21
|
- We will publish a security advisory after the vulnerability is patched
|
|
22
22
|
- We will coordinate public disclosure with you
|
|
23
23
|
|
|
24
|
-
## Automation
|
|
24
|
+
## Automation Security
|
|
25
25
|
|
|
26
|
-
- Context
|
|
27
|
-
- Supply
|
|
26
|
+
- Context Isolation: It is strictly forbidden to include production credentials, API keys, or Personally Identifiable Information (PII) in prompts sent to third-party LLMs or automation services.
|
|
27
|
+
- Supply Chain: All automated dependencies must be verified.
|
|
@@ -101,7 +101,7 @@ module Polyrun
|
|
|
101
101
|
return rows_from_jsonl_file(path)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
text = File.read(path)
|
|
104
|
+
text = File.read(path, encoding: Encoding::UTF_8)
|
|
105
105
|
data =
|
|
106
106
|
begin
|
|
107
107
|
JSON.parse(text)
|
|
@@ -126,7 +126,7 @@ module Polyrun
|
|
|
126
126
|
|
|
127
127
|
def rows_from_jsonl_file(path)
|
|
128
128
|
acc = []
|
|
129
|
-
File.readlines(path, chomp: true).each_with_index do |line, idx|
|
|
129
|
+
File.readlines(path, chomp: true, encoding: Encoding::UTF_8).each_with_index do |line, idx|
|
|
130
130
|
line = line.strip
|
|
131
131
|
next if line.empty?
|
|
132
132
|
|
data/lib/polyrun/version.rb
CHANGED
|
@@ -66,7 +66,8 @@ module Polyrun
|
|
|
66
66
|
err: err_write
|
|
67
67
|
)
|
|
68
68
|
else
|
|
69
|
-
|
|
69
|
+
# Array(cmd) so a String command is one argv element (not character-splatted).
|
|
70
|
+
Process.spawn(child_env, *Array(cmd), *Array(paths), out: out_write, err: err_write)
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
out_write.close
|
|
@@ -137,7 +138,7 @@ module Polyrun
|
|
|
137
138
|
forwarder.consume(stream, io.readpartial(4096))
|
|
138
139
|
end
|
|
139
140
|
rescue IOError, Errno::EPIPE
|
|
140
|
-
|
|
141
|
+
drain_remaining_output(io, forwarder, stream)
|
|
141
142
|
ensure
|
|
142
143
|
io.close unless io.closed?
|
|
143
144
|
end
|
|
@@ -145,13 +146,25 @@ module Polyrun
|
|
|
145
146
|
end
|
|
146
147
|
private_class_method :forwarder_thread
|
|
147
148
|
|
|
149
|
+
# EOFError subclasses IOError; keep drain rescues separate so a closed pipe
|
|
150
|
+
# during the final read does not escape the forwarder thread.
|
|
151
|
+
def drain_remaining_output(io, forwarder, stream)
|
|
152
|
+
remaining = io.read
|
|
153
|
+
forwarder.consume(stream, remaining) if remaining && !remaining.empty?
|
|
154
|
+
rescue IOError, Errno::EPIPE
|
|
155
|
+
nil
|
|
156
|
+
end
|
|
157
|
+
private_class_method :drain_remaining_output
|
|
158
|
+
|
|
148
159
|
def drain_forwarders(entry)
|
|
160
|
+
# Join first so threads can drain pipe buffers after the child exits.
|
|
161
|
+
# Closing read ends before join races and can drop the final bytes.
|
|
162
|
+
entry[:threads].each(&:join)
|
|
149
163
|
entry[:ios].each do |io|
|
|
150
164
|
io.close unless io.closed?
|
|
151
165
|
rescue IOError
|
|
152
166
|
nil
|
|
153
167
|
end
|
|
154
|
-
entry[:threads].each(&:join)
|
|
155
168
|
entry[:forwarder].close
|
|
156
169
|
end
|
|
157
170
|
private_class_method :drain_forwarders
|
data/polyrun.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.summary = "Parallel tests, coverage (SimpleCov-compatible) formatters, fixtures/snapshots, assets & DB provisioning—zero runtime deps"
|
|
9
9
|
spec.homepage = "https://github.com/amkisko/polyrun.rb"
|
|
10
10
|
spec.license = "MIT"
|
|
11
|
-
spec.required_ruby_version = ">= 3.
|
|
11
|
+
spec.required_ruby_version = ">= 3.4"
|
|
12
12
|
|
|
13
13
|
spec.files = (
|
|
14
14
|
Dir["lib/**/*", "sig/**/*.rbs", "bin/polyrun", "README.md", "CHANGELOG.md", "docs/SETUP_PROFILE.md", "LICENSE", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "SECURITY.md", "polyrun.gemspec"] +
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: polyrun
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.
|
|
4
|
+
version: 2.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -393,14 +393,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
393
393
|
requirements:
|
|
394
394
|
- - ">="
|
|
395
395
|
- !ruby/object:Gem::Version
|
|
396
|
-
version: 3.
|
|
396
|
+
version: '3.4'
|
|
397
397
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
398
398
|
requirements:
|
|
399
399
|
- - ">="
|
|
400
400
|
- !ruby/object:Gem::Version
|
|
401
401
|
version: '0'
|
|
402
402
|
requirements: []
|
|
403
|
-
rubygems_version: 4.0.
|
|
403
|
+
rubygems_version: 4.0.6
|
|
404
404
|
specification_version: 4
|
|
405
405
|
summary: Parallel tests, coverage (SimpleCov-compatible) formatters, fixtures/snapshots,
|
|
406
406
|
assets & DB provisioning—zero runtime deps
|