Skip to content

fix: resolve schema against runtime metadata in plugin builds; gate cache overlay by version#1764

Merged
evandance merged 2 commits into
mainfrom
fix/schema-meta-fallback
Jul 6, 2026
Merged

fix: resolve schema against runtime metadata in plugin builds; gate cache overlay by version#1764
evandance merged 2 commits into
mainfrom
fix/schema-meta-fallback

Conversation

@liangshuo-1

@liangshuo-1 liangshuo-1 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two related metadata-loading fixes:

  1. Plugin builds: schema failed with Unknown service. Binaries built from the bare Go module (a wrapper main that blank-imports a plugin package and builds against github.com/larksuite/cli) embed only the empty meta_data_default.json stub — meta_data.json is gitignored and fetched at build time, and the Go module zip only packs tracked files. The runtime registry already sync-fetches full metadata on first run (service commands work), but schema, its shell completion, and the affordance command-form resolver read the embedded-only catalog, so every lookup failed with Unknown service and an empty candidates hint.

  2. Stale cache shadowing embedded meta (ports fix: gate cached meta overlay on version newer than embedded #1376). Cached remote meta was overlaid onto the embedded baseline unconditionally, so after a CLI upgrade an equal- or older-version cache kept shadowing the freshly shipped embedded definitions. fix: gate cached meta overlay on version newer than embedded #1376 (approved) predates the typed meta model and no longer applies to main; re-implemented on top of it.

Changes

  • registry.SchemaCatalog(): returns the embedded catalog when metadata is compiled in (official builds unchanged, still deterministic), otherwise the merged runtime catalog seeded from cache or remote fetch
  • cmd/schema: resolve + completion go through SchemaCatalog(); when no metadata exists at all (offline plugin build with a cold cache) schema returns failed_precondition with an actionable hint instead of Unknown service with an empty list
  • internal/affordance: command-form resolver uses the same catalog source, restoring affordance mapping for irregularly-pluralized resources in plugin builds
  • InitWithBrand: overlay the cache only when update.IsNewer(cached.Version, embeddedVersion); the bare-module stub baseline is 0.0.0, so plugin builds keep taking any real cached version
  • Tests: SchemaCatalog source selection + fallback; five overlay-gate cases (equal / older / newer / unparseable / stub baseline); cache-overlay tests decoupled from the ambient embedded meta

Test Plan

  • CI-exact unit tests in a clean worktree: go test -race -count=1 ./cmd/... ./internal/... ./shortcuts/... ./extension/... — 106 packages ok, 0 failures, 0 data races
  • golangci-lint (--new-from-rev main) 0 issues; lintcheck clean; make quality-gate pass; make script-test 95/95
  • Byte-level output regression vs a main-baseline binary (official build, remote meta off): full schema dump (1.74 MB), service/method envelopes, completion, root/service help, error surfaces — all identical
  • E2E plugin-build matrix (binary built without meta_data.json): first run sync-fetches and schema resolves; warm cache within TTL does not refetch; offline cold cache returns the actionable failed_precondition envelope; full schema dump byte-identical to the official build
  • Overlay gate both directions: an equal-version doctored cache no longer registers a bogus service (reproduces the fix: gate cached meta overlay on version newer than embedded #1376 bug on main); a newer-version cache still overlays
  • Server-side data_version protocol verified live: current version returns not-modified (data:{}), older versions return the full payload

Related Issues

Ports #1376 onto the typed meta model.

Summary by CodeRabbit

  • New Features

    • Command completion now aligns with the schema catalog actually used for schema resolution, improving consistency in strict-mode scenarios.
  • Bug Fixes

    • Schema commands now provide a clearer validation error when schema metadata is unavailable, including guidance to fetch/cache it once.
    • Cached registry overlays are now applied only when the cache is strictly newer than the built-in baseline, preventing older cached data from taking precedence.
    • Improved affordance-to-method mapping to rely on the same schema catalog used for resolution.
  • Tests

    • Added coverage for schema catalog selection and cache-versus-embedded version gating behavior.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds registry.SchemaCatalog() to select embedded or runtime metadata, switches schema command and affordance resolution to it, and gates cached registry overlay on version freshness. Tests cover catalog selection and overlay/version behavior.

Changes

SchemaCatalog and version-gated registry overlay

Layer / File(s) Summary
SchemaCatalog function definition
internal/registry/catalog.go
Adds SchemaCatalog() returning EmbeddedCatalog() when embedded services are present, otherwise RuntimeCatalog(), with an updated doc comment.
Schema command and affordance consume SchemaCatalog
cmd/schema/schema.go, internal/affordance/affordance.go
Completion and execution in schema, and the affordance command-form resolver, now use SchemaCatalog(); runSchema adds a failed-precondition error when no API metadata is available.
Version-gated cache overlay in loader
internal/registry/loader.go
Imports internal/update and overlays cached registry data only when its version is strictly newer than the embedded version.
Overlay gate tests and updated remote tests
internal/registry/loader_test.go, internal/registry/remote_test.go
New overlay-gate test scenarios and updated version expectations/test setup in existing remote tests.
SchemaCatalog tests
internal/registry/catalog_test.go
New helper and tests verifying embedded-vs-runtime selection behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • larksuite/cli#280: Both PRs touch internal/registry test setup around overlay and embedded-version behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the two main fixes: using runtime metadata for schema in plugin builds and gating cache overlay by version.
Description check ✅ Passed The description includes the required Summary, Changes, Test Plan, and Related Issues sections and is detailed and on-topic.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/schema-meta-fallback

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 63.63636% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.44%. Comparing base (ee46e22) to head (b7ac661).

Files with missing lines Patch % Lines
cmd/schema/schema.go 20.00% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1764   +/-   ##
=======================================
  Coverage   74.43%   74.44%           
=======================================
  Files         854      854           
  Lines       88490    88494    +4     
=======================================
+ Hits        65867    65877   +10     
+ Misses      17554    17549    -5     
+ Partials     5069     5068    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Binaries built from the bare Go module (plugin builds) embed only the
empty meta_data_default.json stub because meta_data.json is gitignored
and fetched at build time. The schema command, its completion, and the
affordance command-form resolver read the embedded-only catalog, so
every schema lookup failed with "Unknown service" even though the
runtime registry had already sync-fetched full metadata.

Add registry.SchemaCatalog(): embedded when compiled in (official
builds unchanged, still deterministic), otherwise the merged runtime
catalog seeded from cache or remote fetch. When neither source has
data (offline plugin build with a cold cache), schema now returns a
failed_precondition error with an actionable hint instead of
"Unknown service" with an empty candidate list.
The cached remote meta was overlaid onto the embedded meta_data.json
unconditionally, so after a CLI upgrade an equal- or older-version
cache kept shadowing the freshly shipped embedded definitions until a
later refresh happened to rewrite it.

Only overlay when the cache version is strictly newer than the
embedded baseline. The bare-module stub baseline is "0.0.0", so plugin
builds without compiled metadata still take any real cached version
(TestOverlayGate_StubEmbedded_OverlaysRealCache) and the schema
runtime fallback keeps working offline from a warm cache.

Ports #1376 onto the typed meta model.
@liangshuo-1
liangshuo-1 force-pushed the fix/schema-meta-fallback branch from c6bd6b3 to b7ac661 Compare July 6, 2026 10:15
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@b7ac661e73f24fc8c0b1824fa093fe4c13c310dc

🧩 Skill update

npx skills add larksuite/cli#fix/schema-meta-fallback -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 `@cmd/schema/schema.go`:
- Around line 89-102: Add a test in schema_test.go that exercises runSchema’s
empty-catalog precondition by forcing registry.SchemaCatalog() to return a
catalog with no Services, then assert the returned error is a
failed_precondition validation error. Use the runSchema and SchemaCatalog
symbols to locate the new branch, and verify the hint/error path for the “No API
metadata available” case.
🪄 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

Run ID: 8ca0aaf0-b609-436a-bad1-d5708e9d5022

📥 Commits

Reviewing files that changed from the base of the PR and between ee46e22 and c6bd6b3.

📒 Files selected for processing (7)
  • cmd/schema/schema.go
  • internal/affordance/affordance.go
  • internal/registry/catalog.go
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_test.go
  • internal/registry/remote_test.go

Comment thread cmd/schema/schema.go
@evandance
evandance merged commit f0b6f35 into main Jul 6, 2026
61 of 65 checks passed
@evandance
evandance deleted the fix/schema-meta-fallback branch July 6, 2026 13:24
@liangshuo-1 liangshuo-1 mentioned this pull request Jul 7, 2026
3 tasks
zhaojunlin0405 added a commit that referenced this pull request Jul 9, 2026
…ma catalog

Two plugin_e2e tests resolved differently on a clean CI runner than on a
developer box because they used run(), which inherits the host's ~/.lark-cli
metadata cache and network. On CI (cold cache, offline) they failed; locally
they passed.

- Replace TestSubsystemTransportAbort with TestRuntimeCatalogResolvesSchema.
  The transport round-trip it targeted is unreachable in a bare-module fork
  offline (credential resolution fails first); the transport path is covered
  end-to-end by the sidecar suite and the credential-block test. The new test
  seeds an obviously-synthetic service into a bare-module fork's on-disk cache
  and asserts `schema` resolves it from the runtime catalog -- the primary
  fix for #1764 (module builds now consult the runtime catalog instead of
  returning "Unknown service"). It complements the existing cold-cache degrade
  test, pinning both branches, and runs fully offline.
- Drop the readonly parent-group sub-case: mixed_children_policy needs a
  metadata-enumerated child tree the bare-module fork does not have, so offline
  it collapses to domain_not_allowed; that reason_code is covered by cmdpolicy
  unit tests.
- Fix errorlint in run() (errors.As), and stream `git archive` into `tar`
  through an explicit pipe instead of a shell in gitArchive.
- Set persist-credentials: false on the two new job checkouts and reuse
  assertReasonCodeEnvelope in TestReadonlyDenial.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants