TeamCity wont create release folder - c#

When using TeamCity and running a build I get the following error message.
13:20:31]Step 1/1: MSBuild (1s)
[13:20:32][Step 1/1] src\DystopiaOnline.proj.teamcity: Build target: BuildSolution
[13:20:32][src\DystopiaOnline.proj.teamcity] BuildSolution
[13:20:32][BuildSolution] C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.proj(36, 5): error MSB4062: The "DystopiaOnline.Build.Tasks.GetUnixTimestamp" task could not be loaded from the assembly C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks/bin/Release/DystopiaOnline.Build.Tasks.dll. Could not load file or assembly 'file:///C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
[13:20:32][Step 1/1] Step MSBuild failed
However when I run the build from the developer command prompt the build works fine. Taking a look inside the C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\D ystopiaOnline.Build.Tasks\bin only shows a Debug folder rather than a Release folder. Running the build from the developer command prompt works ok just building from Team City doesn't.
shouldn't the Release folder be created when the build is run from Team City with the Env variable set to prod? what could be causing this? Anyone any ideas?
In my project solution .proj file have the following conditions set to determine a build configuration. can anyone with any experience working with team city offer any advice as to what the problem may be? thanks.
<PropertyGroup>
<Env Condition="'$(Env)' == ''">dev</Env>
<VersionNumber Condition="'$(VersionNumber)' == ''">1</VersionNumber>
<MSBuildCommunityTasksPath>$(MSBuildThisFileDirectory)/Tasks</MSBuildCommunityTasksPath>
<UnityPath Condition="'$(UnityPath)' == ''">c:\Program Files (x86)\Unity</UnityPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'dev'">
<BuildConfig>Debug</BuildConfig>
<Domain>mmo.dystopiaOnline.dev</Domain>
<SetParamsFile>Parameters.Local.config</SetParamsFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'prod'">
<BuildConfig>Release</BuildConfig>
<Domain>mmo.DystopiaOnline.com</Domain>
<SetParamsFile>Parameters.Production.config</SetParamsFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'sta'">
<BuildConfig>Release</BuildConfig>
<Domain>mmo.DystopiaOnline.sta</Domain>
<SetParamsFile>Parameters.Staging.config</SetParamsFile>
</PropertyGroup>
TeamCity build log
[11:45:53]Checking for changes
[11:45:53]Collecting changes in 1 VCS root (1s)
[11:45:55]Clearing temporary directory: C:\TeamCity\buildAgent\temp\buildTmp
[11:45:55]Publishing internal artifacts
[11:45:55]Checkout directory: C:\TeamCity\buildAgent\work\8c8eb5050252f271
[11:45:55]Updating sources: server side checkout
[11:45:55]Step 1/1: MSBuild (4s)
[11:45:55][Step 1/1] Starting: C:\TeamCity\buildAgent\plugins\dotnetPlugin\bin\JetBrains.BuildServer.MsBuildBootstrap.exe /workdir:C:\TeamCity\buildAgent\work\8c8eb5050252f271 "/msbuildPath:C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe"
[11:45:55][Step 1/1] in directory: C:\TeamCity\buildAgent\work\8c8eb5050252f271
[11:45:59][Step 1/1] src\DystopiaOnline.proj.teamcity: Build target: BuildSolution
[11:45:59][src\DystopiaOnline.proj.teamcity] BuildSolution
[11:45:59][BuildSolution] MSBuild
[11:45:59][BuildSolution] C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.proj(36, 5): error MSB4062: The "DystopiaOnline.Build.Tasks.GetUnixTimestamp" task could not be loaded from the assembly C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks/bin/Release/DystopiaOnline.Build.Tasks.dll. Could not load file or assembly 'file:///C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
[11:45:59][Step 1/1] Process exited with code 1
[11:45:59][Step 1/1] MSBuild output
[11:45:59][Step 1/1] Step MSBuild failed
[11:45:59]Publishing internal artifacts
[11:45:59]Build finished
This is how my project setup look witht the build folder.
link to .proj file on OneDrive
Error after copying release file into TeamCity manually
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(3797, 5): error MSB3027: Could not copy "C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Base\bin\Release\DystopiaOnline.Base.dll" to "bin\Release\DystopiaOnline.Base.dll". Exceeded retry count of 10. Failed.
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(3797, 5): error MSB3021: Unable to copy file "C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Base\bin\Release\DystopiaOnline.Base.dll" to "bin\Release\DystopiaOnline.Base.dll". The process cannot access the file 'bin\Release\DystopiaOnline.Base.dll' because it is being used by another process.

