Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 33 additions & 20 deletions .github/workflows/_rust-binary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,21 +151,31 @@ jobs:
# A worker can have a web/ embedded SPA, a ui/ injected bundle, or
# both. Keep the relative paths so the download step can restore
# them exactly where each build.rs expects them.
frontends=()
bundles=()
if [[ -f "$worker/web/package.json" ]]; then
frontends+=(web)
bundles+=("$worker/web")
fi
if [[ -f "$worker/ui/package.json" ]]; then
frontends+=(ui)
bundles+=("$worker/ui")
fi
if [[ ${#frontends[@]} -eq 0 ]]; then
# Path dependencies compile inside this release too, and any of them
# with its own injected UI runs the same build.rs contract: under
# SKIP_UI_BUILD the dist/ must already exist. Missing this is exactly
# how eval/v0.2.0-experimental died — eval depends on the harness
# crate, whose ui/dist nobody had pre-built.
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)
Comment on lines +166 to +170

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ 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}")
PY

Repository: 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}")
PY

Repository: 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 -n

Repository: 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}")
PY

Repository: 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.

if [[ ${#bundles[@]} -eq 0 ]]; then
echo "::error::$worker has neither web/package.json nor ui/package.json; web_bundle=true requires one"
exit 1
fi
frontend_csv=$(IFS=,; echo "${frontends[*]}")
bundle_csv=$(IFS=,; echo "${bundles[*]}")
echo "worker=$worker" >> "$GITHUB_OUTPUT"
echo "frontends=$frontend_csv" >> "$GITHUB_OUTPUT"
echo "::notice::pre-building frontend bundle(s) in $worker/$frontend_csv"
echo "frontends=$bundle_csv" >> "$GITHUB_OUTPUT"
echo "::notice::pre-building frontend bundle(s): $bundle_csv"

# `pnpm/action-setup` must run before `setup-node` so that
# `setup-node`'s `cache: 'pnpm'` finds the binary on PATH. The pnpm
Expand All @@ -184,38 +194,39 @@ jobs:

- name: Build frontend bundles
env:
WORKER: ${{ steps.dirs.outputs.worker }}
FRONTENDS: ${{ steps.dirs.outputs.frontends }}
run: |
set -euo pipefail
IFS=, read -ra frontends <<< "$FRONTENDS"
for frontend in "${frontends[@]}"; do
IFS=, read -ra bundles <<< "$FRONTENDS"
for bundle in "${bundles[@]}"; do
(
cd "$WORKER/$frontend"
cd "$bundle"
pnpm install --frozen-lockfile
pnpm build
)
done

- name: Stage frontend bundles
env:
WORKER: ${{ steps.dirs.outputs.worker }}
FRONTENDS: ${{ steps.dirs.outputs.frontends }}
run: |
set -euo pipefail
IFS=, read -ra frontends <<< "$FRONTENDS"
stage=".release-frontend-bundle/$WORKER"
for frontend in "${frontends[@]}"; do
test -d "$WORKER/$frontend/dist"
mkdir -p "$stage/$frontend"
cp -a "$WORKER/$frontend/dist" "$stage/$frontend/"
IFS=, read -ra bundles <<< "$FRONTENDS"
# Repo-relative staging so the restore lands every dist/ exactly
# where its crate's build.rs expects it — including dependency crates
# outside the released worker's directory.
stage=".release-frontend-bundle"
for bundle in "${bundles[@]}"; do
test -d "$bundle/dist"
mkdir -p "$stage/$bundle"
cp -a "$bundle/dist" "$stage/$bundle/"
done

- name: Upload frontend bundles
uses: actions/upload-artifact@v6
with:
name: frontend-bundles
path: .release-frontend-bundle/${{ steps.dirs.outputs.worker }}/
path: .release-frontend-bundle/
if-no-files-found: error
retention-days: 1

Expand Down Expand Up @@ -339,7 +350,9 @@ jobs:
uses: actions/download-artifact@v7
with:
name: frontend-bundles
path: ${{ steps.dirs.outputs.worker }}/
# Repo-rooted: the artifact carries repo-relative paths (worker and
# any path-dependency crates with their own ui/dist).
path: ./

- name: Build and upload binary
uses: taiki-e/upload-rust-binary-action@v1
Expand Down
Loading