refactor: move manifest template resolver into @microsoft/app-manifest - #16270
Draft
iclanton wants to merge 2 commits into
Draft
refactor: move manifest template resolver into @microsoft/app-manifest#16270iclanton wants to merge 2 commits into
iclanton wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #16270 +/- ##
==========================================
+ Coverage 86.93% 87.08% +0.15%
==========================================
Files 628 629 +1
Lines 32732 33143 +411
Branches 7690 7716 +26
==========================================
+ Hits 28454 28864 +410
+ Misses 2440 2437 -3
- Partials 1838 1842 +4
🚀 New features to boost your workflow:
|
…pp-manifest Relocate the DriverContext-free parts of fx-core's manifest templating into @microsoft/app-manifest so the logic can be consumed without fx-core's DriverContext, localization, or FxError: - expandEnvironmentVariable / getEnvironmentVariables (moved from fx-core component/utils/common.ts) - the file() function resolver and file reader (moved from fx-core component/utils/envFunctionUtils.ts), decoupled from DriverContext and raising plain typed errors that carry the offending path/token - the ManifestType enum Also expose expandFileFunctionMacros (the resolution loop, returning the expanded content plus a function count for host telemetry) and resolveManifest, the host-agnostic counterpart of fx-core's getResolvedManifest. Reuses the package's existing strip-bom and fs-extra usage (no new dependencies). Adds unit tests covering file inlining, JSON escaping, BOM/CRLF normalization, nested file() calls, env-as-parameter, ApiSpec skip, and every typed error path.
Now that the resolver lives in @microsoft/app-manifest (reached transitively via @microsoft/teamsfx-api), remove the duplicated logic from fx-core and delegate: - component/utils/common.ts re-exports expandEnvironmentVariable and getEnvironmentVariables from @microsoft/teamsfx-api, so existing call sites are unchanged. - envFunctionUtils.expandVariableWithFunction delegates its loop to expandFileFunctionMacros, keeping only the telemetry event and mapping the resolver's plain errors to localized UserError / fx-core FileNotFoundError via toFxError. getResolvedManifest is unchanged and keeps composing these primitives. Update the affected tests to drive resolution through real temp files instead of fs mocks, since file reads now happen inside app-manifest.
iclanton
force-pushed
the
odsp/manifest-api-extraction
branch
from
July 6, 2026 21:57
18afc6a to
23a1773
Compare
| isJson: boolean, | ||
| options: Pick<ResolveManifestOptions, "envs" | "fromPath" | "logger"> | ||
| ): Promise<{ content: string; functionCount: number }> { | ||
| const matches = content.match(functionRegex); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves the
DriverContext-free parts of fx-core's manifest templating(
$[file('...')]function expansion and${{ENV}}variable expansion) down into@microsoft/app-manifest, so the logic can be consumed directly from the manifestpackage without depending on
@microsoft/teamsfx-core, aDriverContext,localization, or
UserError.This is a behavior-preserving refactor. fx-core now delegates to the moved logic
and keeps only its host concerns (telemetry + localized error mapping).
What moves where
Relocated into
@microsoft/app-manifest(single source of truth):expandEnvironmentVariable/getEnvironmentVariables— moved verbatim fromfx-core/src/component/utils/common.ts.file()function resolver and file reader — moved fromfx-core/src/component/utils/envFunctionUtils.ts, decoupled fromDriverContextand raising plain typed errors that carry the offending path/token.
ManifestTypeenum.expandFileFunctionMacros(the resolution loop, returning theexpanded content plus a function count for host telemetry) and
resolveManifest,the host-agnostic counterpart of fx-core's
getResolvedManifest.strip-bomandfs-extrausage — no new deps.Left in fx-core (host concerns only):
common.tsre-exportsexpandEnvironmentVariable/getEnvironmentVariablesfrom
@microsoft/teamsfx-api, so all existing call sites are unchanged.expandVariableWithFunctiondelegates its loop toexpandFileFunctionMacros,keeping the telemetry event and mapping the resolver's plain errors to localized
UserError/ fx-coreFileNotFoundErrorviatoFxError.getResolvedManifestis unchanged and keeps composing these primitives (itstelemetry is preserved exactly).
Testing
@microsoft/app-manifestunit suite: 184 passing (manifestTemplate.tsat100% statements / 95% branch / 100% functions).
@microsoft/teamsfx-core: the affected suites plus every consumer of there-exported env functions (aad manifest builder, common utils, scenarios,
declarative-agent generator) pass — no regressions.
of
fsmocks, since file reads now happen inside@microsoft/app-manifest.lint-stagedclean on all changed files.Notes / follow-ups
resolveManifest,expandFileFunctionMacros, andprocessManifestFunctionare new public exports on@microsoft/app-manifest.Happy to adjust the names/shape if the team prefers a different surface.
AppManifestUtils.fetchSchemais local-first (maps the manifest$schemaURL toa bundled
build/json-schemas/...file, with the network only as a fallback).The source bundles the schemas (
src/json-schemas/,prebuild: copy-json-schema,files: ["build/**/*"]), but the published tarball does not includebuild/json-schemas/, so offline validation silently falls back to a networkfetch. Fixing the publish so the schemas ship would make schema validation fully
hermetic with no code change. Can file/fix separately if useful.
functions locally; a full
@microsoft/teamsfx-coresuite run in CI is worth aglance (the 3 unrelated pre-existing failures need bundled template artifacts that
a plain bootstrap doesn't produce).
Opened as a draft to gather feedback on the API surface before finalizing.