There is a typo in your DystopiaOnline.proj file in the word "Configuraton":
<MSBuild Projects="DystopiaOnline.Build.Tasks/DystopiaOnline.Build.Tasks.csproj" Properties="Configuraton=$(BuildConfig)" />
I think that this is the reason of the incorrect configuration building.

How have you setup the parameter in the build? It's most likely that it's value is not being passed to the build runner so it defaults to dev
<Env Condition="'$(Env)' == ''">dev</Env>
If you are using teamcity parameters it should be a system or environment parameter. You can also check the parameters used in a build by clicking on it and going to the parameters tabs, might want to double check that it has the value you want.

First keep in mind, that Windows path is '\' NOT '/'. In normal cases there is not any different (eg. when you want to put path in Explorer), but sometimes (I run in to some problems with some task in MsBuild) the mechanism doesn't recognize that this is proper path. So change the path to
<MSBuildCommunityTasksPath>$(MSBuildThisFileDirectory)\Tasks\</MSBuildCommunityTasksPath>
(Also MsBuild convention told us to put trailing slash)
And whenever you have reference to "DystopiaOnline.Build.Tasks.dll": [...]src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll.
In the build log, there is not any sign that the MsBuild try to build the DystopiaOnline.Build.Tasks. HOW you specify the order of building your projects? Can you add this project that we can see exactly what MsBuild want to do and in what order.
If you use <UsingTask> inside the same project file that want to build DystopiaOnline.Build.Tasks... It will never work, because MsBuild first try to resolve task and then run targets to build.
It could work on your machine when you already build the project but not in clean environment when there is not (yet) any task.

try creating new system parameter called system.Configuration and set value "Release"

Related

Automatically signing ALL compiled output files

I have a .net-core 3.1 project (Microsoft.NET.Sdk.Web) in gitlab, and am setting up a CI/CD pipeline for it. As the final step, I want to have all the .dll and .exe output files signed by our key. I can do this by manually putting in some 'signtool' commands as a part of the gitlab-ci.yml file, however that requires going into each project and manually tweaking the file to reflect the specifics of that project.
On the other hand, I have been able to add a generic target in the .csproj file which calls signtool as an exec/command on $(TargetDir)$(TargetFileName). This works to a degree - but it doesn't sign everything. In this case, it signs (e.g.) cthulhu.dll, but not also cthulhu.Views.dll (both of which are shown in the CLI output of 'dotnet msbuild') and there's also a cthulhu.exe that is generated but is not shown in the msbuild output and also not signed.
The csproj file has this as the target (tried running both after rebuild and after publish):
<Target Name="SignAssembly" AfterTargets="Rebuild">
<Message Text="Signing assembly '$(TargetDir)$(TargetFileName)'" Importance="high" />
<Exec Command="signtool sign /f "mykey.pfx" /p "snip" /tr http://timestamp.digicert.com "$(TargetDir)$(TargetFileName)"" />
And the gitlab-ci.yml file looks like this (I'm aware that I'm using the sdk docker container, but it seems to let me support .net-core builds anyway, whereas there is a bug preventing the specific .net-core container from working):
image: mcr.microsoft.com/dotnet/framework/sdk:4.8
stages:
- build
- release
build:
stage: build
script:
- 'dotnet build -r win-x64'
release:
stage: release
script:
- 'dotnet add package signtool --version 10.0.17763.132'
- 'dotnet msbuild cthulhu.csproj /t:"Restore;Rebuild;SignAssembly;Publish" /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=bin\Release\netcoreapp3.1\publish\win-x64 /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=True'
artifacts:
name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
paths:
- '.\bin\Release\netcoreapp3.1\publish\win-x64'
Why not use standard tools - Directory.Build.props?
However, now you can add a new property to every project in one step
by defining it in a single file called Directory.Build.props in the
root folder that contains your source. When MSBuild runs,
Microsoft.Common.props searches your directory structure for the
Directory.Build.props file (and Microsoft.Common.targets looks for
Directory.Build.targets). If it finds one, it imports the property.
Directory.Build.props is a user-defined file that provides
customizations to projects under a directory
Indicates that the assembly should be signed:
<SignAssembly>true</SignAssembly>
The key is specified using the following property:
<AssemblyOriginatorKeyFile>key.pfx</AssemblyOriginatorKeyFile>
That is, as a result, these properties will be imported into the projects and you will achieve the desired result.

