Skip to content

Static Web Assets: apply deferred asset group resolution during publish - #54941

Open
javiercn with Copilot wants to merge 5 commits into
mainfrom
copilot/fix-deferred-asset-group-resolution
Open

Static Web Assets: apply deferred asset group resolution during publish#54941
javiercn with Copilot wants to merge 5 commits into
mainfrom
copilot/fix-deferred-asset-group-resolution

Conversation

Copilot AI commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Deferred Static Web Asset groups were resolved during build but never during publish. When two grouped variants resolved to the same route with AssetKind=All (e.g. a package fallback plus an app-generated asset), the variant the group was supposed to exclude survived into the publish pipeline and GenerateStaticWebAssetEndpointsManifest threw InvalidOperationException: Sequence contains more than one element. The same project built successfully.

Root cause

The build manifest intentionally retains all group variants so transitive consumers can re-resolve against their own graph. Publish reloads that manifest but:

  1. never re-resolves deferred groups (no publish-side FilterDeferredStaticWebAssetGroups), and
  2. its FilterStaticWebAssetGroups is consumer-scoped (Source="$(PackageId)"), so it structurally cannot filter groups owned by a referenced project or NuGet package.

Re-resolving at publish from the package can't fix this — the decision has to be made where the filter is unscoped (build) and carried forward.

Changes

  • Persist resolved groups in the build manifestStaticWebAssetGroup is now public/serializable with round-trip (ToTaskItem/FromItemGroupToArray) and value equality; StaticAssetsManifest gains a Groups property wired into Create/hash/equals. GenerateStaticWebAssetsManifest writes the resolved (no-longer-Deferred) groups into staticwebassets.build.json.
  • Surface groups on readReadStaticWebAssetsManifestFile exposes a new StaticWebAssetGroups output.
  • Re-apply the unscoped decision at publishLoadStaticWebAssetsBuildManifest re-runs FilterStaticWebAssetGroups (unscoped) using the persisted groups, dropping the excluded variant before the publish endpoints manifest is computed. Build-time groups are also cached (_CachedBuildStaticWebAssetGroups) so the in-process build+publish path is covered alongside fresh/no-build publishes that read from the manifest.
  • Regression test — adds a publish case to DeferredAssetGroupsIntegrationTest where two AssetKind=All variants collapse to one route, owned by a referenced project, and asserts exactly one asset/endpoint survives.

Because the build manifest still retains all variants, transitive consumers continue to re-import the deferred group definitions and re-resolve against their own graph; persistence only governs the current project's build→publish consistency.

Copilot AI changed the title [WIP] Fix deferred asset group resolution during publish Static Web Assets: apply deferred asset group resolution during publish Jun 23, 2026
Copilot AI requested a review from javiercn June 23, 2026 14:49
@javiercn
javiercn marked this pull request as ready for review June 23, 2026 15:01
Copilot AI review requested due to automatic review settings June 23, 2026 15:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a build→publish inconsistency in the Static Web Assets pipeline by persisting resolved (non-deferred) asset group decisions into the build manifest and then re-applying that decision during publish when the build manifest is loaded, preventing duplicate assets/endpoints from surviving into publish and causing endpoint manifest generation failures.

Changes:

  • Persist resolved StaticWebAssetGroup data into staticwebassets.build.json and expose it when reading manifests.
  • Re-apply group filtering during publish after reloading the build manifest (including in-process build+publish via cached groups).
  • Add an integration test covering the publish scenario where two variants collapse to the same route and only one should survive.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/Microsoft.NET.Sdk.StaticWebAssets.Tests/DeferredAssetGroupsIntegrationTest.cs Adds a publish regression test validating only one grouped variant/endpoints survive publish.
