Adopt cached Nx CI and automated releases - #12
Conversation
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR adds Nx-based repository validation, Changesets release configuration, partitioned benchmark CI, shared GitHub setup, release-state checks, artifact publication, changelog synchronization, and workflow contract tests. ChangesCharts infrastructure
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)
166-171: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDisable automatic npm caching in the privileged release workflow.
cache: ''only clears the explicit cache input; it does not disable the newer automatic npm caching path inactions/setup-nodev4+. Setpackage-manager-cache: falseon the release job’ssetup-nodestep if the publish/release job runs automatically, or omit the setup step entirely if Node is not needed for the release creation step.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release.yml around lines 166 - 171, Update the “Setup Node” step in the release workflow to explicitly set package-manager-cache to false, preventing automatic npm caching while preserving the existing Node and registry configuration.Source: Linters/SAST tools
🧹 Nitpick comments (7)
.github/actions/setup/action.yml (1)
25-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDerive the Playwright cache key from the lockfile.
The key hardcodes
1.62.0. If the Playwright version changes inpnpm-lock.yamland this string is not updated, the cache hits,Install Chromiumis skipped, and the runner uses browsers built for the previous version.♻️ Proposed cache key
- key: ${{ runner.os }}-playwright-1.62.0 + key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/setup/action.yml around lines 25 - 36, Update the playwright-cache step’s key to derive its Playwright version from pnpm-lock.yaml instead of hardcoding 1.62.0, ensuring lockfile version changes produce a distinct cache key and trigger Install Chromium when needed. Preserve the existing runner OS prefix and cache path.scripts/ci-workflow.test.mjs (1)
282-295: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winExtend the pin check to composite actions and accept only exact SHA lengths.
Two gaps:
- The check reads only
chart-library-benchmarks.yml..github/actions/setup/action.ymlalso uses external actions, and itsactions/cachepin is 41 characters, which is not a valid SHA. The test passes today.{40,64}accepts any length between 40 and 64, including 41. Use(?:[0-9a-f]{40}|[0-9a-f]{64})so only SHA-1 and SHA-256 lengths pass.♻️ Proposed check
+const setupAction = await readFile( + resolve(import.meta.dirname, '../.github/actions/setup/action.yml'), + 'utf8', +) + function assertPinnedExternalActions(source) { const uses = [...source.matchAll(/^\s*uses:\s*([^\s#]+)\s*(?:#.*)?$/gm)].map( (match) => match[1], ) assert.ok(uses.length > 0, 'workflow must use actions') for (const action of uses) { if (action.startsWith('./')) continue assert.match( action, - /@[0-9a-f]{40,64}$/, + /@(?:[0-9a-f]{40}|[0-9a-f]{64})$/, `${action} must be pinned to an immutable commit`, ) } }Then call
assertPinnedExternalActions(setupAction)alongside the workflow assertion at Line 25.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci-workflow.test.mjs` around lines 282 - 295, Update assertPinnedExternalActions to accept only 40- or 64-character hexadecimal commit SHAs, replacing the ranged length check with exact SHA-1/SHA-256 alternatives. Load the contents of .github/actions/setup/action.yml and invoke assertPinnedExternalActions for it alongside the existing workflow assertion so composite-action references are validated too.scripts/check-framework-adapters.mjs (1)
73-88: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winDuplicated worker pool without fail-fast in
scripts/check-framework-adapters.mjsandscripts/compare-chart-libraries.mjs. Both sites implement the same index-pulling pool, andscripts/publish-release.mjsholds a third copy. In all copies, a rejection in one worker does not stop the remaining workers, so builds keep starting while cleanup runs.
scripts/check-framework-adapters.mjs#L73-L88: add an abort flag torunWithConcurrency, then move it into a shared module such asscripts/benchmark/concurrency.mjs.scripts/compare-chart-libraries.mjs#L281-L296: replace the inline loop inbuildCaseswith an import of the shared helper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/check-framework-adapters.mjs` around lines 73 - 88, Extract runWithConcurrency into a shared concurrency module and add fail-fast behavior using an abort flag so a rejected operation prevents workers from starting further operations; preserve the existing concurrency limit and propagate the rejection. In scripts/check-framework-adapters.mjs#L73-L88, replace the local implementation with the shared helper import. In scripts/compare-chart-libraries.mjs#L281-L296, replace the inline worker loop in buildCases with the same helper import. Do not modify scripts/publish-release.mjs#L? unless separately required by the shared-helper extraction..github/workflows/release.yml (1)
46-55: 🩺 Stability & Availability | 🔵 TrivialConfirm that the version pull request can satisfy branch protection.
changesets/actionusessecrets.GITHUB_TOKEN. GitHub does not start new workflow runs for commits or pull requests created with that token. Theci: Version Packagespull request therefore gets noChart library benchmarksrun and noCIcheck.If
CIis a required status check onmain, the version pull request cannot merge without manual intervention. Use a GitHub App token or a dedicated PAT for this job, or exempt this bot pull request from the required check.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release.yml around lines 46 - 55, Update the changesets/action authentication in the “Create or update version pull request” step so it uses a GitHub App token or dedicated PAT that can trigger workflows, instead of secrets.GITHUB_TOKEN; alternatively configure branch protection to exempt this bot pull request from the required CI and Chart library benchmarks checks.scripts/verify-ci-success.mjs (1)
20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared release repository slug.
scripts/release-security.mjsexportsreleaseRepositorySlug, and releases use it. Import that constant from./release-security.mjsinverify-ci-success.mjsinstead of duplicating'TanStack/charts'so the repository requires fewer edit points.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/verify-ci-success.mjs` around lines 20 - 24, Update the repository assertion in verify-ci-success.mjs to import and use the shared releaseRepositorySlug exported by release-security.mjs instead of the hardcoded 'TanStack/charts' value, preserving the existing CI gate validation.scripts/publish-release.mjs (1)
99-99: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueShare one
runWithConcurrencyimplementation.
scripts/publish-release.mjsuses(values, concurrency, operation), whilescripts/check-framework-adapters.mjsuses(operations, concurrency)where each operation is a thunk. Keep helper implementations separate, export distinct shared helpers, or rename the current helpers until the call sites use one contract.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/publish-release.mjs` at line 99, Unify the runWithConcurrency contract used by scripts/publish-release.mjs and scripts/check-framework-adapters.mjs: both call sites must use the same argument shape and operation semantics. Share a single implementation, or rename/export distinct helpers to avoid conflicting definitions, then update each caller accordingly while preserving existing concurrency behavior.scripts/release-workflow.test.mjs (1)
162-239: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the shared workflow contract helpers into one module.
scripts/ci-workflow.test.mjsandscripts/release-workflow.test.mjsboth definejob,needs,scalarList,assertPinnedExternalActions,indentation, andescapeRegExp. Move these helpers to a shared file such asscripts/workflow-contract.mjsand import them from both tests.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/release-workflow.test.mjs` around lines 162 - 239, Extract job, needs, scalarList, assertPinnedExternalActions, indentation, and escapeRegExp from both workflow test files into a shared scripts/workflow-contract.mjs module, exporting each helper. Remove the duplicate definitions and import the shared helpers in scripts/ci-workflow.test.mjs and scripts/release-workflow.test.mjs, preserving their existing behavior and assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/actions/setup/action.yml:
- Line 17: Update both actions/cache references in the workflow to use the valid
40-character commit SHA 668228422ae6a00e4ad889ee87cd7109ec5666a7, removing the
trailing d while preserving the v5.0.4 pin comment.
In @.github/workflows/chart-library-benchmarks.yml:
- Around line 118-120: Update the “Publish comparison summary” step and the
conformance summary step to tolerate an empty results glob. Ensure the cat
command does not receive a literal unmatched pattern and does not fail when no
.md files exist, while preserving the current append-to-GITHUB_STEP_SUMMARY
behavior when files are present.
In `@package.json`:
- Around line 11-13: Define separate Nx projects for each package with a ci
target so ci:all and ci:pr operate on a multi-project graph and ci:pr can
exclude unaffected packages; otherwise remove the ci:all and ci:pr scripts from
the package scripts until those project definitions exist.
In `@scripts/publish-release.mjs`:
- Around line 99-110: Update runWithConcurrency to wait for every worker to
settle before propagating failure: collect each worker promise with
Promise.allSettled (or equivalent), gather all rejected worker errors, and throw
an aggregated error only after all operations finish. Preserve the existing
concurrency limit and operation ordering behavior.
In `@scripts/release-package-config.mjs`:
- Around line 109-115: Update assertStableReleaseVersion in
scripts/release-package-config.mjs:109-115 to require each numeric component to
match 0|[1-9]\d*, rejecting leading-zero versions while preserving valid stable
versions. Add a rejected 01.2.3 case in
scripts/release-package-config.test.mjs:15-19.
In `@scripts/release-status.mjs`:
- Around line 51-57: Update the tag-revision validation in classifyReleaseStatus
so an existing tag (tagRevision !== null) requires expectedRevision and cannot
bypass the equality guard when the value is undefined or empty; preserve the
existing matching-revision behavior and reject the missing-value case. Add a
release-status test covering a set tagRevision with expectedRevision omitted.
In `@scripts/verify-ci-success.mjs`:
- Around line 32-41: The external API requests lack deadlines, allowing stalled
responses to block release jobs. Add signal: AbortSignal.timeout(30_000) to the
workflow-runs fetch in scripts/verify-ci-success.mjs, and to the fetch calls
used by readRegistryPackage, readLatestVersion, and githubReleaseExists in
scripts/release-status.mjs; preserve their existing request behavior otherwise.
In `@scripts/verify-ci-success.test.mjs`:
- Around line 19-22: Update the invalid candidate fixtures in the verification
test to include runs with non-main head_branch and non-completed status values,
while keeping the existing invalid cases. Ensure the release-gate filtering
exercised by the test depends on both head_branch and status predicates so
removing either predicate causes the test to fail.
---
Outside diff comments:
In @.github/workflows/release.yml:
- Around line 166-171: Update the “Setup Node” step in the release workflow to
explicitly set package-manager-cache to false, preventing automatic npm caching
while preserving the existing Node and registry configuration.
---
Nitpick comments:
In @.github/actions/setup/action.yml:
- Around line 25-36: Update the playwright-cache step’s key to derive its
Playwright version from pnpm-lock.yaml instead of hardcoding 1.62.0, ensuring
lockfile version changes produce a distinct cache key and trigger Install
Chromium when needed. Preserve the existing runner OS prefix and cache path.
In @.github/workflows/release.yml:
- Around line 46-55: Update the changesets/action authentication in the “Create
or update version pull request” step so it uses a GitHub App token or dedicated
PAT that can trigger workflows, instead of secrets.GITHUB_TOKEN; alternatively
configure branch protection to exempt this bot pull request from the required CI
and Chart library benchmarks checks.
In `@scripts/check-framework-adapters.mjs`:
- Around line 73-88: Extract runWithConcurrency into a shared concurrency module
and add fail-fast behavior using an abort flag so a rejected operation prevents
workers from starting further operations; preserve the existing concurrency
limit and propagate the rejection. In
scripts/check-framework-adapters.mjs#L73-L88, replace the local implementation
with the shared helper import. In scripts/compare-chart-libraries.mjs#L281-L296,
replace the inline worker loop in buildCases with the same helper import. Do not
modify scripts/publish-release.mjs#L? unless separately required by the
shared-helper extraction.
In `@scripts/ci-workflow.test.mjs`:
- Around line 282-295: Update assertPinnedExternalActions to accept only 40- or
64-character hexadecimal commit SHAs, replacing the ranged length check with
exact SHA-1/SHA-256 alternatives. Load the contents of
.github/actions/setup/action.yml and invoke assertPinnedExternalActions for it
alongside the existing workflow assertion so composite-action references are
validated too.
In `@scripts/publish-release.mjs`:
- Line 99: Unify the runWithConcurrency contract used by
scripts/publish-release.mjs and scripts/check-framework-adapters.mjs: both call
sites must use the same argument shape and operation semantics. Share a single
implementation, or rename/export distinct helpers to avoid conflicting
definitions, then update each caller accordingly while preserving existing
concurrency behavior.
In `@scripts/release-workflow.test.mjs`:
- Around line 162-239: Extract job, needs, scalarList,
assertPinnedExternalActions, indentation, and escapeRegExp from both workflow
test files into a shared scripts/workflow-contract.mjs module, exporting each
helper. Remove the duplicate definitions and import the shared helpers in
scripts/ci-workflow.test.mjs and scripts/release-workflow.test.mjs, preserving
their existing behavior and assertions.
In `@scripts/verify-ci-success.mjs`:
- Around line 20-24: Update the repository assertion in verify-ci-success.mjs to
import and use the shared releaseRepositorySlug exported by release-security.mjs
instead of the hardcoded 'TanStack/charts' value, preserving the existing CI
gate validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 64db67d1-6e8d-484f-9639-d0892bf549eb
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (35)
.changeset/README.md.changeset/config.json.github/actions/setup/action.yml.github/workflows/chart-library-benchmarks.yml.github/workflows/release.yml.gitignore.nvmrcAPI-FRICTION.mdCONTRIBUTING.mdREADME.mdnx.jsonpackage.jsonpnpm-workspace.yamlproject.jsonscripts/benchmark/filters.mjsscripts/benchmark/filters.test.mjsscripts/check-framework-adapters.mjsscripts/ci-workflow.test.mjsscripts/compare-chart-libraries.mjsscripts/compare-plot-catalog.mjsscripts/publish-release.mjsscripts/release-package-config.mjsscripts/release-package-config.test.mjsscripts/release-security.mjsscripts/release-security.test.mjsscripts/release-status.mjsscripts/release-status.test.mjsscripts/release-workflow.test.mjsscripts/sync-release-changelog.mjsscripts/sync-release-changelog.test.mjsscripts/verify-ci-success.mjsscripts/verify-ci-success.test.mjsscripts/vitest-config.test.mjsscripts/write-release-notes.mjsvitest.config.ts
| async function runWithConcurrency(values, concurrency, operation) { | ||
| let nextIndex = 0 | ||
| await Promise.all( | ||
| Array.from({ length: Math.min(concurrency, values.length) }, async () => { | ||
| while (nextIndex < values.length) { | ||
| const index = nextIndex | ||
| nextIndex += 1 | ||
| await operation(values[index]) | ||
| } | ||
| }), | ||
| ) | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Let all workers settle before the publication step fails.
Promise.all rejects as soon as one worker throws. The other workers continue, and the module-level await rejects, so Node exits while an npm publish request is still in flight. The reported error also hides failures from the remaining workers.
Wait for every worker, then throw an aggregated error.
🛡️ Proposed fix
async function runWithConcurrency(values, concurrency, operation) {
let nextIndex = 0
- await Promise.all(
+ const results = await Promise.allSettled(
Array.from({ length: Math.min(concurrency, values.length) }, async () => {
while (nextIndex < values.length) {
const index = nextIndex
nextIndex += 1
await operation(values[index])
}
}),
)
+ const failures = results
+ .filter((result) => result.status === 'rejected')
+ .map((result) => result.reason)
+ if (failures.length > 0) {
+ throw new AggregateError(failures, 'Artifact publication failed')
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async function runWithConcurrency(values, concurrency, operation) { | |
| let nextIndex = 0 | |
| await Promise.all( | |
| Array.from({ length: Math.min(concurrency, values.length) }, async () => { | |
| while (nextIndex < values.length) { | |
| const index = nextIndex | |
| nextIndex += 1 | |
| await operation(values[index]) | |
| } | |
| }), | |
| ) | |
| } | |
| async function runWithConcurrency(values, concurrency, operation) { | |
| let nextIndex = 0 | |
| const results = await Promise.allSettled( | |
| Array.from({ length: Math.min(concurrency, values.length) }, async () => { | |
| while (nextIndex < values.length) { | |
| const index = nextIndex | |
| nextIndex += 1 | |
| await operation(values[index]) | |
| } | |
| }), | |
| ) | |
| const failures = results | |
| .filter((result) => result.status === 'rejected') | |
| .map((result) => result.reason) | |
| if (failures.length > 0) { | |
| throw new AggregateError(failures, 'Artifact publication failed') | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/publish-release.mjs` around lines 99 - 110, Update runWithConcurrency
to wait for every worker to settle before propagating failure: collect each
worker promise with Promise.allSettled (or equivalent), gather all rejected
worker errors, and throw an aggregated error only after all operations finish.
Preserve the existing concurrency limit and operation ordering behavior.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/verify-published-release.mjs`:
- Line 202: Update waitForAttestations() to catch fetch errors caused by
AbortSignal.timeout(requestTimeout), call delay(), and continue polling;
preserve the existing behavior of stopping on non-timeout failures. Add coverage
for an initial timed-out attestation request followed by a successful later
request.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 70aa9748-6008-4b13-85a9-c635119c6f02
📒 Files selected for processing (31)
.changeset/compact-axis-titles.md.changeset/config.json.github/actions/setup/action.yml.github/workflows/chart-library-benchmarks.yml.github/workflows/release.ymlAPI-FRICTION.mdbenchmarks/bundle-size/universal-baseline.jsonbenchmarks/comparison/bundle-baseline.jsonbenchmarks/conformance/cases/04-stacked-time-area/tanstack.tsbenchmarks/conformance/cases/21-streamgraph/tanstack.tsbenchmarks/conformance/cases/54-bump-ranking/tanstack.tsdocs/comparison.mdpackage.jsonpackages/charts-core/docs/comparison.mdpackages/charts-core/src/scene-layout.test.tspackages/charts-core/src/scene.tspackages/octane-charts/src/CanvasChart.client.test.tsrxscripts/check-framework-adapters.mjsscripts/ci-workflow.test.mjsscripts/compare-chart-libraries.mjsscripts/publish-release.mjsscripts/release-package-config.mjsscripts/release-package-config.test.mjsscripts/release-status.mjsscripts/release-status.test.mjsscripts/release-workflow.test.mjsscripts/run-with-concurrency.mjsscripts/run-with-concurrency.test.mjsscripts/verify-ci-success.mjsscripts/verify-ci-success.test.mjsscripts/verify-published-release.mjs
💤 Files with no reviewable changes (4)
- benchmarks/conformance/cases/21-streamgraph/tanstack.ts
- benchmarks/conformance/cases/04-stacked-time-area/tanstack.ts
- benchmarks/conformance/cases/54-bump-ranking/tanstack.ts
- package.json
🚧 Files skipped from review as they are similar to previous changes (14)
- scripts/release-package-config.test.mjs
- scripts/verify-ci-success.test.mjs
- scripts/check-framework-adapters.mjs
- .github/actions/setup/action.yml
- scripts/release-package-config.mjs
- .changeset/config.json
- scripts/verify-ci-success.mjs
- scripts/release-status.test.mjs
- .github/workflows/chart-library-benchmarks.yml
- scripts/release-status.mjs
- .github/workflows/release.yml
- scripts/publish-release.mjs
- scripts/release-workflow.test.mjs
- scripts/ci-workflow.test.mjs
| const response = await fetch(url, { | ||
| headers: { accept: 'application/json' }, | ||
| redirect: 'error', | ||
| signal: AbortSignal.timeout(requestTimeout), |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
fd -a 'verify-published-release\.mjs$' . || true
echo "== file outline/size =="
wc -l scripts/verify-published-release.mjs
ast-grep outline scripts/verify-published-release.mjs --view expanded || true
echo "== relevant lines 160-230 =="
sed -n '160,230p' scripts/verify-published-release.mjs | nl -ba -v160
echo "== search requestTimeout / waitForAttestations / fetch usages =="
rg -n "requestTimeout|waitForAttestations|AbortSignal\.timeout|fetch\(" scripts/verify-published-release.mjsRepository: TanStack/charts
Length of output: 916
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== full relevant implementation around requestTimeout =="
python3 - <<'PY'
from pathlib import Path
p=Path('scripts/verify-published-release.mjs')
lines=p.read_text().splitlines()
for i,l in enumerate(lines,1):
if 'requestTimeout' in l or 'waitForAttestations' in l or 'AbortSignal.timeout' in l or 'fetch(' in l:
start=max(1,i-20); end=min(len(lines),i+35)
print(f"\n--- {p}:{start}-{end} ---")
for n in range(start,end+1):
print(f"{n}: {lines[n-1]}")
PY
echo "== behavioral model of current loop shape from source =="
python3 - <<'PY'
from pathlib import Path
import re
s=Path('scripts/verify-published-release.mjs').read_text()
m=re.search(r'async function waitForAttestations\(.*?\)\s*\{(?P<body>.*?)\n\b\}', s, re.S)
if not m:
m=re.search(r'function waitForAttestations\(.*?\)\s*\{(?P<body>.*?)\n\}', s, re.S)
print("found function:", bool(m))
print(m.group('body')[:2000] if m else "")
PYRepository: TanStack/charts
Length of output: 11020
🏁 Script executed:
#!/bin/bash
set -euo pipefail
node - <<'JS'
const url = new URL('data:text/plain,hello')
const timeoutMs = 10
let controller
try {
await fetch(url, {
signal: AbortSignal.timeout(timeoutMs),
})
console.log('FETCH_RESOLVED')
} catch (error) {
console.log(String(error.name) + ' ' + String(error.code) + ' ' + String(error.type))
controller = error
}
if (controller && controller.name === 'TimeoutError') {
console.log('timeout_matches')
} else {
console.log('timeout_mismatch')
}
JSRepository: TanStack/charts
Length of output: 1215
Retry timed-out attestation requests.
fetch can fail when AbortSignal.timeout(requestTimeout) expires, but waitForAttestations() has no error handling around the fetch(...). A timeout should call delay() and continue the polling loop; only non-timeout fetch failures should stop the polling. Add a test where an initial attestation request times out and a later request succeeds.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/verify-published-release.mjs` at line 202, Update
waitForAttestations() to catch fetch errors caused by
AbortSignal.timeout(requestTimeout), call delay(), and continue polling;
preserve the existing behavior of stopping on non-timeout failures. Add coverage
for an initial timed-out attestation request followed by a successful later
request.
What changed
CIaggregate check.Why
The previous workflow serialized browser suites behind a monolithic validation job, repeated test files through workspace symlinks, had no reusable local task cache, and required manual release orchestration. This gives local and CI runs the same cached graph while keeping browser measurements and revision-stamped artifacts uncached.
Validation
pnpm run validate— 112 test files / 567 tests plus format, docs, types, packages, bundles, and catalog gatespnpm test— 0.58s with 7/8 Nx tasks restoredchangeset status --since=origin/mainreports no package bump (infrastructure-only change)Summary by CodeRabbit
New Features
Bug Fixes
Documentation