Skip to content

Setting up GitLab as a NuGet Package Source in Visual Studio

TLDR

  • The GitLab Package Registry can serve as a private NuGet repository, allowing for automated packaging and publishing via GitLab CI/CD.
  • Use the dotnet nuget add source command combined with CI_JOB_TOKEN to automate the publishing process within a pipeline.
  • If you encounter the NU1101 error, it is usually because the CI_JOB_TOKEN lacks cross-project or cross-group access permissions; this must be configured in GitLab's "Job token permissions" settings.
  • In Visual Studio, you must use a Personal Access Token with read_api permissions for authentication.
  • If Visual Studio repeatedly prompts for credentials, check if the <packageSourceCredentials> block is correctly written to %AppData%\NuGet\NuGet.Config.

Setting up GitLab CI/CD for Automated Publishing

GitLab does not provide a UI for directly uploading .nupkg files; it is recommended to implement an automated process via GitLab CI/CD. Below is the recommended .gitlab-ci.yml configuration:

yaml
image: 'mcr.microsoft.com/dotnet/sdk:8.0'

stages:
 - pack
 - publish

variables:
 NUGET_PACKAGES_DIRECTORY: '.nuget'

before_script:
 - export PROJECT_FILE=$(find . -type f -name "*.csproj" | head -n 1)
 - export PROJECT_DIR=$(dirname "$PROJECT_FILE")
 - export PROJECT_NAME=$(basename "$PROJECT_FILE" .csproj)
 - dotnet nuget add source "${CI_API_V4_URL}/groups/${PACKAGES_GROUP_ID}/-/packages/nuget/index.json" --name gitlab-packages --username gitlab-ci-token --password ${CI_JOB_TOKEN} --store-password-in-clear-text

pack:
 stage: pack
 tags:
   - docker
 script:
   - dotnet pack $PROJECT_DIR --configuration Release --output $NUGET_PACKAGES_DIRECTORY
 artifacts:
   paths:
     - $NUGET_PACKAGES_DIRECTORY/*.nupkg

publish:
 stage: publish
 tags:
   - docker
 script:
   - dotnet nuget add source "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab-project --username gitlab-ci-token --password ${CI_JOB_TOKEN} --store-password-in-clear-text
   - cd $NUGET_PACKAGES_DIRECTORY
   - for pkg in *.nupkg; do dotnet nuget push "$pkg" --source gitlab-project; done

Handling CI/CD Permission Issues

When you might encounter this issue: When a project needs to reference packages from other projects, or when running dotnet restore within a CI/CD process.

If you see error NU1101: Unable to find package during execution, it is because the $CI_JOB_TOKEN is restricted to accessing its own project by default. Please follow these steps to expand permissions:

  1. Go to "Settings" → "CI/CD".
  2. Click "Add group or project" in the "Job token permissions" section.
  3. Add the group or project that requires access.

TIP

Using the --verbosity detailed parameter can assist with debugging to confirm whether the failure to resolve dependent packages is due to insufficient permissions.

Setting up GitLab Package Source in Visual Studio

Creating an Access Token

To read private packages in Visual Studio, you need to create a Personal Access Token:

  1. Go to "Preferences" → "Access Tokens".
  2. Create a new Token and select the read_api permission.
  3. Copy and save the Token securely.

Configuring Visual Studio

  1. Go to "Tools" → "Options" → "NuGet Package Manager" → "Package Sources".
  2. Add the URL: https://{GitLab Domain}/api/v4/groups/{Group ID}/-/packages/nuget/index.json.
  3. When prompted, enter your GitLab account for the username and the newly generated Token for the password.

Resolving Repeated Credential Prompts

When you might encounter this issue: Visual Studio fails to write the credentials to the configuration file correctly, requiring re-authentication every time the project is opened.

If this happens, manually write the credentials to the NuGet configuration via the command line:

bash
dotnet nuget add source "https://{GitLab Domain}/api/v4/groups/{Group ID}/-/packages/nuget/index.json" --name=GitLab --username={GitLab Account} --password={Access Token}

After execution, check if %AppData%\NuGet\NuGet.Config contains the <packageSourceCredentials> block.

Changelog

    • Initial documentation created.