fix(release): pre-build UI bundles of path-dependency crates - #747
Conversation
eval/v0.2.0-experimental died in every binary shard: panicked at harness/build.rs:50: SKIP_UI_BUILD set but harness/ui/dist/page.js is missing The SPA pre-build job only built the released worker's own frontend, but SKIP_UI_BUILD applies to the whole cargo build — any path-dependency crate with an injected console UI (eval → harness since MOT-4096) runs the same build.rs contract and finds no dist. The pre-build now scans the released worker's Cargo.toml for direct path dependencies and builds their ui/ bundles too. The artifact switches from worker-rooted to repo-rooted paths so each dist/ restores exactly where its crate's build.rs expects it.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe Rust binary workflow now discovers frontend bundles across the repository and direct path dependencies. It stages bundles with repository-relative paths and restores the artifact at the repository root for build shards. ChangesFrontend bundle artifact flow
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
skill-check — worker0 verified, 56 skipped (no docs/).
Four for four. Nicely done. |
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 @.github/workflows/_rust-binary.yml:
- Around line 166-170: Replace the regex-based Cargo.toml path extraction in the
dependency bundle loop with TOML parsing of the worker manifest’s
[dependencies.*].path entries. Resolve each parsed path relative to the worker
manifest, include only paths that remain within the repository, and preserve
adding directories containing ui/package.json to bundles so ui/dist builds are
not skipped.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a620a89d-ba95-4786-bbb7-3bec01386886
📒 Files selected for processing (1)
.github/workflows/_rust-binary.yml
| while IFS= read -r dep; do | ||
| if [[ -f "$dep/ui/package.json" ]]; then | ||
| bundles+=("$dep/ui") | ||
| fi | ||
| done < <(grep -oE 'path *= *"\.\./[A-Za-z0-9_-]+"' "$worker/Cargo.toml" | sed 's|.*"\.\./||; s|"||' | sort -u) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show release workflow callers and their manifest paths.
rg -n -C4 --glob '*.yml' --glob '*.yaml' \
'_rust-binary\.yml|manifest_path:' .github/workflows
# Show every Cargo path value and the directory it resolves to.
python3 - <<'PY'
from pathlib import Path
import re
root = Path.cwd().resolve()
pattern = re.compile(r'path\s*=\s*"([^"]+)"')
for manifest in sorted(root.rglob("Cargo.toml")):
for raw_path in pattern.findall(manifest.read_text()):
resolved = (manifest.parent / raw_path).resolve()
try:
relative = resolved.relative_to(root)
except ValueError:
relative = f"OUTSIDE_REPOSITORY: {resolved}"
print(f"{manifest.relative_to(root)}: {raw_path} -> {relative}")
PYRepository: iii-hq/workers
Length of output: 11087
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- workflow relevant section ---\n'
sed -n '110,210p' .github/workflows/_rust-binary.yml | cat -n
printf '\n--- manifest paths from workflow setup ---\n'
sed -n '1,120p' .github/workflows/release.yml | cat -n
printf '\n--- manifest path examples ---\n'
python3 - <<'PY'
from pathlib import Path
import re
root = Path.cwd().resolve()
pattern = re.compile(r'path\s*=\s*"([^"]+)"')
worker_manifests = Path.cwd() / ".github" / "setup.manifest-path"
if worker_manifests.exists():
print(worker_manifests.read_text())
for manifest in sorted(root.rglob("Cargo.toml")):
text = manifest.read_text()
found = re.findall(r'path\s*=\s*"([^"]+)"', text)
if found:
print(f"\n{manifest.relative_to(root)}")
for raw in found:
resolved = (manifest.parent / raw).resolve()
try:
relative = resolved.relative_to(root)
except ValueError:
relative = f"OUTSIDE_REPOSITORY: {resolved}"
print(f" {raw!r} -> {relative}")
PYRepository: iii-hq/workers
Length of output: 243
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- workflow setup variables ---'
rg -n -C3 'manifest|worker|SKIP_UI_BUILD|bundle|packages_to_cache|ui/package|restores-artifacts|bundles|dep_path' .github/workflows/_rust-binary.yml
printf '%s\n' '--- worker selection files ---'
sed -n '1,220p' .github/workflows/release.yml | cat -nRepository: iii-hq/workers
Length of output: 20226
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from collections import defaultdict
from pathlib import Path
import re
root = Path.cwd().resolve()
pattern = re.compile(r'path\s*=\s*"([^"]+)"')
by_level = defaultdict(list)
for manifest in sorted(root.rglob("Cargo.toml")):
text = manifest.read_text()
found = re.findall(r'path\s*=\s*"([^"]+)"', text)
if not found:
continue
for raw in found:
resolved = (manifest.parent / raw).resolve()
depth = len(Path(raw).parts)
by_level[depth].append(f"{manifest.relative_to(root)}: {raw!r} -> {resolved.relative_to(root)!r}")
print("Cargo path dependency levels and resolved paths:")
for depth, items in sorted(by_level.items()):
print(f"\ndepth={depth}:")
for item in sorted(set(items)):
print(f" {item}")
PYRepository: iii-hq/workers
Length of output: 10322
Resolve Cargo paths through TOML parsing before extending to the root.
Currently, crates/console-ui passes the root-level regex because it appears as ../crates/console-ui, but the parsing is still TOML-unsafe. If a dependency uses spaces, quoted keys, or inline [dependencies], this can treat invalid TOML as a package directory and skip the ui/dist build.
Use a TOML parser for the [dependencies.*].path entries, resolve each value against the worker manifest, and convert only repository-relative paths to bundles.
🤖 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/_rust-binary.yml around lines 166 - 170, Replace the
regex-based Cargo.toml path extraction in the dependency bundle loop with TOML
parsing of the worker manifest’s [dependencies.*].path entries. Resolve each
parsed path relative to the worker manifest, include only paths that remain
within the repository, and preserve adding directories containing
ui/package.json to bundles so ui/dist builds are not skipped.
The repo-rooted upload from #747 pointed upload-artifact at .release-frontend-bundle/ itself — and with the action's default include-hidden-files: false, a dot-directory as the glob root excludes everything: 'No files were found'. The previous layout only worked by accident because its search root was a child of the dot-directory. eval/v0.2.1-experimental built every bundle correctly (the dists are in the job log) and still shipped an empty artifact. Drop the dot: hidden semantics have no business in a CI staging path.
Failure
eval/v0.2.0-experimental died in every binary shard:
Cause
The Pre-build SPA bundle job builds only the released worker's frontend, but
SKIP_UI_BUILDapplies to the entire cargo build. Since MOT-4096,evalhas a path dependency on theharnesscrate — whosebuild.rsruns the same contract (dist must pre-exist under SKIP_UI_BUILD) and found nothing.Fix
Cargo.tomlfor directpath = "../…"dependencies and adds each one'sui/(when it has apackage.json) to the bundle list..release-frontend-bundle/<crate>/ui/dist, artifact uploaded repo-rooted, restored at./— everydist/lands exactly where its crate'sbuild.rsexpects.Verified locally: for
eval, the scan yieldsharness/ui ✓; for workers without UI deps the list is unchanged.Note
release.ymlruns from the tag's ref, so the in-flighteval/v0.2.0-experimentalcannot be fixed by re-run — after merge, cut the next version (0.2.1-experimental) through Release Control.Summary by CodeRabbit