Skip to content

Add copy-to-output-directory MSBuild skill (IfDifferent / SkipUnchangedFilesOnCopyAlways) - #883

Merged
YuliiaKovalova merged 4 commits into
dotnet:mainfrom
YuliiaKovalova:ykovalova/copy-to-output-directory-skill
Jul 16, 2026
Merged

Add copy-to-output-directory MSBuild skill (IfDifferent / SkipUnchangedFilesOnCopyAlways)#883
YuliiaKovalova merged 4 commits into
dotnet:mainfrom
YuliiaKovalova:ykovalova/copy-to-output-directory-skill

Conversation

@YuliiaKovalova

Copy link
Copy Markdown
Member

Summary

Adds a focused dotnet-msbuild skill — copy-to-output-directory — documenting how to choose a CopyToOutputDirectory / CopyToPublishDirectory mode, including the IfDifferent mode and the $(SkipUnchangedFilesOnCopyAlways) property introduced in MSBuild 17.13 / .NET SDK 9.0.2xx by dotnet/msbuild#11052.

No existing skill covered this feature — it was only mentioned tangentially in incremental-build and msbuild-antipatterns.

What the skill covers

  • The four modes (Never / PreserveNewest / Always / IfDifferent) with a comparison table.
  • Why Always is a recurring per-build performance hit, and the destination-mutation scenario it was historically used for.
  • IfDifferent semantics: copies when source and destination differ in either direction (newer or older, or size differs), via the Copy task's SkipUnchangedFiles="true" (timestamp + size comparison).
  • The $(SkipUnchangedFilesOnCopyAlways) property for a bulk, non-invasive opt-in on legacy Always items.
  • How the modes flow through the common targets, transitive copy through ProjectReference, and the MSBuild 17.13 / .NET SDK 9.0.2xx+ version requirement.

Changes

  • New: plugins/dotnet-msbuild/skills/copy-to-output-directory/SKILL.md
  • Registered the skill for routing in the msbuild, msbuild-code-review, and build-perf agent files.

Validation

  • markdownlint-cli2 passes with 0 errors on the new file.

Copilot AI review requested due to automatic review settings July 15, 2026 16:13

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

Adds a new dotnet-msbuild skill, copy-to-output-directory, to document MSBuild’s copy-to-output/publish metadata modes (including the newer IfDifferent mode and $(SkipUnchangedFilesOnCopyAlways)), and wires the skill into existing agent routing so it can be recommended during troubleshooting, code review, and build performance work.

Changes:

  • Added a new skill doc: copy-to-output-directory (mode comparison, IfDifferent semantics, and version gating guidance).
  • Updated msbuild, msbuild-code-review, and build-perf agents to reference the new skill for routing and specialization.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
