Skip to content

chore: Use CircleCI native timing-based test splitting for acceptance shards#6889

Open
danskmt wants to merge 1 commit into
mainfrom
chore/CLI-1482-circleci-native-test-splitting
Open

chore: Use CircleCI native timing-based test splitting for acceptance shards#6889
danskmt wants to merge 1 commit into
mainfrom
chore/CLI-1482-circleci-native-test-splitting

Conversation

@danskmt

@danskmt danskmt commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Pull Request Submission Checklist

  • Follows CONTRIBUTING guidelines
  • Commit messages are release-note ready, emphasizing what was changed, not how.
  • Includes detailed description of changes
  • Contains risk assessment (Low | Medium | High)
  • Highlights breaking API changes (if applicable)
  • Links to automated tests covering new functionality
  • Includes manual testing instructions (if necessary)
  • Updates relevant GitBook documentation (PR link: ___)
  • Includes product update to be announced in the next stable release notes

What does this PR do?

Replaces Jest's --shard with CircleCI's native circleci tests run --split-by=timings so acceptance test shards are automatically balanced by historic runtime data — no manually maintained weight files needed.

  • Replaces --shard=<index>/<total> with circleci tests glob | circleci tests run --split-by=timings --timings-type=file in the acceptance-tests job.
  • Adds addFileAttribute: true to jest-junit config so JUnit XML includes file="..." on each <testsuite>, which CircleCI needs for file-based timing matching.
  • Switches the Windows test step to bash.exe (from PowerShell) since the command uses xargs and Unix pipe syntax. Sources the bash-compatible env script (snyk-env.sh) instead of the PowerShell one.

Where should the reviewer start?

  • .circleci/config.yml — the acceptance-tests job definition (replaced shard_calc_cmd parameter with test_shell, new circleci tests run command)
  • package.jsonaddFileAttribute addition in jest-junit config

How should this be manually tested?

  1. Push branch and trigger CI.
  2. Check that acceptance tests run on all platforms (linux, macOS, Windows).
  3. Compare shard wall times — after 1-2 runs, CircleCI accumulates timing data and balances shards automatically.

What's the product update that needs to be communicated to CLI users?

None. CI-only change; no CLI behavior change for end users.

Risk assessment (Low | Medium | High)?

Medium — changes how tests are distributed across CI shards on all platforms including Windows (shell change). First run may use name-based splitting until CircleCI accumulates timing data from JUnit reports.

Any background context you want to provide?

CircleCI stores timing data per job name across all branches, so existing store_test_results uploads from main should provide immediate timing data. The addFileAttribute flag makes jest-junit emit the file attribute on each <testsuite>, enabling CircleCI to match timing history to spec files. See CircleCI docs: Test splitting and parallelism.

What are the relevant tickets?

CLI-1482

Screenshots (if appropriate)

Before (main) X Now (chore/CLI-1482-circleci-native-test-splitting):
imageimage

Before (feat/CLI-1482-balance-acceptance-test-shards) X Now (chore/CLI-1482-circleci-native-test-splitting)

imageimage

@snyk-io

snyk-io Bot commented Jun 9, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@danskmt danskmt force-pushed the chore/CLI-1482-circleci-native-test-splitting branch 9 times, most recently from be2b704 to cd2482b Compare June 11, 2026 07:31
@danskmt danskmt marked this pull request as ready for review June 11, 2026 08:20
@danskmt danskmt requested a review from a team as a code owner June 11, 2026 08:20
@snyk-pr-review-bot

This comment has been minimized.

Comment thread .circleci/config.yml Outdated
Comment on lines +1730 to +1734
- run:
name: Normalize junit file paths for timing data
when: always
shell: << parameters.test_shell >>
command: node scripts/normalize-junit-file-paths.js test/reports

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step is necessary because CircleCI doesn't automatically save paths like this for Windows:
test/jest/acceptance/snyk-code/snyk-code-user-journey.spec.ts

And then would mismatch, never finding the files, as CircleCI expects in this format.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: would this still be the case if we didn't use bash in Windows?

Write-Host "Failed to upgrade pip, continuing: $($_.Exception.Message)"
}

& $python.Path -m pip install uv

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth to get rid of uv for CI - maybe in a separate Jira

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmmh there is src/lib/plugins/uv/uv.spec.ts... let's forget about that jira

@robertolopezlopez robertolopezlopez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Good job