Could not load file or assembly 'Microsoft.Management.Infrastructure

I am writing a multi-platform c# command line application using .NET Core 3.1 that will need to work as a single executable. I am using Visual Studio 2019 (16.5.4). My OS is Windows 10.0.18363.778 and I intentionally did NOT install Powershell 7. I tested this first bit on my Windows and WSL Ubuntu and it worked until I added Powershell SDK 7. After I installed Microsoft.Powershell.SDK 7.0.0 and when Ì set the project file as follows, everything runs nicely and I can validate I am using PS7 and not Windows PS.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
However, when I add the runtimeIdentifier in PropertyGroup:
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
Build successfully completes without errors. However when I ran (both debuging or standalone) and application hits Powershell.Invoke, it throws a FileNotFound Exception with message:
"Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified."
1) What am I missing to get all depdendencies in the executable directory?
2) When I add the following to create the single executable
<PublishSingleFile>true</PublishSingleFile>
<UseAppHost>true</UseAppHost>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
It does not get created. I get the executable if I use:
"dotnet publish -r win-x64 -c Debug"
but nothing happens when I run it. (This step used to work fine before PS7)
Is there anthing else I need to do to get the single executable running?
I did some research and figured the following:
Answer 1: There is no Runtime identifer specific Microsoft.Management.Infrastructure.dll files in the runtimes directory. Either Powershell SDK does not support all runtime identifers or its a bug. I will take it to github.
Answer 2: Running the single Executable file is misleading. My expected result was creation of a log file which is created in the application directory. I figured that when the single exe is run, it actually unzips ALL the files to the temp directory and runs the application from there (not the single executable) and hence the log file is not created where the single file executabe is.
To resolve your problem, you have to add this reference to your project. It take me 1 day to found this.
<PackageReference Include="NETStandard.Library" Version="1.6.1" />

How do I auto-increment nuget package version using VSTS build process?

