6
votes

I'm using GitLab and I need to create a .gitlab-ci.yml script to run the Continuous Integration pipeline for a project that generates a nuGet package.

I am having serious issues finding reliable documentation to answer this:

Should I use dotnet pack or nuget pack?

nuget.exe is not available as a command unless my CI script downloads it (I am using GitLab so I would have to add something on .gitlab-ci.yml to do so) . My understanding was that dotnet implicitly uses nuget so no need to use directly nuget.

The problem with dotnet pack command is that I cannot reference the nuspec file, it is simply ignored.

I've tried with

dotnet pack 'MyProject.Nuget/MyProject.Nuget.csproj' /p:NuspecFile='MyProject.Nuget/MyProject.NuGet.nuspec' /p:PackageVersion=$VERSION --output nupkgs

Any reliable documentation on what's the right approach for the latest version (dotnet --version is 2.1.401) would be much appreciated as I am unable to create valid nuGet packages that contains multiple dll.

UPDATE: The alternative is:

nuget pack ./*NuGet/*.nuspec -Version $VERSION -OutputDirectory pepe -Prop Configuration=Release -NoDefaultExcludes -Verbosity detailed
3

3 Answers

3
votes

I successfully build now nuGet packages from CI/CD at GitLab for my dotnet core applications.

Things to keep into consideration:

  • The paths are important: My nuspec had paths with the \ windows-style. I needed to change them to linux-style /. Make sure your file src section are referencing dll and pdb that exist at the specified paths or you will get an exception when creating the nuget because it won't find anything. So my nuspec now looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>ToolBelt.Application</id>
    <version>1.0.0</version>
    <authors>TUI</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Shared Contracts and Model for the Application layer</description>
    <projectUrl>https://gitlab.tuiwestern.eu/SalesDistribution/_common-packages/ToolBelt.Application</projectUrl>
  </metadata>
  <files>
    <file src="bin/*/netstandard2.0/ToolBelt.Application.Model.dll" target="lib/netstandard2.0" />
    <file src="bin/*/netstandard2.0/ToolBelt.Application.Model.pdb" target="lib/netstandard2.0" />
    <file src="bin/*/netstandard2.0/ToolBelt.Application.Contracts.dll" target="lib/netstandard2.0" />
    <file src="bin/*/netstandard2.0/ToolBelt.Application.Contracts.pdb" target="lib/netstandard2.0" />
  </files>
</package>
  • The project must have a .gitlab-ci.yml that contains all the steps to build, run generate nuget and push it to a nuget repository (in my case at Artifactory). Example:
#Stages
stages:
  - ci
  - codequality
  - build
  - publish

#Global variables
variables:
  GIT_STRATEGY: $STRATEGY
  BUILD_NUMBER: $CI_PIPELINE_ID

#Jobs
ci:
  image: ocp-golden-images.artifactory.mycompany.eu/gitlab-runner-nuget-dotnet-core:latest
  stage: ci
  script:
    - export VERSION=$(echo $(date +"%Y.%-m%d").$CI_PIPELINE_ID)
    - export NUGET_PACKAGE_FOLDER=nupkgs
    - dotnet build --configuration Release
    - dotnet vstest ./*Tests/bin/Release/**/*Tests.dll
    - mkdir $NUGET_PACKAGE_FOLDER
    - nuget pack ./*NuGet/*.nuspec -Version $VERSION -OutputDirectory $NUGET_PACKAGE_FOLDER -Prop Configuration=Release -NoDefaultExcludes -Verbosity detailed
    - cd $NUGET_PACKAGE_FOLDER
    - dotnet nuget push *.$VERSION.nupkg -s https://artifactory.mycompany.eu/artifactory/api/nuget/MyRepo

So those are all the commands required to build a project with a structure like:

myApp
-ToolBelt.Application.Nuget
--ToolBelt.Application.Nuget.nuspec
-ToolBelt.Application.Contracts
-ToolBelt.Application.Model
-ToolBelt.Application.Model.UnitTests

where the project that contains the nuspec (e.g: ToolBelt.Application.Nuget) MUST have a dependency to each project that is required to be included in the package (e.g: ToolBelt.Application.Contracts and ToolBelt.Application.Model)

0
votes

You must check build logs for errors. Maybe there are some of its presents. I tried to create package and used following: 1. Directory structure

solution \
   interfaces
       bin
           debug
               netcore2.1
                   interfaces.dll
                   common.dll
                   configuration.dll
           interfaces.nuspec
       interfaces.csproj
       IService.cs
   models
   configuration

2. Nuspec content:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
    <metadata>
        <id>Interfaces</id>
        <version>1.0.0</version>
        <authors>Interfaces</authors>
        <owners>Interfaces</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Package Description</description>
    </metadata>
    <files>
        <file src="netstandard2.0\Common.dll" target="lib\netstandard2.0\Common.dll" />
        <file src="netstandard2.0\Configuration.dll" target="lib\netstandard2.0\Configuration.dll" />
        <file src="netstandard2.0\Interfaces.dll" target="lib\netstandard2.0\Interfaces.dll" />
        <file src="netstandard2.0\Models.dll" target="lib\netstandard2.0\Models.dll" />
    </files>
</package>

3. From solution\interfaces folder I run:

dotnet pack interfaces.csproj /p:NuspecFile="bin\debug\interfaces.nuspec"

And all is fine, nupkg contains all *.dll. But if something wrong (paths for example) I got errors.

0
votes

The problem with dotnet pack command is that I cannot reference the nuspec file, it is simply ignored.

For dotnet pack you should define <NuspecFile>***.nuspec</NuspecFile> property in ***.csproj.

https://docs.microsoft.com/en-us/dotnet/core/tools/csproj#nuspecfile https://github.com/NuGet/Home/issues/9788#issuecomment-689151144