src/StaticWebAssetsSdk/Tasks/ReadStaticWebAssetsManifestFile.cs Adds StaticWebAssetGroups output when reading a manifest.
src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsManifest.cs Captures @(StaticWebAssetGroup) input and persists resolved groups into the manifest.
src/StaticWebAssetsSdk/Tasks/Data/StaticWebAssetGroup.cs Makes StaticWebAssetGroup public/serializable with task-item roundtrip + value equality/hash.
src/StaticWebAssetsSdk/Tasks/Data/StaticAssetsManifest.cs Adds Groups to the build manifest model, hash computation, and equality/hash code.
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets Passes groups into build manifest generation and caches build-time groups for in-proc publish.
src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Publish.targets Reloads groups from build manifest and re-filters assets/endpoints during publish using persisted groups.

Comment on lines +100 to +103
var publish = CreatePublishCommand(projectDirectory, "AppWithP2PReference");
ExecuteCommand(publish).Should().Pass();

var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString();
javiercn added a commit to dotnet/aspnetcore that referenced this pull request Jun 23, 2026
…otnet/sdk#54941)

Reverts the framework-asset modeling and the in-package publish workaround. With the SDK fix
in dotnet/sdk#54941 (resolved deferred static web asset groups are persisted into the build
manifest and re-applied, unscoped, when the manifest is reloaded at publish), the idiomatic
deferred-group authoring that the WebView package already uses is correct end-to-end:
blazor.modules.json is a Package static web asset in the deferred BlazorWebViewModules group,
resolved to drop the fallback when the app contributes its own JS modules and keep it
otherwise. No framework-asset hack and no package-local workaround are needed, so the WebView
product files are unchanged from main.

This PR now contributes the static web assets packaging + build/publish regression tests:
- Package-layout tests assert the deferred-group shape for WebView (modules.json = Package in
  BlazorWebViewModules=fallback; webview.js = Framework) and the framework/group shapes for
  Components.WebAssembly, App.Internal.Assets and Identity.UI.
- Build/publish behavior tests (package consumer and ProjectReference consumer) assert a single
  _framework/blazor.modules.json endpoint and that the app's manifest supersedes the fallback.
  The publish assertions are skipped until dotnet/sdk#54941 is in the repo SDK (detected via the
  pre-fix 'Sequence contains more than one element' crash) so the suite stays green meanwhile.

Note: this PR depends on dotnet/sdk#54941 flowing into the repo SDK; until then the in-repo
WebView publish path (and the publish tests) require that fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@javiercn javiercn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot address feedback

Copilot AI commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address feedback

Added Publish_NoBuild_DeferredGroupWithTwoVariantsOnSameRoute_KeepsSingleVariant in commit 539a85c→latest. The new test builds the project first, then republishes with /p:NoBuild=true to exercise the ReadStaticWebAssetsManifestFileLoadStaticWebAssetsBuildManifest disk-read path, asserting that exactly one asset/endpoint survives on the shared route. Also updated the CreateTwoVariantDeferredGroupProject helper to accept a [CallerMemberName] parameter included in the identifier so each test method gets its own isolated test asset directory.

Copilot AI requested a review from javiercn June 23, 2026 20:21
javiercn added a commit to dotnet/aspnetcore that referenced this pull request Jun 23, 2026
#67374)

