Last active
April 21, 2025 21:04
-
-
Save jasonkarns/a0884cb7a5ff25c26e2cd2d339d57d66 to your computer and use it in GitHub Desktop.
Partition RSpec files across runners in a stable way to support deterministic sharding.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jobs: | |
build: | |
docker: [image: cimg/ruby:3.4.3] | |
parallelism: 4 | |
steps: | |
- checkout | |
- run: script/test spec:ci[$((${CIRCLE_NODE_INDEX}+1))/${CIRCLE_NODE_TOTAL}] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jobs: | |
test: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1, 2, 3, 4, 5] | |
steps: | |
- uses: actions/checkout | |
- uses: ruby/setup-ruby | |
- run: script/test spec:ci[${{ matrix.group }}/${{ strategy.job-total }}] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if defined?(RSpec) | |
SPECS = FileList[ENV.fetch "SPEC", RSpec::Core::RakeTask::DEFAULT_PATTERN].uniq | |
namespace :spec do | |
desc "Run default ci specs - no flaky specs [job='N/total' (default: 1/1)]" | |
RSpec::Core::RakeTask.new(:ci, [:job]) do |t, args| | |
args.with_defaults(job: "1/1") | |
group, total = args[:job].split("/").map(&:to_i) | |
# partition such that the grouping is stable regardless of file count | |
# hash the filename taking the first 64 bits as an int, modulo the number of groups | |
# offset by 1 b/c job number is 1-index (so that '5/5' makes sense) | |
ENV["SPEC"] = SPECS.select { |s| Digest::SHA2.digest(s).unpack1("Q") % total == group - 1 }.join(" ") | |
t.rspec_opts = %w[ | |
--tag ~flaky | |
--force-color | |
--format doc | |
--profile 2 | |
--warnings | |
] | |
end | |
desc "Run only flaky specs (need made deterministic or deleted)" | |
RSpec::Core::RakeTask.new(:flaky) do |t| | |
t.rspec_opts = %w[ | |
--tag flaky | |
--force-color | |
--format doc | |
] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Invocation of the rake task looks like:
rake spec:ci[1/4]