Developing a Modern .NetCore Console Application: (4) Automating Build and Publishing NuGet Packages Using GitHub Actions
GitHub Actions automatically build and publish NuGet packages, saving time and effort. Secrets manage tokens, and the workflow works once and for all. Complaining about repeatedly entering tokens for NuGet push, annoying!
目录12 个章节
Preface
The previous article covered publishing nuget packages to GitHub Packages.
This article takes it a step further by using GitHub Actions to set up a CI/CD pipeline for automatic building and publishing of nuget packages. 😎
GitHub Actions works similarly to the GitLab CI/CD I used before. You can use runners provided by GitHub or configure your own servers as runners.
For details, you can refer to what I wrote previously: Continuous Integration Guide: Configuring and Using GitLab's CI/CD Tools
First, create a token
Address: https://github.com/settings/tokens
This was also covered in the previous article, so I won't go into detail here.
Make sure to save this token properly. Once you navigate away from this page, you won't be able to see it again, as it's only displayed once.
Configuring GitHub Secrets
Sensitive information is not suitable for storing in code. Here, GitHub provides the Secret and variables feature.
Address: https://github.com/Deali-Axy/fluent-dotnet-console/settings/secrets/actions
Add the token we created to the Action's secrets.
I named it TOKEN here.
When using it later in the GitHub Workflow configuration, it will look like this:
${{secrets.TOKEN}}
Writing Workflow Configuration
Create a new .github/workflows directory in the project root
PS: This can be done directly on the GitHub website by clicking "Add File" and typing
/in the filename field to automatically recognize it as a directory
Next, start writing the workflow configuration file. It's similar to the previous Gitlab CICD configuration and is also in YAML format.
Here, I'll create a file named publish-nuget.yml
# Publishing a New NuGet Package
name: publish-nuget
run-name: ${{ github.actor }} is publishing a nuget package 🚀
on: [push]
jobs:
publish-nuget-packages:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Restore dependencies
run: dotnet restore ./src/Templates/FluentConsole.Templates.csproj
- name: Build
run: dotnet build --no-restore -c Release ./src/Templates/FluentConsole.Templates.csproj
- name: Create the package
run: dotnet pack -c Release ./src/Templates/FluentConsole.Templates.csproj
- name: Add nuget source
run: dotnet nuget add source --username DealiAxy --password ${{ secrets.TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/Deali-Axy/index.json"
- name: Publish the package to Github Packages
run: dotnet nuget push ./src/Templates/bin/Release/*.nupkg --api-key ${{ secrets.TOKEN }} --source github --skip-duplicate
Introduction to Some Configurations
In this file, I configured a job named publish-nuget-packages to build NuGet packages and push them to GitHub Packages.
The on at the beginning of the file specifies the trigger conditions for this workflow. It can be configured to run only when the master branch is updated. The configuration is as follows:
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
The jobs.<job_id>.runs-on parameter specifies the type of computer to run the job on:
-
The target machine can be a GitHub-hosted runner, a larger runner, or a self-hosted runner.
-
You can target runners based on the labels assigned to them, their group membership, or a combination of both.
-
The
runs-onvalue can be specified in the following forms:- A single string
- A single variable containing a string
- An array of strings, a variable containing strings, or a combination of both
- A
key: valuepair using thegrouporlabelkeys
-
You can specify multiple runners, for example:
// The job will only run on a self-hosted runner with the labels linux, x64, and gpu runs-on: [self-hosted, linux, x64, gpu]This article simply leverages GitHub-hosted runners, so I won't elaborate on the process of setting up your own runner. For details, please refer to the documentation: https://docs.github.com/zh/actions/using-jobs/choosing-the-runner-for-a-job#choosing-self-hosted-runners
Regarding the Setup .NET step, this parameter uses: actions/setup-dotnet@v3 sets up the runtime environment. Similarly, GitHub also provides other environments like Node.js or Gradle, but they are not within the scope of this discussion.
About GitHub-Hosted Runners
When using GitHub-hosted runners, each job runs in a new instance of the runner image specified by runs-on.
Available GitHub-hosted runner types include:
| Virtual Machine | Processor (CPU) | Memory (RAM) | Storage (SSD) | Operating System (YAML Workflow Labels) | Notes |
|---|---|---|---|---|---|
| Linux | 2 | 7 GB | 14 GB | ubuntu-latest, ubuntu-22.04, ubuntu-20.04 | The ubuntu-latest label currently uses the Ubuntu 22.04 runner image. |
| Windows | 2 | 7 GB | 14 GB | windows-latest, windows-2022, windows-2019 | The windows-latest label currently uses the Windows Server 2022 runner image. |
| macOS | 3 | 14 GB | 14 GB | macos-latest, macos-12, macos-11 | The macos-latest workflow label currently uses the macOS 12 runner image. |
| macOS | 4 | 14 GB | 14 GB | macos-13 [Beta] | Unavailable |
Lastly, I want to complain about NuGet's push mechanism. I already specified the token in dotnet nuget add source, but I have to specify it again when using push…
Execute Action
Once done, commit the code.
You can view the execution results on the Action page.

Perfect, hands-free! Plus, you can leverage GitHub's runner compute resources for free 😏
Pushing Packages to the Official NuGet Gallery
The first half of this article focuses on pushing NuGet packages to GitHub Packages using GitHub Actions, which requires installing them from a GitHub source.
Next, we'll investigate how to push to the official NuGet Gallery.
Creating an API Key
Address: https://www.nuget.org/account/apikeys
You can choose an expiration period, with a maximum of 365 days. Remember to update the token before it expires, otherwise all pipelines will become invalid.
After creation, click Copy to copy it. This is similar to GitHub, where the token is only displayed once, and it will be gone the next time you access it, so please save it properly.
Adding GitHub Action Secret
The steps are the same as before.
I added one named NUGET_GALLERY_TOKEN.
Modify Workflow
Modify the configuration of the workflow.
Add one more step at the end.
- name: Publish the package to Nuget Gallery
run: dotnet nuget push ./src/Templates/bin/Release/*.nupkg --api-key ${{ secrets.NUGET_GALLERY_TOKEN }} --source nuget.org --skip-duplicate
The default source is nuget.org, so specifying it is optional.
Use the following command to list the current source list.
dotnet nuget list source
Done~
References
- https://docs.github.com/zh/actions/quickstart
- https://docs.github.com/zh/actions/automating-builds-and-tests/building-and-testing-net
- https://docs.github.com/zh/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token
_EOF_
Developing a Modern .NetCore Console Application: (4) Automating Build and Publishing NuGet Packages Using GitHub Actions
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
C#学习(三)深入理解委托、匿名方法和-Lambda-表达式
前言 lambda的概念建立在委托的基础上,委托,实现了类型安全的回调方法。在.NET 中回调无处不在,所以委托也无处不在,事件模型建立在委托机制上,Lambda 表达式本质上就是一种匿名委托。本文中将完成一次关于委托的旅行,全面阐述委托及其核心话题,逐一梳理委托、委托链、事件、匿名方法和 Lambda 表达式。 委托的定义 了解委托,从其定义开始,通常一个委托被声明为: public deleg
2021-12-18 · C# · 约 1 分钟
开发现代化的.NetCore控制台程序:(3)将nuget包发布到GitHubPackages
发布Nuget包到GitHub Packages?不过是配置token和nuget.config的重复劳动。手动关联包与仓库?GitHub的设计真够奇葩的。搞定,但谁有空折腾这些。
2023-11-10 · C# · 约 1 分钟
C#爬虫:CatSpider#-开发笔记
前言 (PS:我这里用了#号代替了Sharp这个单词) CatSpider是毕设里的数据采集模块,本来爬虫类的应用肯定使用python来开发嘛,不过用request_html做解析的时候,python的动态类型真的把我恶心到了,而且感觉这个库也不是很成熟,html5lib也不好用,也没心思去深入了,之前看到有大佬用.net core平台做爬虫,于是我也来试试,没想到效果贼好,特别是配合LinqPa
2022-05-27 · C# · 约 1 分钟
C#使用iKvm黑科技无缝接入JVM生态
C#开发者用iKVM白嫖JVM生态?省事,但依赖处理还得手动折腾。无缝接入?不过是把JAR转DLL,省了移植代码的麻烦。AI工具缺?直接调用HanLP,但依赖处理,呵呵。
2023-10-06 · C# · 约 1 分钟
讨论
共 0 条加载评论中…