The WebView package ships a fallback _framework/blazor.modules.json (empty []) for
apps that contribute no JS library modules. Modeling it as a deferred static web
asset group required tagging/promoting the consumer's SDK-generated manifest and
depended on an SDK fix (dotnet/sdk#54941) to filter the group at publish; without
it, publish crashed with "Sequence contains more than one element" (#67374).

Replace the group authoring with conditional materialization: the package ships
the fallback raw under build/ (not as a flowing static web asset) and materializes
it as the consumer's own asset during ResolveStaticWebAssetsInputs ONLY when the
app has no JS modules of its own. The decision runs before the build manifest /
conflict check, so exactly one asset ever lands on _framework/blazor.modules.json
and there is never a conflict at build or publish. No asset groups, no consumer
manifest tagging, no SDK dependency.

Tests validate the package layout and build/publish behavior (package + P2P
consumers, with and without JS modules) by cracking the built .nupkg and running
isolated consumer builds under artifacts/ with binlog capture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 5 commits June 23, 2026 19:41
…nifest groups

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…fest

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…upProject

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
@lewing
lewing force-pushed the copilot/fix-deferred-asset-group-resolution branch from 5415398 to d8a29aa Compare June 24, 2026 00:45
javiercn added a commit to dotnet/aspnetcore that referenced this pull request Jun 24, 2026
…otnet/sdk#54941)

Reverts the framework-asset modeling and the in-package publish workaround. With the SDK fix
in dotnet/sdk#54941 (resolved deferred static web asset groups are persisted into the build
manifest and re-applied, unscoped, when the manifest is reloaded at publish), the idiomatic
deferred-group authoring that the WebView package already uses is correct end-to-end:
blazor.modules.json is a Package static web asset in the deferred BlazorWebViewModules group,
resolved to drop the fallback when the app contributes its own JS modules and keep it
otherwise. No framework-asset hack and no package-local workaround are needed, so the WebView
product files are unchanged from main.

This PR now contributes the static web assets packaging + build/publish regression tests:
- Package-layout tests assert the deferred-group shape for WebView (modules.json = Package in
  BlazorWebViewModules=fallback; webview.js = Framework) and the framework/group shapes for
  Components.WebAssembly, App.Internal.Assets and Identity.UI.
- Build/publish behavior tests (package consumer and ProjectReference consumer) assert a single
  _framework/blazor.modules.json endpoint and that the app's manifest supersedes the fallback.
  The publish assertions are skipped until dotnet/sdk#54941 is in the repo SDK (detected via the
  pre-fix 'Sequence contains more than one element' crash) so the suite stays green meanwhile.

Note: this PR depends on dotnet/sdk#54941 flowing into the repo SDK; until then the in-repo
WebView publish path (and the publish tests) require that fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
javiercn added a commit to dotnet/aspnetcore that referenced this pull request Jun 24, 2026
#67374)

