I am trying to build on TFS an API which contains several projects in dotnet.core3.1
When I run the dotnet build Api.sln command on TFS here is the result
[error] Dotnet command failed with non-zero exit code on the following projects: D: \ TFS \ Agent01 \ _work \ 18 \ s \ PMTApi.sln
Context:
TFS 2017
Dotnet Core 3.1 projects
Source code management on TFS git
Agents unable to connect to the outside (internet)
The dependency imports are done from a private server thanks to the NuGet.Config file set up to redirect the dependency imports not on the https://api.nuget.org/v3/index.json server but well on that of our private company.
Explanation:
On the TFS git source manager, the PMTApi.sln project contains 7 .csproj files
But in the PMTApi.sln file there are only 4 .csproj which are included
Local result:
Is good dotnet build completes the 5 successful projects.
Result on TFS:
Not good.
[error] Dotnet command failed with non-zero exit code on the following projects: D: \ TFS \ Agent01 \ _work \ 18 \ s \ PMTApi.sln
Observation:
I have the impression that TFS is based on all the .csproj files from the TFS git source manager and not from PMTApi.sln
Conclusion the projects which are not referenced in PMTApi.sln still try to restore the dependencies which causes the top error.
Test:
I tried to exclude these 3 .csproj projects in my NuGet.Config file like this, but it doesn't work
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="XXX NuGet Packages" value="http://privateServer/nuget" />
</packageSources>
<ItemGroup>
<ProjectReference Exclude="..\folderName1\projectName1.csproj" />
<ProjectReference Exclude="..\folderName2\projectName2.csproj" />
<ProjectReference Exclude="..\folderName3\projectName3.csproj" />
</ItemGroup>
</configuration>
Do you have any ideas for a successful dotnet build task?
The construction:
TFS Return:
Local configuration:
1- here you have to right click on the solution
2- manage package Nuget for solution
3- add the url of your private server
4- and uncheck the server of api.NuGet.org
for my case I also uncheck the visual studio packages
You should specify the csproj file(s) to use in the Project(s) argument, not sln file. Check the description of this argument:
The path to the csproj file(s) to use. You can use wildcards (e.g.
**/*.csproj for all .csproj files in all subfolders). This field follows glob pattern, and is run against root of the repository at all
times irrespective of Working Directory.
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops
Related
I'm trying to create a dotnet core application and deploy it to a kubernetes cluster through azure yaml pipelines (with multiple repositories)
I'm hitting the following error:
CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/File.Pod/File.Pod.csproj]
The project was created with this command : dotnet new console -o File.Pod-n File.Pod
My Goal is to deploy an exe. Most of documentations on Internet talks about deployment ASPNET web applications.
csproj generated
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
**<OutputType>Exe</OutputType>**
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.7" />
<PackageReference Include="Models" Version="9704.0.0-beta" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
<PackageReference Include="Utils.Log" Version="2020.9.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared.Lib\File.Service\File.Service.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Helpers\" />
</ItemGroup>
</Project>
And the docker file:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["File.Pod.csproj", "File.Pod/"]
COPY ["Shared.Lib/File.Service/File.Service.csproj", "Shared.Lib/File.Service/"]
COPY ["Shared.Lib/File.DAL/File.DAL.csproj", "Shared.Lib/File.DAL/"]
COPY ["nuget.config", "./"]
RUN dotnet restore "File.Pod/File.Pod.csproj" --configfile nuget.config -nowarn:msb3202,nu1503 --verbosity diag
COPY . .
WORKDIR "/src/File.Pod"
RUN dotnet build "File.Pod.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "File.Pod.csproj" -c Release -o /app
FROM build AS base
RUN apt update && apt install -y openssh-client
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "run"]
As ENTRYPOINT, I tried ENTRYPOINT ["dotnet", "run"] or ENTRYPOINT ["dotnet", "File.POD.DLL"] with no difference.
I feel that the problem is with the type of images ( FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build) , but I'm unsure. I tried various ones with same result.
Exact error log:
2020-09-11T11:05:41.9723837Z Step 10/26 : RUN dotnet build "File.Pod.csproj" -c Release -o /app
2020-09-11T11:05:42.0083655Z ---> Running in 7ed9311b9c89
2020-09-11T11:05:42.7118936Z Microsoft (R) Build Engine version 16.6.0+5ff7b0c9e for .NET Core
2020-09-11T11:05:42.7119408Z Copyright (C) Microsoft Corporation. All rights reserved.
2020-09-11T11:05:42.7119642Z
2020-09-11T11:05:43.1438745Z Determining projects to restore...
2020-09-11T11:05:45.6330496Z Restored /src/File.Pod/File.Pod.csproj (in 2.04 sec).
2020-09-11T11:05:45.6330978Z Restored /src/Shared.Lib/File.Service/File.Service.csproj (in 2.05 sec).
2020-09-11T11:05:45.7516552Z Restored /src/Shared.Lib/File.DAL/File.DAL.csproj (in 101 ms).
2020-09-11T11:05:49.6118355Z File.DAL -> /app/File.DAL.dll
2020-09-11T11:05:50.2378452Z File.Service -> /app/File.Service.dll
2020-09-11T11:05:50.6394251Z CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/File.Pod/File.Pod.csproj]
2020-09-11T11:05:50.6525494Z
2020-09-11T11:05:50.6525914Z Build FAILED.
2020-09-11T11:05:50.6531013Z
2020-09-11T11:05:50.6536286Z CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/File.Pod/File.Pod.csproj]
2020-09-11T11:05:50.6541921Z 0 Warning(s)
2020-09-11T11:05:50.6542199Z 1 Error(s)
8 hours of work and 47 build attempts later:
Changed :
COPY . .
WORKDIR "/src/File.Pod"
to
WORKDIR "/src/File.Pod"
COPY . .
Note : There are tons of docs, but not an exhaustive good one.
I would expect one doc somewhere that would give sufficient knowledge to get started correctly: choice of image, the directory scope, the importance of what to copy (who is able to understand the importance of "COPY . ." that copies the source code to avoid this error, etc...
I started 2 days ago with docker, vsts pipeline, multiple repositories and can already write a book with all the (weird,generic and obscure) errors I hitted.Not talking about the next step now in error, the problems to install docker in windows 2019 (in a VM hosted in Amazon), linux images that do not work (by default?) on the windows 2019 env.
What a nightmare, I wonder what is mature, hitted more problems these past 2 days than over the last decade ! :-)
TeamCity Professional 2019.1.2 (build 66342)
NuGet.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value=".\packages" />
</config>
<packageSources>
<add key="TFS" value="https://tfs.mydomain.com/nuget/nuget" />
</packageSources>
</configuration>
I have a .NET CLI (dotnet) restore build step including Build Feature NuGet feed credentials
The corresponding command works fine when run from local shell :
> "C:\Program Files\dotnet\dotnet.exe" restore MySolution.sln
> --packages \\packages --source https://tfs.mydomain.com/nuget/nuget --runtime win-x64 --configfile NuGet.config
But TeamCity job run on agent fails with 401 unauthorized :
[15:30:52][restore] C:\Program Files\dotnet\sdk\2.2.101\NuGet.targets(114,5): error : Failed to retrieve information about 'Dapper' from remote source 'https://tfs.mydomain.com/nuget/nuget/FindPackagesById()?id='Dapper'&semVerLevel=2.0.0'.
[15:30:52][restore] C:\Program Files\dotnet\sdk\2.2.101\NuGet.targets(114,5): error : Response status code does not indicate success: 401 (Unauthorized).
I assume shell dotnet restore uses my Windows login creds - exactly what's specified in my Build Feature NuGet feed credentials
Note that I can successfully use same creds in VisualStudio to Manage NuGet Packages ( restore packages on build ).
Try to use the key of the source (TFS) and not the url itself.
Like this;
"C:\Program Files\dotnet\dotnet.exe" restore MySolution.sln --packages \\packages --source tfs --runtime win-x64 --configfile NuGet.config
If that doesn't work, try to add your user credentials manually
nuget sources add -name foo.bar -source C:\NuGet\local -username foo -password bar -StorePasswordInClearText -configfile %AppData%\NuGet\my.config
I am trying to use .NET Core + Ionide + VS Code + Fake + Paket on macOS High Sierra.
Using the project generator, I have created a Suave application called Test. Ionide seems to have generated the appropriate files. After tweaking the TargetFramework to .NET Core, I can build successfully:
$ ./build.sh
...
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:03.72
Finished Target: Build
---------------------------------------------------------------------
Build Time Report
---------------------------------------------------------------------
Target Duration
------ --------
Clean 00:00:00.0026904
InstallDotNetCLI 00:00:01.2292511
Restore 00:00:04.2731055
Build 00:00:07.1234434
Total: 00:00:12.7035334
---------------------------------------------------------------------
Status: Ok
---------------------------------------------------------------------
There are now some files in Test/bin, but none of them are .exe, which is what I would expect as output from fsharpc.
Where does Ionide + Fake put the output executable?
My project has OutputType executable:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Test.fs" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>
.Net Core compiles all projects (even executable applications) to .dll not .exe that can be run with dotnet PATH_TO_DLL. In the bin folder, in the subfolder for given framework target there should be file YOUR_PROJECT_NAME.dll that can be run with dotnet CLI.
To generate an exe you need to supply a run-time identifier. You can include this in the fsproj with
<PropertyGroup>
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
</PropertyGroup>
but you don't need to do that. You can use VSCode's tasks.json file to set up a build task.
My suggestion is just to run the dotnet CLI:
dotnet build -c Release -r win10-x64
This will create an exe in the bin\release\netcoreapp2.0\win10-x64 folder. You can also dotnet publish if you want a self-contained directory to deploy (this can get large). The id for OSX will be something like osx-x64.
By default ionide generates an fsproj file that is targetting net461, and you might also need Fake 5 for dotnetcore. I also suggest you use paket in magic-mode, and commit the .exe to github (if you use git).
There is a webproject with a batchfile that generates all files needed on the targetserver and puts them in a folder "/Deployable" .
The batch file is quite involved because the project contains a pluginsystem and all plugins need to be copied to a certain location.
When I use webdeploy to deploy to the targetserver it happens what you expect: there are some of the needed assemblies copied over, but not the files as specified in the batchfile.
My plan is now to first execute the batchfile and then use webdeploy to copy the folder "/Deployable" to the targetserver. Can this be done with webdeploy?
This is what I see in Visual Studio deploy menue:
This is the resulting publish profile
<?xml version="1.0" encoding="utf-8"?> <publishData>
<publishProfile publishUrl="http://myserver/msdeployagentservice"
deleteExistingFiles="False"
ftpAnonymousLogin="False"
ftpPassiveMode="True"
msdeploySite="mysite/"
msdeploySiteID=""
msdeployRemoteSitePhysicalPath=""
msdeployAllowUntrustedCertificate="False"
msdeploySkipExtraFilesOnServer="False"
msdeployMarkAsApp="False"
profileName="publish_to_myserver"
publishMethod="MSDeploy"
replaceMatchingFiles="True"
userName="myuser"
savePWD="True" userPWD="xxx" SelectedForPublish="True" />
</publishData>>
I think there is an ability to add third-party files into webdeploy package by modifying .csproj file, however, I have never had to use it.
Alternatively, you can easily achieve the same result by using MSDeploy's command-line client and its sync verb, by specifying your /Deployable folder as the -source argument and your target server's msdeploy service as the -dest, e.g.:
$(WebDeployToolPath)\msdeploy -verb:sync -source:dirPath='Deployable\' -dest:dirPath='$(DeployDirectoryLocalPath)',computerName=$(DeployTargetURL),userName='$(DeployUserName)',password='$(Password)',authType='Basic' -verbose -allowUntrusted
Substitutions:
$(WebDeployToolPath) - full path to folder with msdeploy executable (e.g. c:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe )
Deployable\ - full path to the folder you wnat to copy to the target server.
$(DeployDirectoryLocalPath) - full local path to the target folder on the target server.
$(DeployTargetURL) - web deploy service URL (e.g. https://192.168.142.55:8172/MsDeploy.axd or http://myserver/msdeployagentservice)
$(DeployUserName) - username to be used for deployment (should be admin for Win 2003)
$(Password) - user's password.
That's it - this command will synchronize Deployable\ folder with $(DeployDirectoryLocalPath) folder (i.e. make the content exactly match).
You can wrap it into an msbuild target in your .csproj file:
<PropertyGroup>
<DeployTargetURL Condition="'$(DeployTargetURL)'==''">https://192.168.142.55:8172/MsDeploy.axd</DeployTargetURL>
<DeployUserName Condition="'$(DeployUserName)'==''">tergetServer\Administrator</DeployUserName>
<Password Condition="'$(Password)'==''">AdminPassword</Password>
<WebDeployToolPath Condition="'$(WebDeployToolPath)'==''">c:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe</WebDeployToolPath>
<Target Name="Deploy">
<Exec Command=""$(WebDeployToolPath)"\msdeploy -verb:sync -source:dirPath='Deployable\' -dest:dirPath='$(DeployDirectoryLocalPath)',computerName=$(DeployTargetURL),userName='$(DeployUserName)',password='$(Password)',authType='Basic' -verbose -allowUntrusted " />
</Target>
And than run it from the command-line in the following way:
%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MyProject.proj /t:Deploy*
What are the work-arounds for builds failing when moved to TFS because now each file is set to read-only?
Using CC.net, TFS2008 (TFS 2010 within 2 months), target framework 3.5, msbuild 3.5.
You can use an exec command to do this in the AfterGet target:
<PropertyGroup>
<MyProperty>D:\BuildSource</MyProperty>
</PropertyGroup>
....
<Exec Command="Attrib -r -s *.* /S /D" WorkingDirectory="$(MyProperty)" />