Enlighten RequiresFramework35SP1Assembly task for multithreaded mode#13575
Conversation
The task computes a single boolean output from in-memory inputs only: no filesystem, environment, process, or AppDomain access, and no shared mutable static state. Per the multithreaded-task-migration skill (Step 1b), the `[MSBuildMultiThreadableTask]` attribute alone is sufficient -- `IMultiThreadableTask` is not implemented because there is no `TaskEnvironment` consumer. Adds baseline unit tests covering each predicate in `Execute`, the `CreateDesktopShortcut` framework-version gate, and the SP1/Net35 sentinel identity short-circuit, since the task previously had no direct coverage. Fixes #13572 Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Decorates RequiresFramework35SP1Assembly as multithreadable (attribute-only) as part of the built-in task multithreaded migration, and adds direct unit tests to lock in existing ClickOnce-related predicate behavior.
Changes:
- Add
[MSBuildMultiThreadableTask]toRequiresFramework35SP1Assembly. - Add new unit tests covering the task’s independent trigger conditions (URL, shortcut + TFV gate, signing, suite name, and
IncludeHash=false/ sentinel identities).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Tasks/RequiresFramework35SP1Assembly.cs | Marks the task as eligible for multithreaded execution via attribute. |
| src/Tasks.UnitTests/RequiresFramework35SP1Assembly_Tests.cs | Adds predicate-focused unit coverage for RequiresMinimumFramework35SP1 computation. |
There was a problem hiding this comment.
Review Summary — Multithreaded Task Migration for RequiresFramework35SP1Assembly
Overall: Clean PR, correct migration. The task is purely in-memory (string compares, Version parse/compare, ITaskItem metadata reads) with no filesystem, environment variable, process, or shared static state access. The [MSBuildMultiThreadableTask] attribute alone (without IMultiThreadableTask) is the correct approach per the migration guidance.
✅ What looks good
| Dimension | Assessment |
|---|---|
| Multithreaded migration | Correct — attribute-only pattern matches Message, Error, Warning, Telemetry, etc. No IMultiThreadableTask needed since there are no file/env operations. |
| Static state safety | Verified — ConvertFrameworkVersionToString and CompareFrameworkVersions are pure static functions. No shared mutable state. |
| Backwards compatibility | No behavior change — attribute is additive metadata only. |
| Test coverage | Strong — 14 tests covering defaults, each Execute predicate independently, version parsing edge cases (v-prefix and bare), SP1/sentinel identity short-circuit, and the CreateDesktopShortcut TFV gate. |
| Test isolation | Each test creates its own task instance via CreateTask(). No shared state between tests. |
| Concurrency | Task instance is not shared across threads. All fields are instance-scoped. Safe. |
| API surface | No public API changes — [MSBuildMultiThreadableTask] is detected by namespace/name, not assembly. |
| Naming / conventions | Test class follows {TaskName}_Tests convention. Method names describe behavior clearly. |
📝 Minor suggestions (non-blocking)
#nullable disableon new file — Project guidelines say new files should use nullable reference types. Minor style point.- Missing negative test for benign items — A test with items present but not triggering (e.g.,
IncludeHash=true, non-matching identity) would strengthen theIsExcludedFileOrSP1Filenegative-path coverage.
No correctness issues, no breaking changes, no performance concerns.
Generated by Expert Code Review (on open) for issue #13575 · ● 1.9M
- Drop SigningManifests=true default from CreateTask helper. Split the defaults case into two tests so the bare-default behavior (UncheckedSigning triggers) is documented alongside the signing-enabled no-trigger baseline. Per-predicate tests now set SigningManifests=true explicitly. - Remove `#nullable disable` from the new test file per repo convention for new files. Co-authored-by: Copilot <[email protected]>
AR-May
left a comment
There was a problem hiding this comment.
LGTM. The task indeed does not need any change, the tests looks reasonable.
…work35sp1-assembly
Updated [Microsoft.Build](https://github.com/dotnet/msbuild) from 18.6.3 to 18.7.1. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Build's releases](https://github.com/dotnet/msbuild/releases)._ ## 18.7.1 ## What's Changed * Fix TraceEngine file contention deadlock in multithreaded mode by @JanProvaznik in dotnet/msbuild#13446 * Remove duplicate test cases in MultithreadableTaskAnalyzer by @Youssef1313 in dotnet/msbuild#13483 * Ensure ThreadSafeTaskAnalyzer.Tests is considered as a unit test project by @Youssef1313 in dotnet/msbuild#13481 * Fix MSBuildTask0002 analyzer warnings in already-migrated tasks by @JanProvaznik in dotnet/msbuild#13466 * Fix race conditions in task host path resolution by @AR-May in dotnet/msbuild#13485 * Migrate ToolTask and Al task to TaskEnvironment API by @OvesN in dotnet/msbuild#13423 * Bump main to 18.7, add vs18.6 to merge flow by @MichalPavlik in dotnet/msbuild#13472 * Avoid allocations in GetHashCode implementations by @DustinCampbell in dotnet/msbuild#13475 * Add PATs rotation to agentic workflow(s) by @JanKrivanek in dotnet/msbuild#13496 * Fix ASP.NET WebSite projects to copy netstandard.dll facade when required by @JanProvaznik in dotnet/msbuild#13058 * Migrate AspNetCompiler to TaskEnvironment API by @OvesN in dotnet/msbuild#13424 * Add review workflow by @JanKrivanek in dotnet/msbuild#13503 * Strengthen reviewer skill: add step-back analysis dimensions by @JanProvaznik in dotnet/msbuild#13504 * Add 'Request Speedometer Perf Run' to VS experimental insertion build policies by @Copilot in dotnet/msbuild#13505 * Remove duplicate @ prefix from issueAuthor in GitOps by @akoeplinger in dotnet/msbuild#13492 * Improve review aw by @JanKrivanek in dotnet/msbuild#13510 * Migrates unit tests to use RoslynCodeTaskFactory to enable running tests under .NET Core by @jankratochvilcz in dotnet/msbuild#13500 * Fix cross-AppDomain TaskItem modifier cache regression by @DustinCampbell in dotnet/msbuild#13493 * Discourage review agent from approving PRs by @JanKrivanek in dotnet/msbuild#13512 * Stop trying to deploy ValueTuple by @rainersigwald in dotnet/msbuild#13507 * Ad-hoc re-sign bootstrap dotnet on macOS to prevent SIGKILL by @jankratochvilcz in dotnet/msbuild#13513 * RoslynCodeTaskFactory: Log MSB3753 when task class does not implement ITask by @jankratochvilcz in dotnet/msbuild#13517 * Update gh-aw (upon mcp policy changes) by @JanKrivanek in dotnet/msbuild#13526 * Eliminate XmlChildNodes allocations in GetXmlNodeInnerContents by @nareshjo in dotnet/msbuild#13509 * Fix telemetry allocation regression: per-engine collector ownership by @JanProvaznik in dotnet/msbuild#13516 * Migrate to xunit.v3 by @Youssef1313 in dotnet/msbuild#13482 * Fix stray brace in HandleBuildCancel trace string causing MSB1025 by @Copilot in dotnet/msbuild#13535 * Bumping to 10.0.4 runtime packages by @MichalPavlik in dotnet/msbuild#13533 * Remove early return in GetCanonicalForm, always call System.IO.Path by @OvesN in dotnet/msbuild#13532 * Do not overwrite GetCopyToOutputDirectoryItemsDependsOn, just add new… by @snechaev in dotnet/msbuild#13474 * Migrate GetReferenceAssemblyPaths task to TaskEnvironment API by @OvesN in dotnet/msbuild#13495 * Stabilize ToolTaskThatTimeoutAndRetry test by @rainersigwald in dotnet/msbuild#13489 * [automated] Merge branch 'vs18.6' => 'main' by @github-actions[bot] in dotnet/msbuild#13506 * Add extra test assertions around tests by @Youssef1313 in dotnet/msbuild#13536 * Add static eval for repo skills/agents via skill-validator by @JanKrivanek in dotnet/msbuild#13537 * Migrate SGen task to Task environment API by @OvesN in dotnet/msbuild#13457 * Fix TerminalLogger assert failure for metaproj files and cached project eval ID by @OvesN in dotnet/msbuild#13480 * Filter out approving review from pr-reviewer agent by @JanKrivanek in dotnet/msbuild#13553 * Use a unique task name per invocation to tabilize RoslynCodeTaskFactory_ReuseCompilation test by @huulinhnguyen-dev in dotnet/msbuild#13551 * Brief doc on feedback/logging/data systems by @rainersigwald in dotnet/msbuild#13554 * Localized file check-in by OneLocBuild Task: Build definition ID 9434: Build ID 13881982 by @dotnet-bot in dotnet/msbuild#13437 * Stage 3: Forward BuildProjectFile* callbacks from OOP TaskHost to worker node by @JanProvaznik in dotnet/msbuild#13350 * Enable TaskHost Callbacks by default by @JanProvaznik in dotnet/msbuild#13579 * Remove unactionable info from reviewer agent by @JanKrivanek in dotnet/msbuild#13578 * Enlighten RequiresFramework35SP1Assembly task for multithreaded mode by @jankratochvilcz in dotnet/msbuild#13575 * Make SdkResolver-provided environment variables take precedence over ambient environment by @Copilot in dotnet/msbuild#12655 * Add dotnet/skills marketplace and enable plugins by @Evangelink in dotnet/msbuild#13582 * The skills/agents check filters-in only touched files by @JanKrivanek in dotnet/msbuild#13586 * Fix skill-validation workflow failing when agents directory is deleted by @JeremyKuhne in dotnet/msbuild#13592 ... (truncated) Commits viewable in [compare view](dotnet/msbuild@v18.6.3...v18.7.1). </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
RequiresFramework35SP1Assemblyis purely in-memory (string compares,Versionparse/compare,ITaskItemmetadata reads) — no filesystem, env vars, process start, or shared static state. Per themultithreaded-task-migrationskill Step 1b, the[MSBuildMultiThreadableTask]attribute alone is sufficient;IMultiThreadableTaskis not needed. No code changes toExecuteor helpers, no targets change, no ChangeWave.The task previously had no direct unit coverage. Added 14 test cases locking in the contract: defaults, each
Executepredicate triggering independently, theCreateDesktopShortcutTFV ≥ v3.5 gate (bothv-prefixed and bare version strings), and the SP1/Net35Client sentinel identity short-circuit. Passing onnet10.0andnet472.Fixes #13572