Skip to content

Commit

Permalink
feat(dotnet): add target "SignAfterPack"
Browse files Browse the repository at this point in the history
Beware! Very fragile! Handle with care.
Known quirk: If you use the `-p:PropertyName=PropertyValue` to assign a value containing a comma, MSBuild will throw an error because it treats commas in -p: as a delimiter between property assignments. Assign to an environment variable of the same name, instead.
  • Loading branch information
BinToss committed Sep 23, 2024
1 parent 054162f commit 502322d
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions dotnet/SignAfterPack.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<!-- Inputs:
bool IncludeSymbols
string PackageId
string PackageOutputPath
string PackageVersion
/// formats: ["symbols.nupkg", "snupkg"]
string SymbolPackageFormat = "symbols.nupkg";
Also, see PropertyGroup 'DotnetNugetSign'
-->
<Project>
<PropertyGroup Condition=" '$(AssemblyName)' == '' ">
<PackageId>AssemblyName</PackageId>
<PackageVersion>1.0.0</PackageVersion>
<SymbolPackageFormat>symbols.nupkg</SymbolPackageFormat>
</PropertyGroup>

<PropertyGroup Label="DotnetNugetSign">
<!-- Directory where the signed package(s) should be saved. By default the original package is overwritten by the signed package. -->
<DotnetNugetSignOutput></DotnetNugetSignOutput>
<!-- File path to the certificate to be used while signing the package. -->
<DotnetNugetSignCertificatePath></DotnetNugetSignCertificatePath>
<!-- (default: "My") Name of the X.509 certificate store to use to search for the certificate. Defaults to "My", the X.509 certificate store for personal certificates. This option should be used when specifying the certificate via $(DotnetNugetSignCertificateSubjectName) or $(DotnetNugetSignCertificateFingerprint).
(values: ["AddressBook","AuthRoot","CertificateAuthority","Disallowed","My","Root","TrustedPeople","TrustedPublisher"])
-->
<DotnetNugetSignCertificateStoreName></DotnetNugetSignCertificateStoreName>
<!-- (default: "CurrentUser") Name of the X.509 certificate store to use to search for the certificate. Defaults to "CurrentUser", the X.509 certificate store used by the current user. This option should be used when specifying the certificate via $(DotnetNugetSignCertificateSubjectName) or $(DotnetNugetSignCertificateFingerprint). -->
<DotnetNugetSignCertificateStoreLocation></DotnetNugetSignCertificateStoreLocation>
<!-- (required if DotnetNugetSignCertificatePath unspecified) Subject name of the certificate used to search a local certificate store for the certificate. The search is a case-insensitive string comparison using the supplied value, which will find all certificates with the subject name containing that string, regardless of other subject values. The certificate store can be specified by $(DotnetNugetSignCertificateStoreName) and $(DotnetNugetSignCertificateStoreLocation) options. -->
<DotnetNugetSignCertificateSubjectName></DotnetNugetSignCertificateSubjectName>
<!-- (required if DotnetNugetSignCertificatePath unspecified) SHA-1 fingerprint of the certificate used to search a local certificate store for the certificate. The certificate store can be specified by $(DotnetNugetSignCertificateStoreName) and $(DotnetNugetSignCertificateStoreLocation) options. -->
<DotnetNugetSignCertificateFingerprint></DotnetNugetSignCertificateFingerprint>
<!-- Password for the certificate, if needed. This option can be used to specify the password for the certificate. The command will throw an error message if certificate is password protected but password is not provided as input. -->
<DotnetNugetSignCertificatePassword></DotnetNugetSignCertificatePassword>
<!-- (default: "SHA256") Hash algorithm to be used by the RFC 3161 timestamp server. Defaults to SHA256. -->
<DotnetNugetSignHashAlgorithm></DotnetNugetSignHashAlgorithm>
<!-- URL to an RFC 3161 timestamping server. Signed packages should include a timestamp to make sure the signature remains valid when the signing certificate has expired. Else the sign operation will produce a warning. See NU3002 (https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3002)
(Noah Sherwin: for the sake of convenience, I have set the default value of this property to https://rfc3161.ai.moda/) -->
<DotnetNugetSignTimestamper>https://rfc3161.ai.moda/</DotnetNugetSignTimestamper>
<!-- (default: "SHA256") Hash algorithm to be used by the RFC 3161 timestamp server. Defaults to SHA256. -->
<DotnetNugetSignTimestampHashAlgorithm></DotnetNugetSignTimestampHashAlgorithm>
<!-- (default: false) Switch to indicate if the current signature should be overwritten. By default the command will fail if the package already has a signature. -->
<DotnetNugetSignOverwrite></DotnetNugetSignOverwrite>

<PropA>string1</PropA>
<PropB>string0 "$(PropA)"</PropB>
</PropertyGroup>

<Target Name="SignAfterPack" AfterTargets="Pack">
<PropertyGroup>
<_PackageFileName>$(PackageId).$(PackageVersion).nupkg</_PackageFileName>
<_PackageFullPath>$([MSBuild]::NormalizePath($(PackageOutputPath), $(_PackageFileName)))</_PackageFullPath>
<_SymbolPackageFileName>$(PackageId).$(PackageVersion).$(SymbolPackageFormat)</_SymbolPackageFileName>
<_SymbolPackageFullPath>$([MSBuild]::NormalizePath($(PackageOutputPath), $(_SymbolPackageFileName)))</_SymbolPackageFullPath>

<!-- _argsDotnetNugetSign -->

<_argsDotnetNugetSignOutput Condition=" '$(DotnetNugetSignOutput)' != '' ">--output "$(DotnetNugetSignOutput)"</_argsDotnetNugetSignOutput>
<_argsDotnetNugetSignCertificatePath Condition=" '$(DotnetNugetSignCertificatePath)' != '' ">--certificate-path "$(DotnetNugetSignCertificatePath)"</_argsDotnetNugetSignCertificatePath>
<_argsDotnetNugetSignCertificateStoreName Condition=" '$(DotnetNugetSignCertificateStoreName)' != '' ">--certificate-store-name "$(DotnetNugetSignCertificateStoreName)"</_argsDotnetNugetSignCertificateStoreName>
<_argsDotnetNugetSignCertificateStoreLocation Condition=" '$(DotnetNugetSignCertificateStoreLocation)' != '' ">--certificate-store-location "$(DotnetNugetSignCertificateStoreLocation)"</_argsDotnetNugetSignCertificateStoreLocation>
<_argsDotnetNugetSignCertificateSubjectName Condition=" '$(DotnetNugetSignCertificateSubjectName)' != '' ">--certificate-subject-name "$(DotnetNugetSignCertificateSubjectName)"</_argsDotnetNugetSignCertificateSubjectName>
<_argsDotnetNugetSignCertificateFingerprint Condition=" '$(DotnetNugetSignCertificateFingerprint)' != '' ">--certificate-fingerprint "$(DotnetNugetSignCertificateFingerprint)"</_argsDotnetNugetSignCertificateFingerprint>
<_argsDotnetNugetSignCertificatePassword Condition=" '$(DotnetNugetSignCertificatePassword)' != '' ">--certificate-password "$(DotnetNugetSignCertificatePassword)"</_argsDotnetNugetSignCertificatePassword>
<_argsDotnetNugetSignHashAlgorithm Condition=" '$(DotnetNugetSignHashAlgorithm)' != '' ">--hash-algorithm "$(DotnetNugetSignHashAlgorithm)"</_argsDotnetNugetSignHashAlgorithm>
<_argsDotnetNugetSignTimestamper Condition=" '$(DotnetNugetSignTimestamper)' != '' ">--timestamper "$(DotnetNugetSignTimestamper)"</_argsDotnetNugetSignTimestamper>
<_argsDotnetNugetSignTimestampHashAlgorithm Condition=" '$(DotnetNugetSignTimestampHashAlgorithm)' != '' ">--timestamp-hash-algorithm "$(DotnetNugetSignTimestampHashAlgorithm)"</_argsDotnetNugetSignTimestampHashAlgorithm>
<_argsDotnetNugetSignOverwrite Condition=" '$(DotnetNugetSignOverwrite)' != '' ">--overwrite</_argsDotnetNugetSignOverwrite>

<_args>$(_argsDotnetNugetSignOutput)|$(_argsDotnetNugetSignCertificatePath)|$(_argsDotnetNugetSignCertificateStoreName)|$(_argsDotnetNugetSignCertificateStoreLocation)|$(_argsDotnetNugetSignCertificateSubjectName)|$(_argsDotnetNugetSignCertificateFingerprint)|$(_argsDotnetNugetSignCertificatePassword)|$(_argsDotnetNugetSignHashAlgorithm)|$(_argsDotnetNugetSignTimestamper)|$(_argsDotnetNugetSignTimestampHashAlgorithm)|$(_argsDotnetNugetSignOverwrite)"</_args>
</PropertyGroup>

<ItemGroup>
<_PackageOutputs Include="$(_PackageFullPath);"/>
<_PackageOutputs Condition="'$(IncludeSymbols)' == 'true'" Include="$(_PackageFullPath);$(_SymbolPackageFullPath)"/>
</ItemGroup>

<Message Importance="high" Text="$(_args.replace('|', ' ').trim())"/>

<Exec Command="dotnet nuget sign &quot;@(_PackageOutputs, '&quot; &quot;')&quot; $(_args.replace('|', ' ').trim())"/>
</Target>

<!--
Todo: explore potential use of Nuget.Packaging's Signing namespace. See https://www.nuget.org/packages/NuGet.Packaging, https://github.com/NuGet/NuGet.Client/tree/dev/src/NuGet.Core/NuGet.Packaging/Signing
-->
</Project>

0 comments on commit 502322d

Please sign in to comment.