NuGet packages in the package registry
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
Publish NuGet packages in your project’s package registry. Then, install the packages whenever you need to use them as a dependency.
The package registry works with:
To learn about the specific API endpoints these clients use, see the NuGet API reference.
Learn how to install NuGet.
Authenticate to the package registry
You need an authentication token to access the GitLab package registry. Different tokens are available depending on what you’re trying to achieve. For more information, review the guidance on tokens.
- If your organization uses two-factor authentication (2FA), you must use a
personal access token with the scope set to
api
. - If you publish a package with CI/CD pipelines, you can use a CI/CD job token with private runners. You can also register a variable for instance runners.
Use the GitLab endpoint for NuGet packages
You can use either a project or group endpoint to interact with the GitLab package registry:
- Project endpoint: Use when you have a few NuGet packages that are not in the same group.
- Group endpoint: Use when you have many NuGet packages in different projects under the same group.
Some actions, like publishing a package, are only available on the project endpoint.
Because of how NuGet handles credentials, the package registry rejects anonymous requests to public groups.
Add the package registry as a source for NuGet packages
To publish and install packages to the package registry, you must add the package registry as a source for your packages.
Prerequisites:
- Your GitLab username
- An authentication token (the following sections assume a personal access token)
- A name for your source
- A project or group ID
With the project endpoint
To add the package registry as a source with NuGet CLI, run the following command:
nuget source Add -Name <source_name> -Source "https://gitlab.example.com/api/v4/projects/<project_id>/packages/nuget/index.json" -UserName <gitlab_username> -Password <personal_access_token>
Replace:
<source_name>
with your source name<project_id>
with the project ID found on the project overview page<gitlab_username>
with your GitLab username<personal_access_token>
with your personal access token
For example:
nuget source Add -Name "GitLab" -Source "https://gitlab.example.com/api/v4/projects/10/packages/nuget/index.json" -UserName carol -Password <your_access_token>
With the group endpoint
To add the package registry as a source with NuGET CLI:
nuget source Add -Name <source_name> -Source "https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/nuget/index.json" -UserName <gitlab_username> -Password <personal_access_token>
Replace:
<source_name>
with your source name<group_id>
with the group ID found on the Group overview page<gitlab_username>
with your GitLab username<personal_access_token>
with your personal access token
For example:
nuget source Add -Name "GitLab" -Source "https://gitlab.example.com/api/v4/groups/23/-/packages/nuget/index.json" -UserName carol -Password <your_access_token>
Publish a package
Prerequisites:
- Set up the package registry as a source.
- Configure the GitLab project endpoint for NuGet packages.
When publishing packages:
- Review the maximum file size limits for your GitLab instance:
- The package registry limits on GitLab.com instances vary by file format, and are not configurable.
- The package registry limits on GitLab Self-Managed instances vary by file format, and are configurable.
- If duplicates are allowed, and you publish the same package with the same version multiple times, each consecutive upload is saved as a separate file. When installing a package, GitLab serves the most recent file.
- Most uploaded packages should be immediately visible in the Package registry page. A few packages might take up to 10 minutes before they are visible if they need to be processed in the background. a package.
With NuGet CLI
Prerequisites:
To publish a package, run the following command:`
nuget push <package_file> -Source <source_name>
Replace:
<package_file>
with your package filename, ending in.nupkg
.<source_name>
with the name of your source.
For example:
nuget push MyPackage.1.0.0.nupkg -Source gitlab
With .NET CLI
Prerequisites:
To publish a package, run the following command:
dotnet nuget push <package_file> --source <source_name>
Replace:
<package_file>
with your package filename, ending in.nupkg
.<source_name>
with the name of your source.
For example:
dotnet nuget push MyPackage.1.0.0.nupkg --source gitlab
You can publish a package using the --api-key
option instead of username
and password
:
dotnet nuget push <package_file> --source <source_url> --api-key <personal_access_token>
Replace:
<package_file>
with your package filename, ending in.nupkg
.<source_url>
with the URL of the NuGet package registry.
For example:
dotnet nuget push MyPackage.1.0.0.nupkg --source https://gitlab.example.com/api/v4/projects/<project_id>/packages/nuget/index.json --api-key <personal_access_token>
With Chocolatey CLI
Prerequisites:
- A source using a project endpoint.
To publish a package with the Chocolatey CLI, run the following command:
choco push <package_file> --source <source_url> --api-key <gitlab_personal_access_token, deploy_token or job token>
Replace:
<package_file>
with your package filename, ending in.nupkg
.<source_url>
with the URL of the NuGet v2 feed package registry.
For example:
choco push MyPackage.1.0.0.nupkg --source "https://gitlab.example.com/api/v4/projects/<project_id>/packages/nuget/v2" --api-key <personal_access_token>
With a CI/CD pipeline
If you’re publishing NuGet packages with GitLab CI/CD, you can use a
CI_JOB_TOKEN
predefined variable instead of
a personal access token or deploy token. The job token inherits the permissions of the
user or member that generates the pipeline.
The examples in the following sections address common NuGet publishing workflows when using a CI/CD pipeline.
Publish packages when the default branch is updated
To publish new packages each time the main
branch is
updated:
In the
.gitlab-ci.yml
file of your project, add the followingdeploy
job:default: # Updated to a more current SDK version image: mcr.microsoft.com/dotnet/sdk:7.0 stages: - deploy deploy: stage: deploy script: # Build the package in Release configuration - dotnet pack -c Release # Configure GitLab package registry as a NuGet source - dotnet nuget add source "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text # Push the package to the project's package registry - dotnet nuget push "bin/Release/*.nupkg" --source gitlab rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Only run on the main branch environment: production
Commit the changes and push them to your GitLab repository to trigger a new CI/CD build.
Publish versioned packages with Git tags
To publish versioned NuGet packages with Git tags:
In the
.gitlab-ci.yml
file of your project, add the followingdeploy
job:publish-tagged-version: stage: deploy script: # Use the Git tag as the package version - dotnet pack -c Release /p:Version=${CI_COMMIT_TAG} /p:PackageVersion=${CI_COMMIT_TAG} # Configure GitLab package registry as a NuGet source - dotnet nuget add source "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text # Push the package to the project's package registry - dotnet nuget push "bin/Release/*.nupkg" --source gitlab rules: - if: $CI_COMMIT_TAG # Only run when a tag is pushed
Commit the changes and push them to your GitLab repository.
Push a Git tag to trigger a new CI/CD build.
Publish conditionally for different environments
You can configure the CI/CD pipeline to conditionally publish NuGet packages to different environments depending on your use case.
To conditionally publish NuGet packages
for development
and production
environments:
In the
.gitlab-ci.yml
file of your project, add the followingdeploy
jobs:# Publish development/preview packages publish-dev: stage: deploy script: # Create a development version with pipeline ID for uniqueness - VERSION="0.0.1-dev.${CI_PIPELINE_IID}" - dotnet pack -c Release /p:Version=$VERSION /p:PackageVersion=$VERSION # Configure GitLab package registry as a NuGet source - dotnet nuget add source "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text # Push the package to the project's package registry - dotnet nuget push "bin/Release/*.nupkg" --source gitlab rules: - if: $CI_COMMIT_BRANCH == "develop" environment: development # Publish stable release packages publish-release: stage: deploy script: - dotnet pack -c Release # Configure GitLab package registry as a NuGet source - dotnet nuget add source "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text # Push the package to the project's package registry - dotnet nuget push "bin/Release/*.nupkg" --source gitlab rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH environment: production
Commit the changes and push them to your GitLab repository.
With this CI/CD configuration:
- Pushing NuGet packages to the
develop
branch publishes packages to the package registry of yourdevelopment
environment. - Pushing NuGet packages to the
main
branch publishes NuGet packages to the package registry of yourproduction
environment.
- Pushing NuGet packages to the
Turn off duplicate NuGet packages
You can publish multiple packages with the same name and version.
To prevent group members and users from publishing duplicate NuGet packages, turn off the Allow duplicates setting:
- On the left sidebar, select Search or go to and find your group.
- Select Settings > Packages and registries.
- In the NuGet row of the Duplicate packages table, turn off the Allow duplicates toggle.
- Optional. In the Exceptions text box, enter a regular expression that matches the names and versions of packages to allow.
You can also turn off duplicate NuGet packages with the
nuget_duplicates_allowed
setting in the GraphQL API.
If the .nuspec
file is not located in the root of the package
or the beginning of the archive, the package might
not be immediately recognized as a duplicate. When it is inevitably recognized as
a duplicate, an error displays in the Package manager page.
Install a package
The GitLab package registry can contain multiple packages with the same name and version. If you install a duplicate package, the latest published package is retrieved.
Prerequisites:
- Set up the package registry as a source.
- Configure the GitLab endpoint for NuGet packages.
From the command line
Install the latest version of a package by running this command:
nuget install <package_id> -OutputDirectory <output_directory> \
-Version <package_version> \
-Source <source_name>
<package_id>
: The package ID.<output_directory>
: The output directory, where the package is installed.<package_version>
: Optional. The package version.<source_name>
: Optional. The source name.nuget
checksnuget.org
for the requested package first. If GitLab package registry has a NuGet package with the same name as a package atnuget.org
, you must specify the source name to install the correct package.
With NuGet v2 feed
Prerequisites:
- A v2 feed source for Chocolatey.
- A package version must be provided when installing or upgrading a package with NuGet v2 feed.
To install a package with the Chocolatey CLI:
choco install <package_id> -Source <source_url> -Version <package_version>
<package_id>
: The package ID.<source_url>
: The URL or name of the NuGet v2 feed package registry.<package_version>
: The package version.
For example:
choco install MyPackage -Source gitlab -Version 1.0.2
# or
choco install MyPackage -Source "https://gitlab.example.com/api/v4/projects/<project_id>/packages/nuget/v2" -u <username> -p <personal_access_token> -Version 1.0.2
To upgrade a package with the Chocolatey CLI:
choco upgrade <package_id> -Source <source_url> -Version <package_version>
<package_id>
: The package ID.<source_url>
: The URL or name of the NuGet v2 feed package registry.<package_version>
: The package version.
For example:
choco upgrade MyPackage -Source gitlab -Version 1.0.3
Delete a package
Deleting a package is a permanent action that cannot be undone.
Prerequisites:
- You must have the Maintainer role or higher in the project.
- You must have both the package name and version.
To delete a package with the NuGet CLI:
nuget delete <package_id> <package_version> -Source <source_name> -ApiKey <personal_access_token>
<package_id>
: The package ID.<package_version>
: The package version.<source_name>
: The source name.
For example:
nuget delete MyPackage 1.0.0 -Source gitlab -ApiKey <personal_access_token>
Symbol packages
GitLab can consume symbol files from the NuGet package registry. You can use the GitLab package registry as a symbol server to debug your NuGet packages.
Whenever you publish a NuGet package file (.nupkg
),
symbol package files (.snupkg
) are uploaded automatically
to the NuGet package registry.
You can also push them manually:
nuget push My.Package.snupkg -Source <source_name>
Use the GitLab endpoint for symbol files
GitLab package registry provides a special symbolfiles
endpoint that you can configure
with your project or group endpoint:
Project endpoint:
https://gitlab.example.com/api/v4/projects/<project_id>/packages/nuget/symbolfiles
- Replace
<project_id>
with the project ID.
- Replace
Group endpoint:
https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/nuget/symbolfiles
- Replace
<group_id>
with the group ID.
- Replace
The symbolfiles
endpoint is the source where a configured debugger
can push symbol files.
Use the package registry as a symbol server
To use the symbol server:
- Enable the
nuget_symbol_server_enabled
namespace setting with the GraphQL API. - Configure your debugger to use the symbol server.
For example, to configure Visual Studio as your debugger:
- Select Tools > Preferences.
- Select Debugger > Symbol sources.
- Select Add.
- Enter the symbol server URL.
- Select Add Source.
After you configure the debugger, you can debug your application as usual. The debugger automatically downloads the symbol PDB files from the package registry if they’re available.
Consume symbol packages
When the debugger is configured to consume symbol packages, the debugger sends the following information in a request:
Symbolchecksum
header: The SHA-256 checksum of the symbol file.file_name
request parameter: The name of the symbol file. For example,mypackage.pdb
.signature
request parameter: The GUID and age of the PDB file.
The GitLab server matches this information to a symbol file and returns it.
Keep in mind that:
- Only portable PDB files are supported.
- Because debuggers cannot provide authentication tokens, the symbol server endpoint does not support typical authentication methods.
The GitLab server requires the
signature
andSymbolchecksum
to return the correct symbol file.
Supported CLI commands
The GitLab NuGet repository supports the following commands for the NuGet CLI (nuget
) and the .NET
CLI (dotnet
):
NuGet | .NET | Description |
---|---|---|
nuget push | dotnet nuget push | Upload a package to the registry. |
nuget install | dotnet add | Install a package from the registry. |
nuget delete | dotnet nuget delete | Delete a package from the registry. |
Troubleshooting
When working with NuGet packages, you might encounter the following issues.
Clear the NuGet cache
To improve performance, NuGet caches package files. If you encounter storage issues, clear the cache with the following command:
nuget locals all -clear
Errors when publishing NuGet packages in a Docker-based GitLab installation
You might get the following error messages when publishing NuGet packages:
Error publishing
Invalid Package: Failed metadata extraction error
Webhook requests to local network addresses are blocked to prevent exploitation of internal web services.
To resolve these errors, change your network settings to allow webhook and integration requests to the local network.
Docs
Edit this page to fix an error or add an improvement in a merge request.
Create an issue to suggest an improvement to this page.
Product
Create an issue if there's something you don't like about this feature.
Propose functionality by submitting a feature request.
Feature availability and product trials
View pricing to see all GitLab tiers and features, or to upgrade.
Try GitLab for free with access to all features for 30 days.
Get help
If you didn't find what you were looking for, search the docs.
If you want help with something specific and could use community support, post on the GitLab forum.
For problems setting up or using this feature (depending on your GitLab subscription).
Request support