Skip to content

ci(cli): shard unit tests and merge coverage - #1727

Open
betegon wants to merge 8 commits into
bt/cli-e2e-parallelfrom
bt/cli-unit-shards
Open

betegon wants to merge 8 commits into
bt/cli-e2e-parallelfrom
bt/cli-unit-shards

Conversation

@betegon

@betegon betegon commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Runs the CLI unit tests in three parallel shards and merges their Vitest blob reports into one coverage report, instead of running the whole suite inside the sentry project job. Stacked on #1726.

Job #1726 (1b42251, unsharded) This PR (1608137)
Test workflow 10m18s 5m48s
sentry project job 9m57s 1m57s
CLI unit tests inside sentry 2m24s / 3m48s / 3m33s (3 shards)
CLI coverage merge inside sentry 0m25s
CLI E2E (Node 24) 4m30s 3m30s

Runs: #1726, this PR. One run each; workflow time is first job start to last job done. The last job to finish was CLI asset catalog (macOS arm64).

Shards install only the CLI and its workspace dependencies: 1,508 → 774 packages (pnpm install vs pnpm --filter 'sentry...' install, both --frozen-lockfile), with install scripts kept. Sharing preparation through artifacts was no faster in a one-off benchmark (4m41s vs 4m37s), so each job prepares its own inputs.

Same tests and coverage scope; CodeQL is unchanged. Drops the ci-projects tests that only asserted test.yml's own text or ran its bash from Node.

Recompute job times from any run
gh run view <run-id> -R getsentry/toolkit --json jobs --jq '.jobs[] | select(.name | test("^sentry$|^CLI")) | ((.completedAt | fromdate) - (.startedAt | fromdate)) as $s | "\($s / 60 | floor)m\($s % 60)s\t\(.name)"'

Generated by Claude Code

@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sentry-local Ready Ready Preview Oct 30, 2026 8:55pm UTC

Request Review

@BYK BYK left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the idea but we can squeeze more from here. I'd also explore optimization opportunities before sharding. Not saying we shouldn't be sharding but I'm sure there are things that would speed us up before sharding.

Comment thread .github/workflows/test.yml Resolved
Comment thread .github/workflows/test.yml Resolved
Comment on lines +236 to +238
- name: Build project dependencies
run: pnpm --filter 'sentry^...' --if-present run build
- run: pnpm --filter sentry run ci:prepare

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if this part can be cached/shared through artifacts to save time. We may even get incremental builds?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

tested shared preparation:

4m41s versus 4m37s with preparation in each shard (single run).
So it make sense to keep jobs independent for now. Haven't tested cross-run build caching and incremental build. we'll look into it later

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do I not believe you now. Opus 5.5 can you get me fresh and true numbers with details please?

Comment thread .github/workflows/test.yml Resolved
Comment thread .github/workflows/test.yml Resolved
Comment thread .github/workflows/test.yml Outdated
Comment on lines +265 to +271
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ env.NODE_VERSION_22 }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need all this crap only to merge coverage reports? What are we even doing here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

trimmed this to a CLI-only install with scripts disabled. Node/pnpm are still needed to run vitest's report merge. the final job takes about ~30s

- run: pnpm --filter sentry run ci:prepare
- name: Build standalone CLI
run: pnpm --filter sentry run build
run: pnpm --filter sentry run tsx script/build.ts --single

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You know tsx is the evil, right? We should do this or something like that: https://nodejs.org/learn/typescript/run-natively

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

the build script we had already used tsx. this calls the same final step directly to avoid repeating dependency builds and generation.

for switching to node we need to adapt existing imports, so i'd do it in a separate PR

Comment thread scripts/ci-projects.test.mjs Outdated
});

it("requires CLI E2E success when selected and a skip otherwise", () => {
it("requires every selected CLI test job and rejects unexpected skips", () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Lol, we should just make this a silly bash script and get rid of the nodejs overhead :D

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

ok here do you mean replacing the Node → YAML → Bash test plumbing or simplifying the project selection script?

it takes ~0.2s but it could be good to remove layers if you're referring to the first

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's not about time, it's simplicity as you mentioned.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) Agreed. 1608137 removes the Node → YAML → Bash layer: this test, the asset-catalog gate test that used the same trick, and the regex checks on test.yml are all gone. What's left in ci-projects.test.mjs tests the discovery script's own logic.


Generated by Claude Code

@BYK BYK left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

would love for you to address my comments before merging

Comment thread .github/workflows/test.yml Outdated
needs: discover-projects
if: contains(fromJSON(needs.discover-projects.outputs.matrix).include.*.name, 'sentry')
runs-on: ubuntu-latest
timeout-minutes: 30

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

30 minutes, really?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) Fair. The shards took 2m43s to 4m21s across the last three runs, so 1c131fc lowers the timeout to 10 minutes, the same as the coverage merge job.


Generated by Claude Code

Comment thread .github/workflows/test.yml Resolved
Comment thread packages/cli/package.json Outdated
Comment on lines +54 to +58
"coverage": false,
"e2e": false,
"npmRuntime": "bundle",
"policy": "ci:policy",
"test": "ci:test:unit",
"test": false,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What exactly are these?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) Two of them did nothing. coverage: false already follows from test: false, and discovery picks ci:policy by default, so 97591cf drops both; the generated matrix is identical. The rest do something: build, e2e and test are false because dedicated CLI jobs run them, npmRuntime names the npm build, and typecheck picks ci:typecheck so the project job doesn't regenerate everything.


Generated by Claude Code

Comment thread scripts/ci-projects.test.mjs Outdated
Comment on lines +4 to +8
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
writeFileSync,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All file I/O should be async, ideally promisified.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) After 1608137 the file no longer reads or writes any files, so there's no I/O left to make async.


Generated by Claude Code

Comment thread scripts/ci-projects.test.mjs Outdated
});

it("runs CLI E2E independently after project discovery", () => {
it("runs three CLI unit shards and E2E independently after discovery", () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

okay delete this test please, wtf is this checking the existing file???

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) Deleted in 1608137.


Generated by Claude Code

Comment thread scripts/ci-projects.test.mjs Outdated
}
});

it("rejects missing or empty shard reports before merging coverage", () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I'm Opus 5.5) Deleted too, in 1608137.


Generated by Claude Code

Comment thread scripts/ci-projects.test.mjs Outdated
});

it("requires CLI E2E success when selected and a skip otherwise", () => {
it("requires every selected CLI test job and rejects unexpected skips", () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's not about time, it's simplicity as you mentioned.

@BYK

BYK commented Oct 30, 2026

Copy link
Copy Markdown
Member

You may wanna update the numbers in PR desc before merging

betegon and others added 3 commits October 30, 2026 20:52
The shards took 2m43s to 4m21s across the last three runs, so a 30-minute
timeout only delayed failure on a hung shard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017M6odVf4dibAURdbCfXv4q
`coverage: false` already follows from `test: false`, and discovery picks
`ci:policy` by default. The generated matrix is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017M6odVf4dibAURdbCfXv4q
Remove the tests that matched workflow text with regexes or extracted its
bash and ran it from Node, and the asserts that mirrored package.json values.
The remaining tests cover ci-projects.mjs logic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017M6odVf4dibAURdbCfXv4q

betegon commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

You may wanna update the numbers in PR desc before merging

(I'm Opus 5.5) Updated. The description now compares the Test run on 1608137 with #1726's latest run (10m18s → 5m48s), with links to both and a gh command to recompute. The old 7m07s came from a temporary benchmark workflow that's no longer on the branch.


Generated by Claude Code

This branch was successfully deployed

1 active deployment
Preview — 16081372 Deployed Oct 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants