Best practices for writing addins

This page gives some best practices for writing Cake addins. Each guideline describes either a good or bad practice.

The wording of each guideline indicates how strong the recommendation is:

Do guidelines should nearly always be followed. You need a really unusual case for breaking a Do guideline.

Consider guidelines should generally be followed. You can deviate from a Consider guideline if you fully understand the meaning behind the guideline and have a good reason to do so.

Avoid guidelines indicates something you should almost never do.

Naming

§1.1 Do use Cake.xxx as the naming schema for addins, where xxx is a meaningful and unique name that describes what the addin does.

Why? Following a convention makes it easier for users to find and work with addins. The automated AddinDiscoverer, which is used for auditing and keeping website up to date, also uses this convention to identify Cake addins.

Example:

Cake.Email is the name that clearly identifies the addin for Cake that allows to send emails from the build script. This name is used in the GitHub repo, it's the name of the solution file, it's the name of the project file, the name of the generated assembly and finally, it's also the name of the NuGet package.


§1.2 Do use the same name for the GitHub repo, the C# solution name, the assembly generated from the project and the NuGet package.

Why? Using the same name across different artifacts makes it easier for users and improves results of automated processes.

References

Cake reference

§2.1 Do reference the lowest version of Cake with API compatibility to the latest version (currently 0.33.0).

Why? This gives the best support for different versions of Cake. Addins built against newer versions of Cake might not be compatible with previous versions of Cake and vice-versa, addins built against older versions might not be compatible with future versions of Cake (this is especially true when a future version of Cake introduces breaking changes).

Cake versions which are API compatible with a specific addin will be shown when the addin is added to the Cake website.


§2.2 Do reference a newer version than Cake 0.33.0 if the addin requires a specific functionality.

Why? If a specific feature of Cake is required in an addin the lowest version of Cake which introduces this feature should be referenced to have access to the feature and the best support for different versions of Cake.


§2.3 Do update addin to a newer version of Cake if a version of Cake with breaking changes becomes available.

Why? Cake will output a warning that the addin was built against an incompatible version of Cake and the addin might no longer work. It is incumbent on addin authors to upgrade their references and publish new version of their NuGet packages


§2.4 Avoid dependencies to Cake.Core and Cake.Common in the NuGet package.

Why? Those references are being implicitly added by the Cake engine.

Example:

References to Cake.Core and Cake.Common need to be marked as private assets in the project file:

<ItemGroup>
  <PackageReference Include="Cake.Core" Version="0.33.0" PrivateAssets="All" />
  <PackageReference Include="Cake.Common" Version="0.33.0" PrivateAssets="All" />
</ItemGroup>

When using a nuspec file omit the references to Cake.Core and Cake.Common

.NET target version

§2.4 Consider to multi-target netstandard2.0 and net461.

Why? Since .NET Framework < 4.7.2 has issues with running .NET Standard assemblies, and Cake itself can run on .NET Framework 4.6.1 multi-target addins to netstandard2.0 and net461 will give the maximum compatibility.

Multi-targeting was suggested by Microsoft in this .NET Conf 2018 talk and the underlying issues are explained in this tweet

This replaces the previous suggestion to only target netstandard2.0 starting with Cake 0.26.0 as since then issues were found with running netstandard2.0 on .NET Framwork < 4.7.2.

Package metadata

Icons

§3.1 Do define an icon for the NuGet package.

Why? Icons helps the user to identify Cake addins.


§3.2 Consider using the Cake Contrib icon.

Why? When the addin doesn't have an own product icon, using the Cake Contrib icon gives a common branding to Cake addins.


§3.3 Avoid using the Cake icon.

Why? The Cake icon is reserved for core Cake packages.


§3.4 Do embed the icon in the package.

Why? Using an icon embedded in the package is more reliable then linking to an icon an external web site which hosts the icon.

Example:

This can be done with the following line in the addins .csproj:

<PackageIcon>PackageIcon.png</PackageIcon>

The addins .csproj should also contain a reference to the png file:

<ItemGroup>
    <None Include="..\PackageIcon.png" Pack="true" PackagePath="" />
</ItemGroup>

Notice the Pack attribute, this is particularly important to ensure the file is embedded in the NuGet package.

Until early 2019, the recommendation was to reference the Cake Contrib icon hosted on the rawgit CDN but rawgit announced that it would shutdown in October 2019 therefore the recommendation changed to reference the Cake Contrib icon hosted on the jsDelivr CDN. This recommendation changed once again in the fall of 2019 when NuGet started supporting embedded icons.

Documentation

§4.1 Do follow the Cake Documentation Guidelines.

Why? Proper XML comments and usage of CakeAliasCategoryAttribute is important to be able to show documentation for the addin when the it is added to the Cake website.

§4.2 Do add documentation XML files to the NuGet package.

Why? XML documentation XML files are used to show documentation for the aliases and API provided by the addin on the Cake website.