Comment thread package.json
"jest-junit": {
"reportTestSuiteErrors": "true"
"reportTestSuiteErrors": "true",
"addFileAttribute": "true"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this addFileAttribute: true to jest-junit config so JUnit XML includes file="..." on each , which CircleCI needs for file-based timing matching.

Comment thread .circleci/config.yml Outdated
Comment on lines 995 to 998
test_shell: bash.exe
pre_test_cmds: |
if (Test-Path '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>') { . '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>' }
if [ -f '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_bash_env_script >>' ]; then source '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_bash_env_script >>'; fi

@j-luong j-luong Jun 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: let's stick to the existing shell being used. changing the shell here leads to other issues (which you fixed in your other changes) that aren't necessary.

Comment thread .circleci/config.yml Outdated
default: 4
shard_calc_cmd:
default: 6
test_shell:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: same as above

Comment thread .circleci/config.yml Outdated
Comment on lines +1718 to +1723
circleci tests glob "test/jest/acceptance/**/*.spec.ts" "ts-binary-wrapper/test/acceptance/**/*.spec.ts" \
| node -e "let input='';process.stdin.on('data',c=>input+=c);process.stdin.on('end',()=>process.stdout.write(input.split(String.fromCharCode(92)).join('/')))" \
| circleci tests run \
--command="xargs npx jest --maxWorkers=1 --selectProjects coreCli --reporters=jest-junit --reporters=default --" \
--split-by=timings \
--timings-type=file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest: a few things.

node -e "let input='';process.stdin.on('data',c=>input+=c);process.stdin.on('end',()=>process.stdout.write(input.split(String.fromCharCode(92)).join('/')))" seems necessary because we're running bash in a Windows env. With the comments above, I think this is unnecessary.

We can follow the same pattern as << parameters.pre_test_cmds >> and introduce a << parameters.test_cmds >> to split Powershell vs Bash test commands.

@j-luong j-luong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think introducing bash as the shell for Windows causes more problems than it solves, let's see if we can do this without needing bash for Windows. That way we can clean up the extra scripts you introduced

@danskmt danskmt force-pushed the chore/CLI-1482-circleci-native-test-splitting branch 2 times, most recently from 9c558a5 to 1dc3634 Compare June 11, 2026 13:49
@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@danskmt danskmt force-pushed the chore/CLI-1482-circleci-native-test-splitting branch from 1dc3634 to c84875a Compare June 11, 2026 15:31
@snyk-pr-review-bot

This comment has been minimized.

@danskmt danskmt force-pushed the chore/CLI-1482-circleci-native-test-splitting branch from c84875a to 08d6deb Compare June 11, 2026 16:46
@snyk-pr-review-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

CI Hang Risk 🔴 [critical]

The test_cmd default (and the Windows override) incorrectly includes xargs within the --command flag for circleci tests run. According to CircleCI's documentation, circleci tests run partitions the test files and appends them as positional arguments to the command string automatically. By prefixing the command with xargs, the process will wait for input on stdin (which is not provided by the test runner), likely causing all acceptance test jobs to hang indefinitely and eventually time out.

find test/jest/acceptance ts-binary-wrapper/test/acceptance -name '*.spec.ts' \
  | circleci tests run \
      --command="xargs npx jest --maxWorkers=1 --selectProjects coreCli --reporters=jest-junit --reporters=default --" \
      --split-by=timings \
      --timings-type=file
Windows CI Failure 🟠 [major]

The Windows acceptance test configuration is broken and contradicts the PR description. The description states a switch to bash.exe, but the diff for the Windows job (lines 1003-1008) uses PowerShell cmdlets (Test-Path, Get-ChildItem, ForEach-Object). If the shell remains PowerShell, the command will fail because xargs is not a native Windows utility. If the shell is indeed switched to bash.exe (via a configuration not visible in the diff), the PowerShell cmdlets provided in the override will cause immediate execution errors.

pre_test_cmds: |
  if (Test-Path '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>') { . '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>' }
test_cmd: |
  Get-ChildItem -Recurse -Path test/jest/acceptance,ts-binary-wrapper/test/acceptance -Filter *.spec.ts |
    ForEach-Object { (Resolve-Path -Relative $_.FullName) -replace '\\', '/' -replace '^\./', '' } |
    circleci tests run --command "xargs npx jest --maxWorkers=1 --selectProjects coreCli --reporters=jest-junit --reporters=default --" --split-by=timings --timings-type=file
📚 Repository Context Analyzed

This review considered 7 relevant code sections from 5 files (average relevance: 0.67)

🤖 Repository instructions applied (from AGENTS.md)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants