I wrote about NuGet on GitHub, now it’s time to publish to Codeberg.

Codeberg offers free package hosting. You can store your NuGet packages there. You can remove them when you want. This is a self-hosted solution. You control everything.

But there is one problem. Codeberg runners do not support Windows. This means we must build packages on our local machine. Then we push them to Codeberg. This article shows you how.

First, you need an API key. Codeberg uses this key to know it’s you. To create the key, follow these steps:

  1. Log in to Codeberg
  2. Click your profile picture in the top right corner
  3. Go to Settings
  4. Click Applications on the left sidebar
  5. Under “Manage Access Tokens”, type a name for your token (use something clear like “nuget-push”)
  6. Click Generate Token

What permissions do you need? You only need one permission: write:packages. This lets you upload. You do not need read permissions. You do not need delete permissions for basic publishing.

Important: The token appears only once. Copy it right away. Save it somewhere safe. If you lose it, you must create a new one.

Now you have your API key, but you cannot put it directly in scripts. That is not safe. Instead, we use environment variables. This keeps your key secret. For permanent use on Windows, open PowerShell as Administrator and run this command:

[Environment]::SetEnvironmentVariable("CODEBERG_API_KEY", "your-token-here", "User")

Replace your-token-here with the token you copied earlier. This saves the key permanently. You do not need to set it again after reboot. To check if it works, run:

[Environment]::GetEnvironmentVariable("CODEBERG_API_KEY")

It should show your token.

With the API key ready, we can create the push script. Save this script as push-to-codeberg.ps1 in your project folder.

There is one important thing to know about the folder structure. Your .slnx file (the solution file) must be in the parent directory. The script uses ..\ to go up one level from where the script runs. Also, I put my compiled NuGet packages in ..\target\NuGet. This means after packing, the .nupkg files go to the target folder. You can change this path if your setup is different, but the script expects packages there.

You can look at the example here.

Here is the complete script:

# Get API key from environment variable
$apiKey = [Environment]::GetEnvironmentVariable("CODEBERG_API_KEY")

# Your Codeberg username - change this to your own username
$owner = "nochein"

# The URL for Codeberg NuGet feed
$sourceUrl = "https://codeberg.org/api/packages/$owner/nuget/index.json"

# Pack the project (slnx file is in parent directory)
dotnet pack ..\ -c Release

# Add Codeberg as a package source
dotnet nuget add source $sourceUrl --name codeberg

# Find all packages in ..\target\NuGet and push them
Get-ChildItem "..\target\NuGet" -Filter *.nupkg | ForEach-Object {
    dotnet nuget push $_.FullName --source codeberg --api-key $apiKey --skip-duplicate
}

Before running the script, change the owner name. Replace nochein with your own Codeberg username.

The script does several things. First, it reads your API key from the environment variable you set earlier. Then it packs your project in Release mode. The ..\ tells dotnet to look for the solution file in the parent directory. After packing, it adds Codeberg as a package source so NuGet knows where to push. Finally, it finds every .nupkg file inside ..\target\NuGet and pushes each one to Codeberg. The --skip-duplicate flag is very useful. If a package version already exists on the server, NuGet will not fail. It will simply skip that package and continue.

To run the script, open PowerShell in your project folder and type:

.\push-to-codeberg.ps1

You will see .NET packing your project, then the source being added, and finally each package being uploaded. If everything works, you will see success messages for each package.

Now go to your Codeberg profile and click the Packages tab. Your NuGet packages will be there. You can see all versions, download packages, delete old versions, and see package size. This is your own package store.

To use these packages in your projects, you need a nuget.config file. Create this file in your solution root folder:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="codeberg" value="https://codeberg.org/api/packages/nochein/nuget/index.json" />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    </packageSources>
</configuration>

Replace nochein with your username again. You do not need an API key to download packages. Only to upload them. This means anyone can restore your packages if they know the feed URL.

If you need to remove a package, go to Codeberg and open your profile. Click the Packages tab, then click the package you want to remove. Go to the Settings, find Delete package and click it. Confirm deletion. The storage space is freed immediately.

That is it. Your NuGet packages are now on Codeberg. You can share them with others. You can remove them when not needed. You have your own self-hosted NuGet package store.