feat!: always emit dev dependencies with scope=excluded; deprecate --exclude-dev#1044
Open
feat!: always emit dev dependencies with scope=excluded; deprecate --exclude-dev#1044
Conversation
This was referenced Mar 1, 2026
…via BFS
Dev dependencies (PrivateAssets=all / developmentDependency=true) are now
always included in the BOM with scope="excluded" — no flag is needed and
--exclude-dev is deprecated (retained as a no-op for backward compat).
The scope is no longer set eagerly at load time for IsDevDependency.
Instead, Runner performs a BFS from direct runtime references after all
packages are loaded:
- Seeds: direct references that are not dev deps and not already excluded
by the test-project pass (scope=Excluded set in ProjectAssetsFileService).
- BFS follows DotnetDependency.Dependencies. Any package reached via a
runtime path is marked runtime-reachable and its children are queued.
- Packages never reached by the BFS receive scope=Excluded.
This correctly handles the shared-transitive case: a package reachable
from both a dev dep and a runtime dep stays scope=required because the
runtime BFS path reaches it first.
Adds two functional tests covering the transitive-only and shared-transitive
scenarios, and a new docs/dev-and-test-dependencies.md documenting the
behaviour and the rationale for using scope=excluded.
2fcd984 to
2ec29ee
Compare
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
Dev dependencies are now always included in the BOM with
scope="excluded"ratherthan being silently dropped when
--exclude-devis passed. This aligns with theCycloneDX spec, which expects excluded components to be present but marked as such.
Changes
--exclude-devdeprecated — the flag is retained for backward compatibilitybut is now a no-op. Passing it emits a deprecation warning. Planned for removal
in a future major release.
After all packages are loaded, a BFS from direct runtime references determines
reachability. Packages never reached via a runtime path receive
scope=excluded.This correctly handles the shared-transitive case: a package reachable from both
a dev dep and a runtime dep is kept in scope.
ProjectAssetsFileService— dev dependency scope is no longer set eagerly;test-project exclusions are unaffected.
Breaking Change
Previously,
--exclude-devomitted dev dependency entries from the BOM entirely.They are now always present with
scope="excluded". Consumers that relied on theflag to suppress those entries from output will see additional components.
Testing
docs/dev-and-test-dependencies.mddocuments the behavior and rationale.