In this video from MSDN at the 3:34 second mark, the presenter shows how to append the Build ID to a nuget's version. In the MSBuild arguments, he specifies:
/t:pack /p:PackageVersion=1.0.$(Build.BuildId)
So, when the project is built by VSTS, the nuget assembly's revision number is using the build id.
I would like to do something similar. Instead of hard coding the 1.0 in the build definition, I'd like to retrieve that from .csproj file. I am using the new .csproj file which stores nuget information.
For example, I'd like to specify in the csproj:
<Version>0.0.1-beta</Version>
Then, VSTS would append the BuildID and generate the assembly version as 0.0.0.1-beta.49 (49 being the build id)
I ended up doing the opposite of what Shayki Abramczyk suggested.
I use a task called "Variables Task Pack". It can be found here (and is free at the time of this answer): https://marketplace.visualstudio.com/items?itemName=YodLabs.VariableTasks#qna
Using this task, I set two variable: $(BuildId) and $(ReleaseType). See the settings snapshots at the end of the answer.
Then, in my CSPROJ project file, I modified the nuget version to use the two environment variables. Here's a clip of the project file:
<PropertyGroup>
<Version>0.0.0.0$(BuildId)$(ReleaseType)</Version>
<FileVersion>0.0.0.0$(BuildId)$(ReleaseType)</FileVersion>
...
</PropertyGroup>
IMPORTANT: Notice the extra 0 in front of $(BuildId). I had to add that in order to build locally. Without it, the build failed with an incorrect version format error.
Now, after building, I get the buildid as my revision number and release type appended.
Here are the screen shots showing configuration of both variables.
You can create a Power Shell script that retrieves the version from csproj file, then add the version to a new environment variable with this command: Set-VstsTaskVariable
For Example:
$csprojId = $retrivedIdfromTheFile
Set-VstsTaskVariable -Name "CSPROJ_ID" -Value $csprojId
Now you can use the CSPROJ_ID variable on the MSBuild arguments:
/p:PackageVersion=$(CSPROJ_ID).$(Build.BuildId)

Powershell, Service Bus For Windows Server Programmatically: Command found, module could not be loaded

