target-authoring
Canonical patterns for writing custom MSBuild targets. USE FOR: diagnosing and fixing custom target authoring anti-patterns; broken SDK target chains across files (e.g., Directory.Build.targets silently redefining SDK targets); targets that replace CompileDependsOn instead of extending it with $(Com…
Install / Use
npx skills add dotnet/skills --skill target-authoringInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Content & MediaSupported Platforms
Tags
Our assessment of target-authoring
target-authoring scores 87/100 on our quality scale, 255th of 504 Content & Media skills we index.
Its SKILL.md is 6.5 KB long, well organised into 9 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.
With 5,471 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 2 days ago, so target-authoring is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
target-authoring compared with similar skills
All 4 of these similar skills score higher than target-authoring; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| target-authoring (this skill)by dotnet | 87 | 5.5k | 2d ago | SKILL.md |
| siyuanby siyuan-note | 100 | 46.5k | today | MCP Server |
| algorithmic-artby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 130.2k | 5d ago | SKILL.md |
Frequently asked questions
- How do I install target-authoring?
- Run
npx skills add dotnet/skills --skill target-authoring. The install tabs above show the steps for each supported agent. - Which AI agents does target-authoring work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is target-authoring safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is target-authoring still maintained?
- The repository was last updated 2 days ago, so target-authoring is actively maintained.
Skill content
View source on GitHubname: target-authoring description: "Canonical patterns for writing custom MSBuild targets. USE FOR: diagnosing and fixing custom target authoring anti-patterns; broken SDK target chains across files (e.g., Directory.Build.targets silently redefining SDK targets); targets that replace CompileDependsOn instead of extending it with $(CompileDependsOn); query targets returning stale results from Outputs vs Returns misuse; missing Inputs/Outputs causing unnecessary rebuilds; missing FileWrites registration. Covers DependsOnTargets vs BeforeTargets vs AfterTargets, the Build→CoreBuild three-level pattern, and the $(XxxDependsOn) chain-extension pattern. DO NOT USE FOR: incremental build tuning (use incremental-build), parallelization (use build-parallelism), general anti-patterns (use msbuild-antipatterns), non-MSBuild build systems." license: MIT
Custom Target Authoring Patterns
Canonical patterns from Microsoft.Common.CurrentVersion.targets in the MSBuild repository.
The Three-Level Target Chain
Every major entry point (Build, Rebuild, Clean) delegates to a property listing its dependencies, which chains through Before → Core → After:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
<!-- Empty extensibility targets — users override these -->
<Target Name="BeforeBuild" />
<Target Name="AfterBuild" />
CoreBuild delegates to $(CoreBuildDependsOn) and includes error handlers:
<Target Name="CoreBuild" DependsOnTargets="$(CoreBuildDependsOn)">
<OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent"
Condition="'$(RunPostBuildEvent)' == 'Always'" />
<OnError ExecuteTargets="_CleanRecordFileWrites" />
</Target>
Rules
- Delegate to a property (
DependsOnTargets="$(MyTargetDependsOn)"), not hardcoded targets. OnErrorgoes inside the orchestrating target to ensure cleanup runs even on failure.- Empty Before/After targets are extensibility points. Users override them; SDKs never put logic in them.
Chain Extension — Append, Never Overwrite
When adding a custom target to an existing chain, append to the DependsOn property:
<!-- GOOD: Append to existing chain -->
<PropertyGroup>
<CompileDependsOn>$(CompileDependsOn);MyCodeGenTarget</CompileDependsOn>
</PropertyGroup>
<!-- BAD: Overwrites the entire chain, dropping SDK targets -->
<PropertyGroup>
<CompileDependsOn>MyCodeGenTarget</CompileDependsOn>
</PropertyGroup>
DependsOnTargets vs BeforeTargets vs AfterTargets
| Mechanism | Defined in | Best for |
|---|---|---|
| DependsOnTargets | The target that needs deps | Target explicitly requires others |
| BeforeTargets | The injecting target | Insert before a target you don't own |
| AfterTargets | The injecting target | Insert after a target you don't own |
Validation targets use BeforeTargets to intercept all entry points:
<Target Name="_CheckForInvalidConfigurationAndPlatform"
BeforeTargets="$(BuildDependsOn);Build;$(RebuildDependsOn);Rebuild;$(CleanDependsOn);Clean">
</Target>
Rules:
- Use
DependsOnTargetswhen your target needs specific prerequisites. - Use
BeforeTargets/AfterTargetswhen injecting into a pipeline you don't own. - Prefer
BeforeTargets="CoreCompile"over modifying$(CompileDependsOn)when you don't control the targets file.
Returns vs Outputs
<!-- Build returns items for consumption by referencing projects -->
<Target Name="Build"
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
<!-- GetTargetPath is a lightweight query target -->
<Target Name="GetTargetPath" Returns="@(TargetPathWithTargetPlatformMoniker)" />
Returnsspecifies what the MSBuild task receives when calling this project. Use for inter-project communication.Outputson inner targets is for incrementality (timestamp checks). Use for up-to-date detection.- Never mix the two purposes. Query targets (
GetTargetPath,GetTargetFrameworks) should useReturns, notOutputs.
Target Naming Conventions
| Pattern | Meaning | Example |
|---|---|---|
| _PrefixedName | Internal/private target | _TimeStampBeforeCompile |
| CoreXxx | The actual implementation | CoreBuild, CoreCompile |
| BeforeXxx / AfterXxx | Empty extensibility hooks | BeforeBuild, AfterCompile |
| PrepareXxx | Setup/validation phase | PrepareForBuild |
| ResolveXxx | Discovery/resolution phase | ResolveReferences |
| GetXxx | Lightweight query (no side effects) | GetTargetPath |
Complete Custom Target Template
<!-- 1. Define the DependsOn chain for extensibility -->
<PropertyGroup>
<MyFeatureDependsOn>
_ValidateMyFeatureInputs;
BeforeMyFeature;
CoreMyFeature;
AfterMyFeature
</MyFeatureDependsOn>
</PropertyGroup>
<!-- 2. Outer target with Returns for inter-project communication -->
<Target Name="MyFeature"
DependsOnTargets="$(MyFeatureDependsOn)"
Returns="@(MyFeatureOutput)" />
<!-- 3. Empty extensibility points -->
<Target Name="BeforeMyFeature" />
<Target Name="AfterMyFeature" />
<!-- 4. Core implementation with Inputs/Outputs for incrementality -->
<Target Name="CoreMyFeature"
Inputs="$(MSBuildAllProjects);@(MyFeatureInput)"
Outputs="$(IntermediateOutputPath)myfeature.generated.cs">
<Exec Command="my-tool.exe -o $(IntermediateOutputPath)myfeature.generated.cs" />
<!-- 5. Register outputs for clean tracking -->
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)myfeature.generated.cs" />
<FileWrites Include="$(IntermediateOutputPath)myfeature.generated.cs" />
</ItemGroup>
</Target>
<!-- 6. Validation target runs first in the dependency chain -->
<Target Name="_ValidateMyFeatureInputs">
<Error Text="MyFeatureInput items are required."
Condition="'@(MyFeatureInput)' == ''" />
</Target>
Common Pitfalls
- Overwriting
DependsOnproperties drops SDK targets silently. Always include$(ExistingProperty)when appending. - Using
Outputson query targets causes MSBuild to skip them when "up to date," returning stale data. UseReturns. - Defining targets in
.propsmeansBeforeTargetson SDK targets have nothing to hook into yet. Move targets to.targets. - Forgetting
OnErrorin orchestrating targets means file tracking fails on build errors, breaking subsequent incremental builds.
Related Skills
siyuan
46.5kAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
130.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