plugins/dotnet-msbuild/skills/copy-to-output-directory/SKILL.md New skill documentation covering CopyToOutputDirectory/CopyToPublishDirectory mode selection and MSBuild 17.13+ features.
plugins/dotnet-msbuild/agents/msbuild.agent.md Adds routing and skill list entry for the new copy-to-output-directory skill.
plugins/dotnet-msbuild/agents/msbuild-code-review.agent.md Adds the new skill to the companion skills reference list.
plugins/dotnet-msbuild/agents/build-perf.agent.md Adds the new skill to the performance-focused specialized skills reference list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adds a focused dotnet-msbuild skill documenting how to choose a
CopyToOutputDirectory / CopyToPublishDirectory mode, including the
`IfDifferent` mode and the `$(SkipUnchangedFilesOnCopyAlways)` property
introduced in MSBuild 17.13 / .NET SDK 9.0.2xx (dotnet/msbuild#11052).

Covers mode semantics (Never/PreserveNewest/Always/IfDifferent), why
`Always` is a per-build perf hit, the SkipUnchangedFiles timestamp+size
comparison, transitive copy through ProjectReference, and version
requirements. Registers the skill in the msbuild, msbuild-code-review,
and build-perf agent routing lists.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
Copilot AI review requested due to automatic review settings July 15, 2026 16:25
@YuliiaKovalova
YuliiaKovalova force-pushed the ykovalova/copy-to-output-directory-skill branch from 2875d0e to a608f8e Compare July 15, 2026 16:25

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

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

Comment thread plugins/dotnet-msbuild/skills/copy-to-output-directory/SKILL.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 15, 2026 16:40

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@github-actions github-actions Bot added the pr-state/ready-for-eval PR is mergeable and awaiting evaluation label Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Skill Validation Results

Model: claude-opus-4.6 | Judge: claude-opus-4.6

🔍 Full Results - additional metrics and failure investigation steps

▶ Sessions Visualisation -- interactive replay of all evaluation sessions
📊 Session Analytics (preview) -- aggregated metrics across evaluation sessions

@github-actions github-actions Bot added waiting-on-review PR state label and removed pr-state/ready-for-eval PR is mergeable and awaiting evaluation labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Evaluation passed for 63ffc97. cc @ViktorHofer @JanKrivanek @dotnet/skills-msbuild-reviewers — please review.

@Evangelink Evangelink 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.

Reviewed in depth — approving. Verified every technical claim against the live dotnet/msbuild Microsoft.Common.CurrentVersion.targets:

  • Target names _CopyOutOfDateSourceItemsToOutputDirectoryAlways, _CopyDifferingSourceItemsToOutputDirectory, and _CopyToOutputDirectoryTransitiveItems — exact match.
  • $(SkipUnchangedFilesOnCopyAlways) defaults to false and is passed as SkipUnchangedFiles="$(SkipUnchangedFilesOnCopyAlways)" on the Always target — correct.
  • IfDifferent target uses SkipUnchangedFiles="true" (timestamp + size heuristic) — correct, and the doc's careful "not a content hash" wording is accurate.
  • FileWrites registration, transitive copy via ProjectReference, and ClickOnce inclusion of IfDifferent alongside Always/PreserveNewest — all confirmed.
  • Version claim (MSBuild 17.13 / SDK 9.0.2xx / dotnet/msbuild#11052, merged 2024-12-05) — accurate.

Non-blocking notes for consideration:

  1. Skill-menu budget headroom (heads-up). Using the validator's exact RenderedSkillMenuCost formula, this brings dotnet-msbuild to 14,953 / 15,000 chars — only ~47 chars of headroom. It passes check, but given the recent restore-15k-skill-budget work, any later skill or a small description tweak will tip the plugin over and silently truncate the alphabetically-last skill's description. Might be worth reclaiming a few chars from an over-long sibling description (e.g. property-patterns ~975, target-authoring ~929) at some point.

  2. Description routing pattern. 16/18 sibling skills use the USE FOR: / DO NOT USE FOR: pattern for routing. This one uses a plain sentence — reasonable given the budget pressure above, just flagging it as an intentional trade-off.

  3. Minor wording. "GetCopyToOutputDirectoryItems ... into three copy targets, which run from CopyFilesToOutputDirectory" — the three copy targets are actually invoked via _CopySourceItemsToOutputDirectory (a dependency of CopyFilesToOutputDirectory). Harmless simplification.

Nice, well-sourced addition. 👍

- Soften the IfDifferent description to avoid overclaiming: it skips
  when "unchanged per MSBuild's heuristic" (timestamp + size, not a
  content hash), rather than "identical"/full Always equivalence.
- Correct the target-flow wording: the three copy targets run as
  dependencies of _CopySourceItemsToOutputDirectory (invoked by
  CopyFilesToOutputDirectory).
- Restore the USE FOR / DO NOT USE FOR routing pattern for the skill's
  frontmatter description, matching sibling skills.
- Reclaim skill-menu budget headroom (per maintainer note) by tightening
  the verbose property-patterns and target-authoring descriptions;
  dotnet-msbuild rendered menu is now ~14,897/15,000 chars.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
Copilot AI review requested due to automatic review settings July 16, 2026 08:35

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

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

Comment thread plugins/dotnet-msbuild/skills/copy-to-output-directory/SKILL.md Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 881d26ad-87b7-48e3-8ec6-043163944437
Copilot AI review requested due to automatic review settings July 16, 2026 08:40

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

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@Evangelink Evangelink 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.

Re-reviewed after the follow-up commits — all three points from my prior review are addressed, and I re-verified the changes:

  • Budget headroom reclaimed. Trimming property-patterns and target-authoring descriptions offsets the now-richer copy-to-output-directory description. Recomputed with the validator's exact RenderedSkillMenuCost formula: dotnet-msbuild is now 14,901 / 15,000 chars (~99 headroom, up from ~47). Fits with a bit more room.
  • USE FOR / DO NOT USE FOR restored on the new skill's description — matches sibling convention.
  • Target-flow wording corrected and accurate. Verified against the common targets: CopyFilesToOutputDirectory_CopySourceItemsToOutputDirectory → the three copy targets (_CopyOutOfDateSourceItemsToOutputDirectory, _CopyOutOfDateSourceItemsToOutputDirectoryAlways, _CopyDifferingSourceItemsToOutputDirectory).
  • IfDifferent description softened to correctly frame SkipUnchangedFiles as a timestamp+size heuristic (not a content hash) — accurate.
  • "an SQLite" article fix — good catch.

All previously-verified technical claims still hold. LGTM. 👍

@YuliiaKovalova
YuliiaKovalova enabled auto-merge (squash) July 16, 2026 08:49
@github-actions github-actions Bot added waiting-on-author PR state label and removed waiting-on-review PR state label labels Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 @YuliiaKovalova — this PR has 1 unresolved review thread(s). When you're ready, please address the feedback and push an update; the triage bot will pick up the next state automatically. (Add the no-stale label to silence further pings.)

@github-actions github-actions Bot added pr-state/ready-for-eval PR is mergeable and awaiting evaluation and removed waiting-on-author PR state label labels Jul 16, 2026

@Evangelink Evangelink 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.

Approving — no changes since my last review (head 7b047f2, already verified). Technical claims check out against MSBuild source, skill-menu budget fits (14,901/15,000), and all earlier feedback was addressed. LGTM. 👍

@YuliiaKovalova
YuliiaKovalova merged commit 9c7436b into dotnet:main Jul 16, 2026
37 checks passed
github-actions Bot added a commit that referenced this pull request Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Skill Validation Results

Skill Scenario Quality Skills Loaded Overfit Verdict
property-patterns Diagnose shared build property issues 5.0/5 → 5.0/5 ✅ property-patterns; tools: skill / ✅ property-patterns; tools: glob, skill ✅ 0.18 [1]
property-patterns Diagnose multi-level property hierarchy bugs 4.3/5 → 5.0/5 🟢 ✅ property-patterns; tools: skill / ✅ property-patterns; tools: skill, bash ✅ 0.18 [2]
property-patterns Fix shared property configuration 5.0/5 → 5.0/5 ✅ property-patterns; tools: glob, skill / ✅ property-patterns; tools: skill ✅ 0.18
target-authoring Diagnose custom target build regression 5.0/5 → 5.0/5 ✅ target-authoring; tools: skill / ✅ target-authoring; tools: skill, bash ✅ 0.18 [3]
target-authoring Diagnose broken SDK target chain across files 3.0/5 → 3.0/5 ✅ target-authoring; tools: skill ✅ 0.18 [4]
target-authoring Fix custom target anti-patterns 4.0/5 → 4.7/5 🟢 ✅ target-authoring; tools: bash, skill, glob / ⚠️ NOT ACTIVATED ✅ 0.18 [5]

[1] (Isolated) Quality unchanged but weighted score is -18.1% due to: judgment, tokens (108549 → 227575), time (66.4s → 83.7s)
[2] ⚠️ High run-to-run variance (CV=101%) — consider re-running with --runs 5
[3] ⚠️ High run-to-run variance (CV=143%) — consider re-running with --runs 5. (Isolated) Quality unchanged but weighted score is -11.9% due to: judgment, tokens (94587 → 118464)
[4] ⚠️ High run-to-run variance (CV=1080%) — consider re-running with --runs 5
[5] ⚠️ High run-to-run variance (CV=320%) — consider re-running with --runs 5. (Plugin) Quality unchanged but weighted score is -6.7% due to: tokens (91323 → 290219), time (41.1s → 80.8s), tool calls (9 → 15)

Model: claude-opus-4.6 | Judge: claude-opus-4.6

🔍 Full Results - additional metrics and failure investigation steps

To investigate failures, paste this to your AI coding agent:

For PR 883 in dotnet/skills, download eval artifacts with gh run download 29489283964 --repo dotnet/skills --pattern "skill-validator-results-*" --dir ./eval-results, then fetch https://raw.githubusercontent.com/dotnet/skills/7b047f26a74f59b806f66b31231fb9cf741bbb7e/eng/skill-validator/src/docs/InvestigatingResults.md and follow it to analyze the results.json files. Diagnose each failure, suggest fixes to the eval.yaml and skill content, and tell me what to fix first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-state/ready-for-eval PR is mergeable and awaiting evaluation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants