Skip to content

Quality Improvement: Embedded-project packability intent is implicit for MSTestAdapter.PlatformServices #10709

Description

@github-actions

🎯 Repository Quality Improvement Report — Embedded-Project Packability Intent Clarity

Analysis Date: 2026-08-24
Focus Area: embedded-project-packability-intent-clarity (custom)
Strategy Type: Custom

Executive Summary

MSTest's repo ships several "embedded-only" projects — assemblies that are never published as their own NuGet package but instead get folded into a sibling package via TfmSpecificPackageFile (e.g. MSTest.TestAdapter embeds MSTestAdapter.PlatformServices.dll, TestFramework.Extensions embeds TestFramework.dll). The repo already has an established, well-documented pattern for this: src/TestFramework/TestFramework/TestFramework.csproj explicitly sets <IsPackable>false</IsPackable> with a detailed comment explaining why ("This project is never packed on its own... uses a distinct PackageId so it is not seen as a circular/self reference... Extensions references it directly, NuGet would still surface it as a package dependency, so _RemoveNonPublishableCoreDependency removes it").

src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj follows the exact same embedding pattern (its DLL is copied into MSTest.TestAdapter's buildTransitive folder via TfmSpecificPackageFile, and it is never itself passed to dotnet pack in CI) but has no IsPackable property at all. Under Microsoft.NET.Sdk, IsPackable defaults to true, so this project silently relies on nobody happening to invoke pack on it directly — rather than declaring its non-shipping intent explicitly the way its sibling does. Since the root Directory.Build.targets's _ValidatePackageMetadata target only runs Condition=" '$(IsPackable)' == 'true' " and this project has no PackageDescription/PackageReadmeFile, a future dotnet pack invocation scoped to this project would fail late with an unhelpful "no package description" error, rather than being caught early by an explicit, well-commented IsPackable=false.

This is a maintainability/consistency gap rather than an active break: today's -pack invocations target specific shipping projects, so the missing declaration causes no visible failure. But it leaves the packaging intent of MSTestAdapter.PlatformServices implicit and undocumented, unlike every other embedded-only project in the repo, making it easy for a future contributor to misunderstand the project's shipping status or accidentally regress it when refactoring the Adapter packaging pipeline.

Full Analysis Report

Focus Area: Embedded-Project Packability Intent Clarity

Current State Assessment

Metrics Collected:

Metric Value Status
Projects embedding a sibling DLL via TfmSpecificPackageFile 20 (searched src/**/*.csproj) i️
Embedded-only projects with explicit, documented IsPackable=false (e.g. TestFramework.csproj) 1 pattern found, well documented
Embedded project relying on implicit SDK default (IsPackable unset ⇒ true) while never packed standalone MSTestAdapter.PlatformServices.csproj ⚠️
_ValidatePackageMetadata guard scope Only fires when IsPackable == true (Directory.Build.targets:52-69) i️
MSTestAdapter.PlatformServices.csproj has PackageDescription / PACKAGE.md No / No ⚠️

Findings

Strengths

  • The repo already has a strong, precedent-setting pattern for embedded-only assemblies: TestFramework.csproj explicitly declares <PackageId>NotPublishable</PackageId> + <IsPackable>false</IsPackable> with an in-line comment explaining the rationale and pointing at _RemoveNonPublishableCoreDependency.
  • Directory.Build.targets's _ValidatePackageMetadata target is a solid guard rail that fails packable projects early if they lack a PackageDescription or PackageReadmeFile — it just can't catch projects that never set IsPackable in the first place because it's conditioned on IsPackable == true.
  • All genuinely-shipping Platform packages inherit a well-reasoned default (src/Platform/Directory.Build.props sets IsPackable>true at the directory level for every Platform project, since virtually all of them ship their own package) — that default is appropriate there and not part of this gap.

Areas for Improvement

  • ⚠️ src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj embeds its output DLL into MSTest.TestAdapter's package (TfmSpecificPackageFile Include="$(TargetDir)MSTestAdapter.PlatformServices.dll" PackagePath="$(_BuildTransitiveDir)" in MSTest.TestAdapter.csproj:182) but has no IsPackable declaration of its own, unlike the analogous TestFramework.csproj/TestFramework.Extensions.csproj pair.
  • ⚠️ Because src/Adapter has no Directory.Build.props setting a directory-wide IsPackable default (unlike src/Platform/Directory.Build.props), this project silently falls back to the .NET SDK's own default of IsPackable=true, which is the opposite of its actual shipping status.
  • ⚠️ No documentation (code comment or docs/) records why this specific Adapter project is embedded-only, making the packaging intent discoverable only by tracing TfmSpecificPackageFile references across two other .csproj files.

🤖 Suggested Improvement Tasks

Task 1: Add an explicit, documented IsPackable=false to MSTestAdapter.PlatformServices.csproj

Priority: Medium
Estimated Effort: Small

In src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj, add a <PropertyGroup> with <IsPackable>false</IsPackable> accompanied by a comment mirroring the one in src/TestFramework/TestFramework/TestFramework.csproj (lines 12–17), explaining that this assembly is never packed on its own and is instead embedded into MSTest.TestAdapter's buildTransitive folder via the TfmSpecificPackageFile item in MSTest.TestAdapter.csproj. This turns an implicit, SDK-default-dependent behavior into an explicit, self-documenting one and lets _ValidatePackageMetadata continue to correctly skip the project.


Task 2: Audit remaining embedded-only projects for the same implicit-default gap

Priority: Medium
Estimated Effort: Small

Cross-check every project that appears only as the target of a TfmSpecificPackageFile reference elsewhere in src/**/*.csproj (not as a project that itself declares TfmSpecificPackageFile) against whether it declares IsPackable explicitly, either directly or via an ancestor Directory.Build.props. For any project found relying on an implicit SDK default that doesn't match its real shipping status, add the same explicit declaration + comment as Task 1.


Task 3: Document the "embedded assembly" packaging pattern once, centrally

Priority: Low
Estimated Effort: Small

Add a short section (or a comment block referenced from each embedded project) describing the "embedded-only assembly" pattern used across the repo: IsPackable=false + distinct internal PackageId (where applicable) + TfmSpecificPackageFile in the consuming package + (if the embedded project would otherwise be seen as a package dependency) a _RemoveNonPublishableCoreDependency-style cleanup target. A good home is a comment near _ValidatePackageMetadata in the root Directory.Build.targets, or a short paragraph in docs/ referenced by each embedding project, so future contributors adding a new embedded assembly have a copy-pasteable template instead of re-deriving the pattern from TestFramework.csproj alone.


Task 4: Consider extending _ValidatePackageMetadata (or a companion check) to flag projects with no explicit IsPackable

Priority: Low
Estimated Effort: Medium

Evaluate adding a lightweight guard (e.g. in Directory.Build.targets, gated to $(IsSourceProject)=='true' and projects lacking a directory-level IsPackable default) that emits a warning when a project neither sets IsPackable itself nor inherits it from a Directory.Build.props, nudging authors of new src/ projects to make their packaging intent explicit rather than relying on the SDK default. Scope this carefully to avoid false positives on projects intentionally inheriting src/Platform/Directory.Build.props's IsPackable=true default.


📊 Historical Context

Previous Focus Areas
Date Focus Area Type
2026-08-20 obsolete-attribute-deprecation-consistency Custom
2026-08-19 help-option-description-punctuation-consistency Custom
2026-08-18 banned-symbols-project-wiring-completeness Custom
2026-08-17 executable-condition-attribute-parity-gap Custom
2026-08-04 mtp-exit-code-documentation-gap Custom

🎯 Recommendations

Immediate Actions (This Week)

  1. Add explicit documented IsPackable=false to MSTestAdapter.PlatformServices.csproj (Task 1) — Priority: Medium

Short-term Actions (This Month)

  1. Audit the remaining embedded-only projects and centralize documentation of the pattern (Tasks 2–3) — Priority: Medium/Low

Next analysis: next scheduled run — Focus area selected based on diversity algorithm

🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 114.8 AIC · ⌖ 3.26 AIC · ⊞ 15.2K · [◷]( · )

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
  • expires on Aug 26, 2026, 10:33 PM UTC

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions