Skip to content

fix(build): rewrite app_pack references to materialised paths#104

Open
BimaPangestu28 wants to merge 1 commit into
researchfrom
research-fix-app-pack-paths
Open

fix(build): rewrite app_pack references to materialised paths#104
BimaPangestu28 wants to merge 1 commit into
researchfrom
research-fix-app-pack-paths

Conversation

@BimaPangestu28
Copy link
Copy Markdown
Member

Summary

`gtc setup doctor` on a freshly-built `.gtbundle` failed with `setup.bundle_manifest.reference_exists` because bundle.yaml shipped the user-source-relative `file://./.gtpack` reference while the materialiser had moved the file to `packs/.gtpack`. Doctor's resolver tried `bundle_root.join(reference)` and the file didn't exist there.

Layered bugs

  1. Path mismatch: `app_pack_copy_targets` moves files to `packs/.gtpack` (or `tenants/.../packs/...` for scoped mappings) but the YAMLs inside the squashfs kept the canonical user-supplied reference. Mismatch = doctor failure.
  2. `file://` scheme not unwrapped: Doctor treats the whole reference as a literal path component. Even `file://./packs/.gtpack` dangled. The shape it understands is bare relative path: `packs/.gtpack`.

Fix

  • Expose `MaterializedCopyTarget` + `app_pack_copy_targets` as `pub(crate)` so the build layer reuses the same destination rules.
  • In `build_manifest` (resolved-YAML producer), rewrite each `ResolvedReferencePolicy.reference` to its materialised destination as a bare relative path.
  • In `build/plan.rs::build_state`, rewrite the squashfs-bound `bundle.yaml` via a new text-level `rewrite_app_pack_references_in_yaml` helper. Comments, quoting, section ordering all survive (serde re-emit would lose them).
  • Manifest fields parsed from the user-authored YAML before rewrite — `bundle-manifest.json`'s `app_packs` keeps canonical refs since downstream tooling expects them.
  • User's source bundle.yaml left untouched. Canonical refs still recorded in `bundle.lock.json`.

Verification

Check Before After
`reference_exists` doctor ERROR ❌ FAIL ✅ PASS
`fmt + clippy` clean clean
Unit tests n/a 4 new (rewrite helper)
Workspace test suite 170/170 170/170 (1 expectation updated)

End-to-end smoke against a real 28-node `support-ticket-router` canvas via the research designer's `/api/wizard/build`:

  • Pre-fix: `errors=2 (reference_exists + answers.present)`
  • Post-fix: `errors=1 (just answers.present — develop-mode setup wizard skip)`

Remaining `answers.present` ERROR + 4 warnings are expected develop-mode limitations (webchat setup wizard hasn't run; cosmetic `:latest`-tag warnings; lock + static-routes skipped in develop mode), not path/build bugs.

Branching

Targets `research` per the cross-repo research-branch convention. Once stable, promote to develop alongside the other ongoing research-tier work.

`gtc setup doctor`'s `setup.bundle_manifest.reference_exists` check
on a freshly-built `.gtbundle` failed with:

```
[ERROR] reference_exists: file:///<bundle_root>/file://./testing.gtpack
  expected: referenced .gtpack exists
  actual: file://./testing.gtpack
```

even though the file IS in the squashfs at `packs/testing.gtpack`.
Two layered bugs:

1. The bundle.yaml that ships *inside* the squashfs carried the
   user-source-relative reference (`file://./testing.gtpack`) while
   `app_pack_copy_targets` had moved the file into `packs/<id>.gtpack`
   (or `tenants/.../packs/...` for scoped mappings). The doctor's
   resolver concatenated bundle root with the verbatim reference and
   the resulting path didn't exist.
2. The doctor's resolver doesn't strip the `file://` scheme — it
   treats the whole string as a relative path component. Even after
   rewriting to `file://./packs/testing.gtpack` the doctor still
   tried to open `<bundle_root>/file://./packs/testing.gtpack`. The
   shape it actually understands is a bare relative path:
   `packs/testing.gtpack`.

## Changes

- `src/project/mod.rs`:
  - `MaterializedCopyTarget` + `app_pack_copy_targets` exposed as
    `pub(crate)` so the build layer can reuse the same destination
    rules without duplicating slug logic.
  - In `build_manifest` (the resolved-YAML producer), each
    `ResolvedReferencePolicy.reference` gets rewritten to its
    materialised destination (bare relative path, no scheme). This
    is the YAML the doctor reads when validating.
- `src/build/plan.rs`:
  - `build_state` parses the manifest fields from the user-authored
    YAML *before* any rewrite — `bundle-manifest.json`'s `app_packs`
    keeps the canonical references the workspace declared, since
    downstream tooling (catalog hooks, lock-file generators) expects
    those.
  - The bundle.yaml that ships inside the squashfs is rewritten via
    a new `rewrite_app_pack_references_in_yaml` helper that operates
    on the raw YAML text — comments, quoting, section ordering all
    survive (re-emitting via serde would lose all of that).
  - 4 unit tests cover the rewrite helper (replace, no-op, leave
    unrelated refs alone, empty list).

The user's source bundle.yaml on disk is left untouched. The
canonical references are still recorded in `bundle.lock.json`.
Only the YAMLs that ship inside the squashfs are rewritten so the
runtime + doctor can resolve them against the squashfs root.

## Test plan

- `cargo fmt --all -- --check` clean
- `cargo clippy --all-targets --all-features -- -D warnings` clean
- `cargo test --workspace` — 170+/170+ pass (one existing wizard
  test updated to assert the new bare-path reference shape — its
  setup involves a slugified pack id that lands at
  `packs/cisco-bundle.gtpack` post-materialisation).
- End-to-end doctor smoke against a real designer-built bundle
  (28-node `support-ticket-router` canvas via the research
  designer's `/api/wizard/build`): `reference_exists` ERROR is now
  GONE. Remaining errors are the expected develop-mode limitations
  (`answers.present` — webchat setup wizard hasn't run; cosmetic
  `:latest`-tag warnings; lock + static-routes skipped in develop
  mode).
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