Skip to content

juanri0s/sbt-sharding

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

sbt-sharding

GitHub Action that automatically shards Scala tests for parallel execution in CI.

Usage

Basic Example

name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4] # Number of shards
    steps:
      - uses: actions/checkout@v4 # Pin to exact commit SHA for production

      - name: Setup Scala
        uses: olafurpg/setup-scala@v13 # Pin to exact commit SHA for production

      - name: Shard Tests
        id: shard
        uses: juanri0s/sbt-sharding@v1 # Pin to exact commit SHA for production
        with:
          max-shards: 4
          shard-number: ${{ matrix.shard }}
          algorithm: round-robin

      - name: Run Tests
        run: sbt ${{ steps.shard.outputs.test-commands }}

Advanced Example

name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4, 5]
    steps:
      - uses: actions/checkout@v4 # Pin to exact commit SHA for production

      - name: Setup Scala
        uses: olafurpg/setup-scala@v13 # Pin to exact commit SHA for production

      - name: Shard Tests
        id: shard
        uses: juanri0s/sbt-sharding@v1 # Pin to exact commit SHA for production
        with:
          max-shards: 5
          shard-number: ${{ matrix.shard }}
          algorithm: round-robin
          test-pattern: '**/*Test.scala,**/*Spec.scala,**/*Suite.scala'

      - name: Run Tests
        if: steps.shard.outputs.test-files != ''
        env:
          JAVA_OPTS: -Xmx2g
        run: |
          echo "Running tests in shard ${{ matrix.shard }}/${{ steps.shard.outputs.total-shards }}"
          sbt ${{ steps.shard.outputs.test-commands }}

Inputs

Input Description Required Default
max-shards Maximum number of shards to split tests into Yes -
shard-number Current shard number (1-indexed). Should match matrix.shard when using matrix strategy. Defaults to 1. No 1
algorithm Sharding algorithm to use No round-robin
test-pattern Comma-separated glob patterns for test files No **/*Test.scala,**/*Spec.scala,**/Test*.scala,**/Spec*.scala
project-path Optional project directory path to filter test files. If provided, only test files within this directory will be included. No -

Outputs

Output Description
total-shards Total number of shards created
test-files Comma-separated list of test files to run in this shard
test-commands SBT commands to run tests for this shard (e.g., testOnly com.example.Test1 testOnly com.example.Test2)
shard-matrix JSON array of shard numbers for use in GitHub Actions matrix (e.g., [1,2,3])

Environment Variables

The action sets these environment variables for convenience:

  • SBT_TEST_FILES: Comma-separated list of test files
  • SBT_TEST_COMMANDS: SBT commands to run tests

Note: To set environment variables for your test execution, use the env key in your GitHub Actions workflow step, not this action.

Sharding Algorithms

round-robin (Default)

Distributes test files evenly across shards using round-robin distribution.

complexity

Distributes tests based on estimated complexity to balance execution time across shards.

Complexity factors:

  • Property tests: +3 points
  • Integration/container/E2E tests: +4 points
  • Unit tests: -1 point (minimum 1)
  • Files with many tests (>20): +2 points, (>10): +1 point
  • Large files (>5000 chars): +1 point

Tests are sorted by complexity (highest first) and distributed using a greedy bin-packing algorithm to balance total complexity across shards.

Requirements

  • Node.js 24+ (automatically provided by GitHub Actions)
  • pnpm 10+ (managed via corepack)
  • SBT project structure with test files in src/test/scala/ or similar

Building

Before using this action (or when developing), you need to build it:

corepack enable
pnpm install
pnpm run build

Monorepo Example

For monorepos with multiple projects, use the project-path input to scope test discovery to a specific project directory:

name: Test Monorepo

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        project: [projectA, projectB]
        shard: [1, 2, 3]
    steps:
      - uses: actions/checkout@v4 # Pin to exact commit SHA for production
      - name: Setup Scala
        uses: olafurpg/setup-scala@v13 # Pin to exact commit SHA for production
      - name: Shard Tests
        id: shard
        uses: juanri0s/sbt-sharding@v1 # Pin to exact commit SHA for production
        with:
          max-shards: 3
          shard-number: ${{ matrix.shard }}
          project-path: ${{ matrix.project }}
          test-pattern: '**/*Test.scala,**/*Spec.scala'
      - name: Run Tests
        if: steps.shard.outputs.test-files != ''
        run: sbt ${{ steps.shard.outputs.test-commands }}

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors