Skip to content

test(install): port four allowBuilds review tests from pnpm lifecycleScripts.ts#441

Merged
jdx merged 7 commits intomainfrom
claude/unruffled-proskuriakova-e1bd1a
May 1, 2026
Merged

test(install): port four allowBuilds review tests from pnpm lifecycleScripts.ts#441
jdx merged 7 commits intomainfrom
claude/unruffled-proskuriakova-e1bd1a

Conversation

@jdx
Copy link
Copy Markdown
Contributor

@jdx jdx commented Apr 30, 2026

Summary

Four ports from pnpm/test/install/lifecycleScripts.ts into test/lifecycle_scripts.bats, bumping the row in PNPM_TEST_IMPORT.md from 8/21 → 12/21:

  1. misc.ts:226aube add under strictDepBuilds=true against an unreviewed registry build script fails. Asserts the dep + lockfile + review placeholder are still written so the user can flip and re-run.
  2. misc.ts:260 — auto-populated allowBuilds review placeholder lands in package.json#aube.allowBuilds when no workspace yaml is present.
  3. misc.ts:268 — placeholder merges with pre-existing allowBuilds entries in pnpm-workspace.yaml without clobbering them.
  4. misc.ts:303strictDepBuilds=true still fails when side-effects are already cached in the store (regression for pnpm/pnpm#11035).

Aube divergences (translated, not silently elided)

  • Placeholder format: aube writes the literal boolean false; pnpm writes the string "set this to true or false". Same review-required semantic — aube's value is more directly readable by automation.
  • Strict-dep-builds error: aube reads dependencies with build scripts must be reviewed before install; pnpm reads Ignored build scripts:.
  • Setting surface: aube has no --config.strict-dep-builds=true CLI flag; the test reads it via .npmrc (appended to preserve the registry= line that _common_setup writes when AUBE_TEST_REGISTRY is set).

Remaining tests classified

Updates the doc row to split the 9 untouched cases into actionable buckets so future port PRs don't re-discover the same blockers:

  • Fixture/setup blocked: rollback-dep-on-build-failure (108), node-gyp on PATH (128), repeat-install warning preservation (245 — aube short-circuits at the freshness check), git-dep prepare under dangerouslyAllowAllBuilds (336).
  • Aube-feature blocked: --allow-build=<pkg> CLI flag (149, 164, 347), verify-deps-before-run recursion (179, 200), selective aube rebuild <pkg> (282).
  • Already covered: installation-fails-on-lifecycle-script-error (17 — aube's lifecycle_scripts.bats:187 covers the same contract).

Test plan

  • mise run test:bats test/lifecycle_scripts.bats — 25/25 green (21 prior + 4 new)
  • cargo fmt --check

Note

Medium Risk
Touches lifecycle-script gating by changing how unreviewed allowBuilds entries are written and by adding a flag that can enable dependency scripts during aube add, so mistakes could inadvertently run builds or persist approvals in the wrong config file.

Overview
Adds aube add --allow-build=<pkg> to pre-approve specific dependency lifecycle scripts by writing allowBuilds.<pkg>=true to the workspace YAML (or package.json#aube.allowBuilds) before install, with a hard error if the package is explicitly denied and a clap-level conflict with --no-save.

Changes strict-dep-builds seeding from allowBuilds: false to pnpm’s canonical review placeholder string ("set this to true or false"), updates parsing/serialization to preserve string values verbatim across JSON/YAML, and teaches build-policy parsing to treat the placeholder as “unreviewed” without emitting warnings.

Updates approve-builds, install paths, CLI docs/spec (aube.usage.kdl, docs/cli/add.md, commands.json), and expands Bats coverage around placeholder seeding/merging, strictDepBuilds behavior, and --allow-build conflicts (including --filter root writes).

Reviewed by Cursor Bugbot for commit d13f310. Bugbot is set up for automated code reviews on this repo. Configure here.

…Scripts.ts

Ports four pnpm/test/install/lifecycleScripts.ts cases covering aube's
allowBuilds review machinery:

- L226: strictDepBuilds throws on unreviewed registry build scripts
- L260: review placeholder is auto-populated in package.json#aube.allowBuilds
- L268: placeholder merges with existing approvals in pnpm-workspace.yaml
- L303: strictDepBuilds still fails for packages with cached side-effects
  (regression for pnpm/pnpm#11035)

Bumps the lifecycleScripts.ts port count from 8/21 to 12/21. The
PNPM_TEST_IMPORT.md row now classifies the remaining 9 cases into
fixture-blocked, divergence, and equivalent-coverage buckets so future
ports don't re-discover the same blockers.

Two divergences worth noting in ports: aube writes the literal boolean
\`false\` for review placeholders (vs pnpm's \`"set this to true or false"\`
string), and aube's strict-dep-builds error reads "dependencies with
build scripts must be reviewed before install" (vs pnpm's "Ignored build
scripts:").
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR introduces aube add --allow-build=<pkg> for selectively pre-approving dependency lifecycle scripts, replaces the install-time allowBuilds seed value from false to pnpm's canonical "set this to true or false" placeholder string (via the new AllowBuildsWriteMode enum), and ports 7 pnpm lifecycleScripts.ts tests plus adds 2 aube-specific regression tests (workspace-filter path and --no-save conflict). The previously flagged issue of the conflict check running after update_manifest_for_add has been fixed — apply_allow_build_flags now runs before any manifest mutation in both the direct and filtered code paths.

Confidence Score: 5/5

Safe to merge — no P0/P1 issues found; the prior conflict-ordering bug has been addressed and is pinned by a new test.

All changes are well-covered by unit and bats tests (25/25 green per the PR). The AllowBuildsWriteMode refactor is a clean enum-for-bool replacement with no hidden branching changes. The namespace handling in pnpm_allow_builds() correctly merges both pnpm.* and aube.* sources, so the conflict check in apply_allow_build_flags is complete. No security-sensitive code paths are affected.

No files require special attention.

Important Files Changed

Filename Overview
crates/aube-manifest/src/workspace.rs Introduces AllowBuildsWriteMode enum and ALLOW_BUILDS_REVIEW_PLACEHOLDER constant; replaces the bool parameter in add_to_allow_builds/write_allow_builds_yaml with the enum; adds verbatim string handling for YAML to match the JSON side; well-covered by existing + new unit tests.
crates/aube-manifest/src/lib.rs Adds Value::String arm to AllowBuildRaw::from_json with a clear regression comment; pnpm_allow_builds() already reads from both pnpm.* and aube.* namespaces so the conflict check in apply_allow_build_flags is complete; new round-trip unit test is well-targeted.
crates/aube/src/commands/add.rs Adds allow_build: Vec<String> to AddArgs, implements apply_allow_build_flags, and correctly places the conflict check + approval write BEFORE update_manifest_for_add in both the direct and run_filtered paths, addressing the ordering bug from the prior review.
crates/aube-scripts/src/policy.rs Adds a continue branch for the canonical placeholder string in BuildPolicy, keeping placeholder-seeded packages out of the allowed-builds set without emitting a spurious UnsupportedValue warning; other strings still warn as before.
test/lifecycle_scripts.bats Adds 9 new bats tests covering: allowBuilds placeholder seeding, merge with existing approvals, strictDepBuilds failures, cached-side-effects regression, --allow-build flag (selective approval, bare flag rejection, workspace-filter path, --no-save conflict, explicit-false conflict); quote-agnostic grep patterns used where serializer quoting style may vary.
test/approve_builds.bats One existing test updated: assertion string changed from false boolean to the canonical placeholder string, matching the new ReviewPlaceholder write mode.
aube.usage.kdl Adds --allow-build <PKG> flag definition with long help text describing the pnpm mirror, conflict with --no-save, and the explicit-deny guard.
test/PNPM_TEST_IMPORT.md Updates ported-test count from 8/21 to 15/21 and fills in actionable buckets for the remaining 6 cases; PR title says 'four ports' but the doc and diff reflect 7 newly-ported pnpm cases (226, 260, 268, 303, 149, 164, 347).
crates/aube/src/commands/install/mod.rs Mechanical update: two call-sites of add_to_allow_builds switched from false to AllowBuildsWriteMode::ReviewPlaceholder; no logic change.
crates/aube/src/commands/approve_builds.rs Two call-sites updated to AllowBuildsWriteMode::Approve; no logic change.

Reviews (5): Last reviewed commit: "fix(cli): apply --allow-build in the wor..." | Re-trigger Greptile

Comment thread test/lifecycle_scripts.bats
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Benchmark changes

Versions:

  • aube: 1.5.1 -> 1.5.2
  • pnpm: 11.0.2 -> 11.0.3

Public ratios: warm installs vs Bun 4x -> 9x; warm installs vs pnpm 5x -> 11x.

Benchmark aube bun pnpm
Fresh install (warm cache) 1021ms -> 244ms (-76%) 4134ms -> 2121ms (-49%) 4717ms -> 2640ms (-44%)
CI install (warm cache, GVS disabled) 2920ms -> 907ms (-69%) 3396ms -> 2254ms (-34%) 4864ms -> 2431ms (-50%)
CI install (cold cache, GVS disabled) 10801ms -> 4043ms (-63%) 10012ms -> 4229ms (-58%) 9722ms -> 4909ms (-50%)

d13f310 vs 400c56a | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex.

Two pnpm-parity wins:

1. allowBuilds review entries now write the canonical string
   "set this to true or false" (matching pnpm verbatim), not the
   bool `false` aube was emitting. Read-side recognizes the string
   in `aube-scripts::policy` and treats it as Unspecified (skip
   silently); strictDepBuilds still surfaces it via
   `unreviewed_dep_builds`. New `AllowBuildsWriteMode { Approve,
   ReviewPlaceholder }` enum on `add_to_allow_builds` makes the
   intent explicit at every call site.

2. `aube add --allow-build=<pkg>` (repeatable) pre-approves a dep's
   lifecycle scripts as part of the add. Writes
   `allowBuilds: { <pkg>: true }` before the install runs. Refuses
   to silently flip a pre-existing `false` (mirrors pnpm's conflict
   error verbatim).

Bats coverage: ports lifecycleScripts.ts L149 (selective build),
L164 (bare flag rejected), L347 (false-conflict error). Bumps the
lifecycleScripts.ts row in PNPM_TEST_IMPORT.md from 12/21 → 15/21
and drops the now-obsolete divergence notes (placeholder format,
--allow-build CLI flag).

Also addresses greptile's quote-fragility concern on the merge-test
assertion by switching from `assert_output --partial '<single-quoted>'`
to a quote-agnostic `grep -E "<key>['\"]?: <value>"` pattern.
Comment thread crates/aube/src/commands/add.rs
Comment thread crates/aube-scripts/src/policy.rs
Comment thread crates/aube/src/commands/add.rs
…-wins precedence

Three bugbot fixes on top of the placeholder/--allow-build work:

- HIGH: AllowBuildRaw::from_json was JSON-encoding string values via
  Value::to_string, baking the outer quotes into the payload. Once
  the canonical "set this to true or false" placeholder was written
  to package.json, every subsequent install would read it back as
  the JSON-quoted form ("\"set this to true or false\""), miss the
  read-side equality check in aube-scripts::policy, and emit a
  spurious UnsupportedValue warning on every install. Same shape on
  the YAML side via WorkspaceConfig::allow_builds_raw — both paths
  now extract Value::String contents directly. Two regression unit
  tests pin the round-trip.

- LOW: apply_allow_build_flags merged manifest + workspace allowBuilds
  using or_insert (manifest wins), inverted vs build_policy_from_sources
  in install/lifecycle.rs (workspace wins). A pkg pinned to false in
  pnpm-workspace.yaml could be silently overridden by a true in
  package.json, defeating the conflict check the flag exists to enforce.
  Switched to insert so the install pipeline and the conflict check see
  the same effective value.

- MEDIUM: doc-comment fix — apply_allow_build_flags landed mid-way
  through lockfile_path_for_project's doc comment in the previous
  commit, splitting both into garbled fragments. Function moved
  above lockfile_path_for_project with its own intact doc.
Comment thread crates/aube/src/commands/add.rs
Comment thread crates/aube/src/commands/add.rs Outdated
jdx and others added 3 commits April 30, 2026 19:36
Bugbot follow-up: --allow-build can write to a workspace yaml via
add_to_allow_builds, but --no-save's restore path snapshots only
package.json + the lockfile. Combining the two would leak an orphaned
approval into the workspace yaml. Same reasoning as the existing
--save-catalog / --no-save conflict (aube/src/commands/add.rs:39 prior
art); enforce it the same way via clap's `conflicts_with`.

Adds a bats regression test asserting clap rejects the combo before
any write.
Greptile follow-up: the conflict check in apply_allow_build_flags
fired AFTER update_manifest_for_add wrote the new deps to
package.json. A failing check would return early, leaving the user
with new deps in the manifest and no install — an inconsistent
half-mutated state requiring manual cleanup.

Move the call earlier so the check runs against the pre-add state.
The install pipeline re-reads both files from disk, so writing
allowBuilds before the deps doesn't change the install behavior.

Strengthens the L347 bats port to assert the manifest is unchanged
on conflict — locks in the no-half-mutation contract.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a135cfd. Configure here.

Comment thread crates/aube/src/commands/add.rs
Bugbot follow-up: the workspace-filter add path (`aube add
--filter=<sel> <pkg>` via `run_filtered`) silently dropped
`args.allow_build` — no conflict check ran and no approval was
written, so a user passing `--allow-build` under `--filter` would
believe the build was pre-approved when it was not.

Wire `apply_allow_build_flags` into `run_filtered`, targeting the
workspace root (`&root`) since `allowBuilds` is a workspace-level
setting. Runs before any per-package manifest mutation so a
conflict can't half-mutate child manifests, mirroring the contract
already enforced in the non-filtered path.

Adds a bats regression test exercising both legs (conflict + happy
path) under `--filter`.
@jdx jdx merged commit 60ff453 into main May 1, 2026
18 checks passed
@jdx jdx deleted the claude/unruffled-proskuriakova-e1bd1a branch May 1, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant