Repository navigation
feat(api): use the Trunk API v2 when Trunk chooses it (TRUNK-21083) - #1256
Conversation
|
😎 Merged successfully - details. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1256 +/- ##
==========================================
+ Coverage 84.00% 84.64% +0.63%
==========================================
Files 74 78 +4
Lines 18019 18633 +614
==========================================
+ Hits 15136 15771 +635
+ Misses 2883 2862 -21 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
|
@claude review |
Independent reviewNothing here blocks merging. The routing logic is solid: v1 is the default, the version check fails open, v2 never falls back to v1, and the disk cache keeps v1 and v2 entries in separate files. The new Worth fixing1. Every plugin process now asks Trunk which API to use before reading the quarantine disk cache (
2.
Minor
🤖 Generated with Claude Code |
|
Thanks. Addressed in 82eab55:
|
|
One more change, and it needs a deploy order. The v2 quarantine lookup now sends only each test's Order: trunk-io/trunk2#7531 must be live in production before any run uses v2 with this build. Until #7531 deploys, v2 still requires |
TylerJang27
left a comment
There was a problem hiding this comment.
A few spec contention points at the beginning. Almost there
Before a run looks up quarantine or uploads, ask POST /v1/metrics/getUploadApiVersion which API to use (2 s timeout, no retry; anything but an explicit "v2" is v1). On v2 the CLI and the test-runner plugins call quarantine-status (batched by 2,000), all-quarantined-tests (limit=25000, matched by computed test GUID) and uploads, with the token as a bearer credential. A failed v2 call is reported, never retried on v1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eal forks - test_report keeps the chosen API on disk with the quarantine cache's TTL, and publish reads it, so worker processes and the uploading process agree and a cached run makes no extra call. - isForkPr comes from the GitHub event (head and base repositories differ) or CircleCI's CIRCLE_PR_NUMBER, not from --allow-forked-pr-uploads. - A dry run uses v1 without asking. - Paging all-quarantined-tests stops with an error on a repeated cursor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v2 matches an identifier with an id by the id alone, so the names only added bytes: about 389 KB for 2,000 failures becomes about 80 KB. Needs trunk-io/trunk2#7531, which stops requiring name and parentName beside an id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review (Tyler Jang): - A test runner pages all-quarantined-tests by repository coordinates and reads the scope from the page, with no quarantine-status call first. - The v2 upload reads the collection UUID from its own response, so the client no longer caches it from an earlier lookup, and a run with no lookup still gets GUID links. - The CLI's lookup and a runner's whole set return their own types (QuarantineLookup, QuarantinedTestSet), so the v1 wire type keeps no skipped v2 fields. A lookup of no tests makes no request. - The v2 upload body borrows the request's fields instead of cloning them. - The API version check retries once after a timeout, connection error or 5xx, so a slow answer costs at most 4s. Needs trunk-io/trunk2#7589 deployed first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tory as null all-quarantined-tests is now a POST whose body names the repository as quarantine-status's does; the cursor and limit stay in the query. v2 refuses empty repository parts, so the upload, the lookup and the list all send null for an upload without a repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to api/tests
client.rs becomes client/{mod,v1,v2}.rs: mod.rs keeps the client, the
version check and the calls that choose an API; v1.rs and v2.rs hold each
version's requests. The v2 client tests move to api/tests/v2_client.rs on
MockServerBuilder, whose state now keeps the requests to the routes a test
adds. Also rewords QuarantinedTests::ByTestCaseGuid's doc comment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c9c7ecc to
0397c90
Compare
What
The CLI and the test-runner plugins move from the v1 upload and quarantine routes to v2, behind a server-side choice, so the rollout can be ramped and reversed without a release.
Choosing the API, once per run, before anything else.
ApiClient::get_upload_api_versioncallsPOST /v1/metrics/getUploadApiVersion(trunk-io/trunk#34794) with the CLI version, org slug, collection id, repository, CI provider, whether the run is a fork PR, andcaller(cliortest-runner-plugin)."v2"means v2.Using Trunk API v1/v2.On v2:
Authorization: Bearer.POST /v2/test-collections/{id}/quarantine-status, batched into requests of at most 2,000 identifiers, sending each test's id only. ItstestCollectionUuidandrepositoryIdturn the failure links into GUID links. A lookup of no tests makes no request.GET …/all-quarantined-tests?repoHost=…&repoOwner=…&repoName=…&limit=25000, readtestCollectionUuid,repositoryIdandquarantineEnabledfrom the page, and match each test by its computed GUID (gen_test_case_guid). Noquarantine-statuscall. The disk cache keeps v1 and v2 entries in separate files.POST /v2/test-collections/{id}/uploads. The bundle'sbundle_upload_id_v2(base64 of{id, createdAt, repoId}) and its test-collection fields are built from the response, which is what ingestion reads. The response'stestCollectionUuidgives the upload GUID links even when the run made no lookup.QuarantineLookupand a runner's whole setQuarantinedTestSet(api/src/quarantine.rs). Each API's wire types convert into them, so v1'sGetQuarantineConfigResponsecarries no v2 fields.Depends on trunk-io/trunk2#7611 (the list is a
POSTnaming the repository in its body). Merge and deploy it first. It follows trunk-io/trunk2#7589 (merged), where the list returns its scope and the upload returnstestCollectionUuid.run_uploadtakes the choice throughRunUploadOptions::upload_api_version, so a plugin's quarantine lookups and its upload use the same API.Formatting only: the
render_groupblock incli/src/upload_command.rs(about 90 lines) is reformatted, not changed.mainis not formatted under the pinned rustfmt, and the pre-committrunk fmtformats a modified file whole.Testing
api: the decision (request body, explicitv2, every v1 case, a slow answer, no call without a token or collection), the v2 upload mapping and bearer header, batching by 2,000, paging the quarantined set, no paging when quarantining is off, and no v1 call after a failed v2 lookup.cli/tests/upload.rs: an upload that runs end to end on v2, checking the bundle's metadata and that no v1 route is called.test_report/tests/quarantine.rs: a v2 run quarantines a test by its GUID.xunitupload tests, which fail the same way onmainin an environment without a Swift language server.Linear: TRUNK-21083
🤖 Generated with Claude Code