When using a git repository to host a ClickOnce project, additional previous versions may exist. This means each version will contain a manifest file so when the sign tool iterates through the ClickOnceSigner looking for a SingleOrDefault manifest to sign, it may find more than one, resulting in the below stack trace.
Repro steps
Publish ClickOnce output
Bump version
Publish ClickOnce output to same directory
Run sign tool on manifest .application file
Profit Encounter exception
Expected behavior
I believe two different behaviors are acceptable here per manifest file:
Iterate across all files, signing as usual.
Iterate across all files. If files were previously signed, for example version 1 was signed previously, don't re-sign.
I believe the preference should probably be with the first, but I'm indifferent
Actual behavior
fail: Sign.Core.ISigner[0]
Sequence contains more than one matching element
System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at Sign.Core.ClickOnceSigner.<>c__DisplayClass9_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 130
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
--- End of stack trace from previous location ---
at Sign.Core.ClickOnceSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 82
at Sign.Core.AggregatingSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/AggregatingSigner.cs:line 204
at Sign.Core.Signer.<>c__DisplayClass3_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/Signer.cs:line 155
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
--- End of stack trace from previous location ---
at Sign.Core.Signer.SignAsync(IReadOnlyList`1 inputFiles, String outputFile, FileInfo fileList, DirectoryInfo baseDirectory, String applicationName, String publisherName, String description, Uri descriptionUrl, Uri timestampUrl, Int32 maxConcurrency, HashAlgorithmName fileHashAlgorithm, HashAlgorithmName timestampHashAlgorithm) in /_/src/Sign.Core/Signer.cs:line 84
Describe the bug
When using a git repository to host a ClickOnce project, additional previous versions may exist. This means each version will contain a manifest file so when the sign tool iterates through the
ClickOnceSigner
looking for aSingleOrDefault
manifest to sign, it may find more than one, resulting in the below stack trace.Repro steps
.application
fileProfitEncounter exceptionExpected behavior
I believe two different behaviors are acceptable here per manifest file:
I believe the preference should probably be with the first, but I'm indifferent
Actual behavior
Additional context
Potentially problematic code:
https://github.com/dotnet/sign/blob/d018f756bb9fea160069bca578f6f1bb33d00549/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs#L125-L132
This issue happened with at least the three latest versions:
0.9.1-beta.24406.1+6584f5d081d8a06660d58d1a777b2352ff376a68
0.9.1-beta.24170.3
0.9.1-beta.24361.2