The WebView package ships a fallback _framework/blazor.modules.json (empty []) for
apps that contribute no JS library modules. Modeling it as a deferred static web
asset group required tagging/promoting the consumer's SDK-generated manifest and
depended on an SDK fix (dotnet/sdk#54941) to filter the group at publish; without
it, publish crashed with "Sequence contains more than one element" (#67374).

Replace the group authoring with conditional materialization: the package ships
the fallback raw under build/ (not as a flowing static web asset) and materializes
it as the consumer's own asset during ResolveStaticWebAssetsInputs ONLY when the
app has no JS modules of its own. The decision runs before the build manifest /
conflict check, so exactly one asset ever lands on _framework/blazor.modules.json
and there is never a conflict at build or publish. No asset groups, no consumer
manifest tagging, no SDK dependency.

Tests validate the package layout and build/publish behavior (package + P2P
consumers, with and without JS modules) by cracking the built .nupkg and running
isolated consumer builds under artifacts/ with binlog capture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
javiercn added a commit to dotnet/aspnetcore that referenced this pull request Jun 24, 2026
…l fallback (#67374) (#67375)

* [Blazor] Model WebView blazor.modules.json as a framework asset (#67374)

Microsoft.AspNetCore.Components.WebView shipped its fallback blazor.modules.json
via a static web asset group (BlazorWebViewModules=fallback) plus manifest-promotion
targets. At publish, group filtering runs with SkipDeferred=true, so the fallback was
not excluded and GenerateStaticWebAssetEndpointsManifest saw two AssetKind=All assets
on _framework/blazor.modules.json, throwing 'Sequence contains more than one element'
in MAUI Blazor Hybrid apps that also reference a JS-module-contributing RCL.

Model blazor.modules.json as a framework static web asset (like
Microsoft.AspNetCore.Components.WebAssembly ships its JS): BasePath '/', assets under
wwwroot/_framework/, and StaticWebAssetFrameworkPattern '**/*.js;**/*.modules.json'.
The framework pattern is matched against the fingerprinted relative path, so a suffix
glob (*.modules.json) is required for the JS module manifest to be classified as a
Framework asset. The deferred BlazorWebViewModules group + promotion targets are
removed; a minimal StaticWebAssets.Groups.targets keeps JSModuleManifestRelativePath
and CompressionEnabled for consumers.

Add a test project that cracks the built .nupkg files and asserts the static web assets
layout/shape for the WebView, WebAssembly, App.Internal.Assets and Identity.UI packages,
plus end-to-end build/publish tests that reference the locally-built WebView package
from a generated app (and a JS-module RCL) and validate the produced endpoints.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix WebView ProjectReference publish conflict and improve packaging tests

The framework-asset modeling of blazor.modules.json/blazor.webview.js broke publish for
in-repo projects that reference the WebView project via ProjectReference (the WebView E2E
test and the Photino sample): the SDK applies StaticWebAssetFrameworkPattern when computing
a referenced project's BUILD static web assets but not its PUBLISH assets, so publish ends up
with both the materialized framework asset (SourceType=Discovered, SourceId=consumer) and the
original (SourceType=Project, SourceId=WebView) at the same _framework/... target path and
fails with 'Conflicting assets with the same target path'.

Add a no-op-for-package-consumers workaround in StaticWebAssets.Groups.targets that drops the
redundant Project-sourced WebView framework assets at publish (the materialized copies are the
ones served), and import the groups targets from the WebView E2E test so it (like the Photino
sample) also gets JSModuleManifestRelativePath. Package consumers receive these assets as
SourceType=Package, so nothing is removed for them.

Test improvements:
- Build-behavior tests now create working folders under artifacts/tmp instead of the system
  temp folder.
- Each build/publish captures a binary log under artifacts/log so CI collects it and failures
  can be diagnosed; the working folder is preserved on failure and removed on success.
- Tests log the dotnet invocation, output and binlog path via ITestOutputHelper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add ProjectReference (P2P) publish regression test for WebView framework assets

Adds Publish_ProjectReferenceToWebViewWithJsModuleRcl_SucceedsWithSingleModulesManifest,
which references the WebView source project (not the package) plus a JS-module RCL and runs
'dotnet publish'. This is the exact in-repo scenario that regressed in CI: without the
StaticWebAssets.Groups.targets workaround it fails with 'Conflicting assets with the same
target path _framework/blazor.modules.json'. The test asserts publish succeeds, a single
_framework/blazor.modules.json endpoint is produced, and the app's generated manifest (with
the RCL module) supersedes the WebView fallback.

ConsumerBuild gains an isolateNuGetFeeds option so P2P builds inherit the repo NuGet.config
(needed to build the referenced source project) instead of the isolated package feed used by
the PackageReference tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use deferred static web asset group for WebView modules.json (rely on dotnet/sdk#54941)

Reverts the framework-asset modeling and the in-package publish workaround. With the SDK fix
in dotnet/sdk#54941 (resolved deferred static web asset groups are persisted into the build
manifest and re-applied, unscoped, when the manifest is reloaded at publish), the idiomatic
deferred-group authoring that the WebView package already uses is correct end-to-end:
blazor.modules.json is a Package static web asset in the deferred BlazorWebViewModules group,
resolved to drop the fallback when the app contributes its own JS modules and keep it
otherwise. No framework-asset hack and no package-local workaround are needed, so the WebView
product files are unchanged from main.

This PR now contributes the static web assets packaging + build/publish regression tests:
- Package-layout tests assert the deferred-group shape for WebView (modules.json = Package in
  BlazorWebViewModules=fallback; webview.js = Framework) and the framework/group shapes for
  Components.WebAssembly, App.Internal.Assets and Identity.UI.
- Build/publish behavior tests (package consumer and ProjectReference consumer) assert a single
  _framework/blazor.modules.json endpoint and that the app's manifest supersedes the fallback.
  The publish assertions are skipped until dotnet/sdk#54941 is in the repo SDK (detected via the
  pre-fix 'Sequence contains more than one element' crash) so the suite stays green meanwhile.

Note: this PR depends on dotnet/sdk#54941 flowing into the repo SDK; until then the in-repo
WebView publish path (and the publish tests) require that fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix WebView blazor.modules.json publish crash via conditional fallback (#67374)

The WebView package ships a fallback _framework/blazor.modules.json (empty []) for
apps that contribute no JS library modules. Modeling it as a deferred static web
asset group required tagging/promoting the consumer's SDK-generated manifest and
depended on an SDK fix (dotnet/sdk#54941) to filter the group at publish; without
it, publish crashed with "Sequence contains more than one element" (#67374).

Replace the group authoring with conditional materialization: the package ships
the fallback raw under build/ (not as a flowing static web asset) and materializes
it as the consumer's own asset during ResolveStaticWebAssetsInputs ONLY when the
app has no JS modules of its own. The decision runs before the build manifest /
conflict check, so exactly one asset ever lands on _framework/blazor.modules.json
and there is never a conflict at build or publish. No asset groups, no consumer
manifest tagging, no SDK dependency.

Tests validate the package layout and build/publish behavior (package + P2P
consumers, with and without JS modules) by cracking the built .nupkg and running
isolated consumer builds under artifacts/ with binlog capture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
lewing pushed a commit to dotnet/aspnetcore that referenced this pull request Jun 24, 2026
…ish crash via conditional fallback (#67374) (#67401)

* [Blazor] Model WebView blazor.modules.json as a framework asset (#67374)

Microsoft.AspNetCore.Components.WebView shipped its fallback blazor.modules.json
via a static web asset group (BlazorWebViewModules=fallback) plus manifest-promotion
targets. At publish, group filtering runs with SkipDeferred=true, so the fallback was
not excluded and GenerateStaticWebAssetEndpointsManifest saw two AssetKind=All assets
on _framework/blazor.modules.json, throwing 'Sequence contains more than one element'
in MAUI Blazor Hybrid apps that also reference a JS-module-contributing RCL.

Model blazor.modules.json as a framework static web asset (like
Microsoft.AspNetCore.Components.WebAssembly ships its JS): BasePath '/', assets under
wwwroot/_framework/, and StaticWebAssetFrameworkPattern '**/*.js;**/*.modules.json'.
The framework pattern is matched against the fingerprinted relative path, so a suffix
glob (*.modules.json) is required for the JS module manifest to be classified as a
Framework asset. The deferred BlazorWebViewModules group + promotion targets are
removed; a minimal StaticWebAssets.Groups.targets keeps JSModuleManifestRelativePath
and CompressionEnabled for consumers.

Add a test project that cracks the built .nupkg files and asserts the static web assets
layout/shape for the WebView, WebAssembly, App.Internal.Assets and Identity.UI packages,
plus end-to-end build/publish tests that reference the locally-built WebView package
from a generated app (and a JS-module RCL) and validate the produced endpoints.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix WebView ProjectReference publish conflict and improve packaging tests

The framework-asset modeling of blazor.modules.json/blazor.webview.js broke publish for
in-repo projects that reference the WebView project via ProjectReference (the WebView E2E
test and the Photino sample): the SDK applies StaticWebAssetFrameworkPattern when computing
a referenced project's BUILD static web assets but not its PUBLISH assets, so publish ends up
with both the materialized framework asset (SourceType=Discovered, SourceId=consumer) and the
original (SourceType=Project, SourceId=WebView) at the same _framework/... target path and
fails with 'Conflicting assets with the same target path'.

Add a no-op-for-package-consumers workaround in StaticWebAssets.Groups.targets that drops the
redundant Project-sourced WebView framework assets at publish (the materialized copies are the
ones served), and import the groups targets from the WebView E2E test so it (like the Photino
sample) also gets JSModuleManifestRelativePath. Package consumers receive these assets as
SourceType=Package, so nothing is removed for them.

Test improvements:
- Build-behavior tests now create working folders under artifacts/tmp instead of the system
  temp folder.
- Each build/publish captures a binary log under artifacts/log so CI collects it and failures
  can be diagnosed; the working folder is preserved on failure and removed on success.
- Tests log the dotnet invocation, output and binlog path via ITestOutputHelper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add ProjectReference (P2P) publish regression test for WebView framework assets

Adds Publish_ProjectReferenceToWebViewWithJsModuleRcl_SucceedsWithSingleModulesManifest,
which references the WebView source project (not the package) plus a JS-module RCL and runs
'dotnet publish'. This is the exact in-repo scenario that regressed in CI: without the
StaticWebAssets.Groups.targets workaround it fails with 'Conflicting assets with the same
target path _framework/blazor.modules.json'. The test asserts publish succeeds, a single
_framework/blazor.modules.json endpoint is produced, and the app's generated manifest (with
the RCL module) supersedes the WebView fallback.

ConsumerBuild gains an isolateNuGetFeeds option so P2P builds inherit the repo NuGet.config
(needed to build the referenced source project) instead of the isolated package feed used by
the PackageReference tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use deferred static web asset group for WebView modules.json (rely on dotnet/sdk#54941)

Reverts the framework-asset modeling and the in-package publish workaround. With the SDK fix
in dotnet/sdk#54941 (resolved deferred static web asset groups are persisted into the build
manifest and re-applied, unscoped, when the manifest is reloaded at publish), the idiomatic
deferred-group authoring that the WebView package already uses is correct end-to-end:
blazor.modules.json is a Package static web asset in the deferred BlazorWebViewModules group,
resolved to drop the fallback when the app contributes its own JS modules and keep it
otherwise. No framework-asset hack and no package-local workaround are needed, so the WebView
product files are unchanged from main.

This PR now contributes the static web assets packaging + build/publish regression tests:
- Package-layout tests assert the deferred-group shape for WebView (modules.json = Package in
  BlazorWebViewModules=fallback; webview.js = Framework) and the framework/group shapes for
  Components.WebAssembly, App.Internal.Assets and Identity.UI.
- Build/publish behavior tests (package consumer and ProjectReference consumer) assert a single
  _framework/blazor.modules.json endpoint and that the app's manifest supersedes the fallback.
  The publish assertions are skipped until dotnet/sdk#54941 is in the repo SDK (detected via the
  pre-fix 'Sequence contains more than one element' crash) so the suite stays green meanwhile.

Note: this PR depends on dotnet/sdk#54941 flowing into the repo SDK; until then the in-repo
WebView publish path (and the publish tests) require that fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix WebView blazor.modules.json publish crash via conditional fallback (#67374)

The WebView package ships a fallback _framework/blazor.modules.json (empty []) for
apps that contribute no JS library modules. Modeling it as a deferred static web
asset group required tagging/promoting the consumer's SDK-generated manifest and
depended on an SDK fix (dotnet/sdk#54941) to filter the group at publish; without
it, publish crashed with "Sequence contains more than one element" (#67374).

Replace the group authoring with conditional materialization: the package ships
the fallback raw under build/ (not as a flowing static web asset) and materializes
it as the consumer's own asset during ResolveStaticWebAssetsInputs ONLY when the
app has no JS modules of its own. The decision runs before the build manifest /
conflict check, so exactly one asset ever lands on _framework/blazor.modules.json
and there is never a conflict at build or publish. No asset groups, no consumer
manifest tagging, no SDK dependency.

Tests validate the package layout and build/publish behavior (package + P2P
consumers, with and without JS modules) by cracking the built .nupkg and running
isolated consumer builds under artifacts/ with binlog capture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Javier Calvarro Nelson <jacalvar@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants