Why do you need to increase the version of the nuget package? When you push a new nuget package to nuget.org, you need to increase the version of the package. Otherwise, you will get an error. I will show you how to do it automatically with Github Actions. As an example, I will use my nuget package MaximGorbatyuk.DatabaseSqlEndpoints.
TL;DR
- You need
github.run_number
variable to increase the version, - The release.yml file as example for you,
- Code example - MaximGorbatyuk.DatabaseSqlEndpoints.
Workflow
Usually, I use the following workflow:
- Work on a feature in a separate branch. For example,
feature/1234-add-new-feature
. - Create a pull request to the
dev
branch. - Code in the pull request is tested by Github Actions CI.
- If the tests are successful, the pull request is merged to the
dev
branch by me. - If I decide to deply new version of nuget, I merge the
dev
branch to themain
branch. - New code in the
main
branch is used for building nuget package. - the nuget package is deployed to nuget.org.
For automatic version increase, I use a little hack. Github has run_number variable that represents the order number of the pipeline run. I use this number as last version number of the nuget package.
The main problem is how to put this number into the csproj file. Here I use a sed command to replace the version number in the csproj file inside <Version>1.0.0</Version>
. The sed command looks like this:
sed -i "s/\(<Version>\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{github.run_number}}/" ${{env.PROJECT_FILE}}
For example, the version is 1.0.0
and the github.run_number
is 5
. The result will be 1.0.5
. That’s what I need. Let’s see how to use it in Github Actions.
How to setup repository
First of all, you need to add two yml files to your repository:
test.yml
release.yml
The first one test.yml will be responsible for testing the code. The second one release.yml will be responsible for building the nuget package and deploying it to nuget.org.
The test.yml
is very simple. It looks like this:
name: Build and test
on:
push:
branches: [dev] # run tests on push to dev branch
pull_request:
branches: [dev] # OR run tests on pull requests to dev branch
jobs:
Test:
runs-on: ubuntu-latest
env:
solution-file: MaximGorbatyuk.DatabaseSqlEndpoints.sln
steps:
- uses: actions/checkout@v2
- name: Backend build and test
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x" # SDK Version to use.
- name: Install dependencies # installing dependencies for all projects in the solution
run: dotnet restore ${{env.solution-file}}
- name: Test # running tests for all projects in the solution
run: dotnet test ${{env.solution-file}} --no-restore --verbosity normal
The release.yml
is a bit more complicated. It looks like this:
name: Publish nuget
on:
push:
branches: [main] # run deployment on push to main branch
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
project: MaximGorbatyuk.DatabaseSqlEndpoints
PROJECT_FOLDER: ./MaximGorbatyuk.DatabaseSqlEndpoints
PROJECT_FILE: MaximGorbatyuk.DatabaseSqlEndpoints/MaximGorbatyuk.DatabaseSqlEndpoints.csproj
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0.x" # .NET SDK version to use.
# github.run_number is a number of the pipeline run. It is increased automatically.
# That's why we can use it to increase the version of the nuget package.
# Here we replace the last number in the version with github.run_number.
- name: Set version
run: |
echo "Buid version is ${{github.run_number}}"
sed -i "s/\(<Version>\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{github.run_number}}/" ${{env.PROJECT_FILE}}
- name: Build
working-directory: ${{env.PROJECT_FOLDER}}
run: dotnet build --configuration Release
- name: Pack
working-directory: ${{env.PROJECT_FOLDER}}
run: dotnet pack --configuration Release --no-build --output .
# Here we use external public config file to publish nuget package.
# The script needs to know the path to the csproj file and the nuget API key.
- name: Publish nuget package
uses: brandedoutcast/publish-nuget@v2.5.2
with:
PROJECT_FILE_PATH: ${{env.PROJECT_FILE}}
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
The NUGET_API_KEY
is a Github secret variable that contains the API key for nuget.org. Here you can learn how to get it. Here is a screenshot of the secret variable in my repository:
That’s all. Now you can push your code to the dev
branch and it will be tested by Github Actions. When you are ready to deploy new version of nuget package, you need to merge the dev
branch to the main
branch. After that, the release.yml
will be triggered and the new version of the nuget package will be deployed to nuget.org.
If you want to use the same approach in Gitlab CI, you may use CI_PIPELINE_IID
variable instead of github.run_number
. It represents the project-level IID (internal ID) of the current pipeline as well as github.run_number in Github Actions.
I hope this tutorial will be useful for you. If you have any questions, you may find my contacts here.