An empty return value indicates that your build fails. Your comment "setup.msi doesn't exist" confirms that.But how could it be, that build doesn't fail, if the last line of my code is project.BuildMsi(), but fails, if after that string there will be even your Tasks.DigitalySign() method?
Each time and only on clean build. It means, that some files during the first build are creating (writing) too long and msi is not ready to be created and the process is fininshing in a background (direct async writing to the files for example).