From C# code I'm trying to retrieve all the namespaces from powershell... (Later more complex things, like creating namespaces)
PowerShell ps = PowerShell.Create();
ps.AddCommand("Import-Module").AddArgument("ServiceBus").Invoke();
var result = ps.AddCommand("Get-SBNamespace").Invoke();
Above code gives the following exception:
The 'Get-SBNamespace' command was found in the module 'ServiceBus',
but the module could not be loaded. For more information, run
'Import-Module ServiceBus'.
Does anyone know how to solve this error?
CURRENT STATUS: after some debugging I've found that no modules are loaded by default in the PowerShell object. Using the code:
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[]{#"serviceBus"});
PowerShell ps = PowerShell.Create(iss);
doesn't work to load the service bus module. Also the code:
ps.AddCommand("Import-Module").AddParameter("-Name", "serviceBus").Invoke();
doesn't work to import the service bus module. Running Visual Studio in administrator mode also doesn't make a difference
Thanks in advance
You didn't say which version of Visual Studio you're using. If it's VS 2012, when you tried the x64 platform target did you make sure that "Prefer 32-bit" was not checked? Even if it was not checked try checking it, saving the project configuration, clearing it and saving again - this worked for me on another project.
UPDATE
It's been suggested elsewhere that there's a bug in VS2012 that shows "Prefer 32-bit" as greyed-out and unchecked when it's actually active. I'm running Update 2 and I don't see that. But it sounds like you might be. I suggest you edit the .csproj file directly.
Whilst "Platform Target" is set at "Any CPU", in Solution Explorer, right-click on the Project name (or, with go to the PROJECT menu) and select "Unload Project". Project files will close and Solution Explorer will display project name (unavailable) > The project file was unloaded:
Right-click on the Project name again and select "Edit project name.csproj". The file is XML and mostly comprises PropertyGroup and ItemGroup elements. In a console project, the first PropertyGroup usually contains a Platform element which should read AnyCPU if you followed my instructions above. The next two PropertyGroups are normally for Debug and Release configurations. If you've added another configuration, it will have its own PropertyGroup. In each of these, look for an element which reads:
<Prefer32Bit>true</Prefer32Bit>
What you should have is an element which reads:
<Prefer32Bit>false</Prefer32Bit>
Either change it or insert it (in each configuration ProjectGroup), save the file and close it. Back in Solution Explorer, right-click the project and select "Reload Project". Let me know if that solves it. You can confirm your PowerShell is now running 64-bit by get the result of
[System.IntPtr]::Size
e.g.
ps.AddScript("[System.IntPtr]::Size");
which will be 4 in an x86 process and 8 in an x64 process.
Which my project set up like this, I was able to load ServiceBus using:
ps.AddCommand("Import-Module").AddArgument("ServiceBus");
Hopefully, you will, too.
I don't have ServiceBus installed so I can't verify exactly what you've tried but
ps.AddCommand("Import-Module").AddArgument("ActiveDirectory").Invoke();
worked for me, so your original syntax looks good.
Just to test for failure, I tried:
ps.AddCommand("Import-Module").AddArgument("CheeseDirectory");
ps.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
var importResult = ps.Invoke();
foreach (PSObject result in importResult)
{
Console.WriteLine(result);
}
and got
The specified module 'CheeseDirectory' was not loaded because no valid
module file was found in any module directory.
Have you tried similar?
Do you take care of your Assembly target in your C# program (x86 versus X64). The module may exist in one target, not in the other. PowerShell exists in both.
Seems you're trying to import some modules and execute the cmdlet or function inside the module, right?
So I think you could try the following code:
PowerShell ps = PowerShell.Create();
Assembly ass = Assembly.LoadFile(#"yourServiceBus.dll");
ps.AddCommand("Import-Module").AddParameter("Assembly", ass).Invoke();
var result = ps.AddCommand("Get-SBNamespace").Invoke();
Hope this could help.

build .net application in Jenkins using MSBuild

I have a .net application built on .net framework 3.5, I am trying to build this application on Jenkins CI server. I've added MSBuild plugin and and have added path to the .exe file of 2.0, 3.5 and 4.0 versions of MSBuild. But my building processes are failing by showing the below error message.
Path To MSBuild.exe: msbuild.exe
Executing command: cmd.exe /C msbuild.exe Neo.sln && exit %%ERRORLEVEL%%
[Test project] $ cmd.exe /C msbuild.exe Neo.sln && exit %%ERRORLEVEL%%
'msbuild.exe' is not recognized as an internal or external command,
operable program or batch file.
Build step 'Build a Visual Studio project or solution using MSBuild.' marked uild as failure
Finished: FAILURE
Could anyone plz help me out..??
To make the MSBuild plugin work, you need to configure the plugin in the Jenkins management screen.
NOTE: in the newer Jenkins versions you find the MSBuild configuration in the Global Tool Configuration:
Note the "Name" field, where I've called this particular configuration v4.0.30319. You could call it anything you like, but ideally the name will somehow refer to the version.
You'll need to refer to this name later in the Jenkins PROJECT that's failing.
Note: The yellow warning implies that the Path to MSBuild field should be populated with a directory name rather than a file name. In practice you do need to enter the filename here too (ie. msbuild.exe) or the build step will fail.
In the Jenkins project that's failing, go to the MSBuild build step.
The first field in the build step is "MSBuild Version". If you created the build step before configuring any MSBuild versions, the value here will be (default).
After configuring one or more MSBuild versions, the drop down will be populated with the available configurations. Select the one you require.
You can see here that I've now selected the named configuration that matches the installation above.
Jenkins | Manage Jenkins | Configure System
scroll down to the MSBuild section and click MSBuild installations
define the full path to msbuild.exe, on my system I have 3.5 and v4.0.30319
Note - specify the path to 32-bit tools even on a 64-bit system, otherwise you might get an error message:
Building Windows Phone application using MSBuild 64 bit is not supported.
So in Jenkins - it could be for example:
Name: Version 3.5
Path: C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe
Name: Version 4.0
Path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSbuild.exe
I think you should set an absolute path for "msbuild.exe" in your Jenkins configuration,
for example:
C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe
You can also add the path where the msbuild.exe is, to the PATH system environment variable of the node (or nodes) that is running that specific job.
You could try executing the
%comspec% /k ""c:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86
command, which will temporarily update your environment path variables to reflect the VS2010 build environment. Execute this before you call MSBUILD and see what happens. I use this in my own build scripts with no issues.
Side note; it's very likely counterproductive to have multiple versions of MSBUILD on your PATH. Concentrate on getting one version working and go from there.

Categories