• 从一次解决Nancy参数绑定“bug”开始发布自己的第一个nuget包(扩展篇)


    前言

      上一篇,我们已经实现了nuget包的打包,发布到nuget。最近,发现github也有持续集成持续交付部署(CICD)的功能(请原谅我的菜)。原来也没太关注这块,主要原来一直专注于写业务。最近开始系统学习微服务相关的内容,了解到是通过jenkins之类的工具来实现的部署。在github上闲逛的时候,发现有个Actions的功能,就尝试了一番。它是通过一个yml配置文件来实现,代码推送到仓库后,自动打包发布到nuget源和github源。这个过程就是在一个docker环境或者虚拟服务器环境中,将代码clone下来,通过nuget.exe这样的命令行打包上传工具来实现原本人工的操作过程(我猜的)。所以,本文主要实现的就是当我们的代码推送到git仓库后,自动打包nuget package,并推送到nuget.org和github.com。

     

    准备工作

      1.首先,我们先修改一下nuget package的配置文件,准备一个待发布的新版本源码。说明一下,这一步不是必须的,我是为了演示一下这个过程,所以故意把版本号改了。只要你的代码是有修改,未推送到git仓库就行了。

       2.通过copy命令将我们打包所需的文件copy到一个独立的文件夹中,方便打包。

     

     命令行完整代码,这里copy后的文件结构和我们在nuget package explorer里面是一样的。

    copy "$(SolutionDir)Nancy.FixQueryDictionary\bin\Release\Nancy.FixQueryDictionary.dll" "$(SolutionDir)\NugetPublish\Release\lib\Nancy.FixQueryDictionary.dll"
    copy "$(SolutionDir)Nancy.FixQueryDictionary\bin\Release\Nancy.FixQueryDictionary.xml" "$(SolutionDir)\NugetPublish\Release\lib\Nancy.FixQueryDictionary.xml"
    copy "$(SolutionDir)Nancy.FixQueryDictionary\bin\Release\Nancy.FixQueryDictionary.pdb" "$(SolutionDir)\NugetPublish\Release\lib\Nancy.FixQueryDictionary.pdb"
    copy "$(SolutionDir)README.md" "$(SolutionDir)\NugetPublish\Release\README.md"
    

       3.在我们的项目中新建一个yml文件,我这里直接上我自己的yml文件。

    name: GitHub Actions
    on:
      push:
        branches: [ publish ]
      pull_request:
        branches: [ publish ]
    jobs:
      Explore-GitHub-Actions:
        runs-on: ubuntu-latest
        steps:
          - run: echo "该作业由${{github.event_name}}事件自动触发"
          - run: echo "此作业现在正在GitHub托管的${{runner.os}}服务器上运行"
          - run: echo "分支的名称是${{github.ref}},存储库是${{github.repository}}"
          - name: 签出存储库代码
            uses: actions/checkout@v2
          - run: echo "${{github.repository}}存储库已克隆到运行程序"
          - name: 列出存储库中的文件
            run: |
              ls ${{ github.workspace }}
          - name: 列出Release发布的文件
            run: |
              ls NugetPublish/Release
          - name: 安装nuget 
            uses: nuget/setup-nuget@v1
            with:        
                nuget-version: '6.x'
          - name: 打包nuget package
            run: |
                 nuget pack NugetPublish/Nancy.FixQueryDictionary.nuspec -OutputDirectory NugetPublish/Release/
          - name: 添加Github源
            run: |
                dotnet nuget add source --name github "https://nuget.pkg.github.com/OWNER/index.json"
          - name: 发布到Github
            run: |
                dotnet nuget push NugetPublish/Release/*.nupkg  --api-key ${{ secrets.GITHUB_TOKEN }} --source "github" --skip-duplicate
          - name: 发布到NuGet
            run: |
                 dotnet nuget push NugetPublish/Release/Nancy.FixQueryDictionary.1.1.3.nupkg --api-key ${{secrets.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json --skip-duplicate
          - run: echo "此作业的状态为${{job.status}}"
    

    Github工作流yml配置说明

      下面就这个yml配置文件做一下()简()单()的()说()明(),我是经过了九九54次(见下图)的尝试,爬过坑,才最终实现想要的效果。

     

     第一段是定义这个Action(工作流)的名称,触发的仓库分支名称。

    name: GitHub Actions
    on:
      push:  
        branches: [ publish ]#这个表示当代码推送到publish分支时触发工作流执行
    pull_request:
      branches: [ publish ]#这个表示当代码合并推送到publish分支时触发工作流执行(我猜的,等下我们验证一下)

    第二段,定义工作流的job,执行的系统环境,将当前仓库名称打印输出。这些echo的内容并不是必须的,通过这些输出你可以了解到有哪些内置的变量,这些变量通过${{}}来绑定输出。每个独立的动作前面都有一个 - ,如果是一个简单的动作,这个短横线是直接放在run前面,且有一个空格。 

    jobs:
      Explore-GitHub-Actions:
        runs-on: ubuntu-latest
        steps:
          - run: echo "该作业由${{github.event_name}}事件自动触发"
          - run: echo "此作业现在正在GitHub托管的${{runner.os}}服务器上运行"
          - run: echo "分支的名称是${{github.ref}},存储库是${{github.repository}}" 

    这里需要注意空格的数量,多了少了都会报错,具体见下图。具体的格式我也没有仔细去研究,毕竟我们全宇宙第一的IDE会有格式纠错提示。如果你直接在github上创建这个yml文件并进行编辑的话,也是有纠错提示的,多尝试几次就好了。

      第三段,这一段表示将我们要用来打包的代码checkout(签出),这里的users是固定写法(貌似是这样的,我看好几个都是这样的)。后面的echo表示已经job已经执行到这里了,代码已经签出了。这就像我们在控制台打印一些自定义的消息一样的。

    - name: 签出存储库代码
            uses: actions/checkout@v2
          - run: echo "${{github.repository}}存储库已克隆到运行程序"

    第四段,这一段有两个动作,用来显示签出的源代码文件列表和我们要打包的文件列表。这个ls命令不就是Linux里面查看文件目录用的吗?同样的,这两段也不是必须的。

    - name: 列出存储库中的文件
            run: |
              ls ${{ github.workspace }}
          - name: 列出Release发布的文件
            run: |
              ls NugetPublish/Release

      第五段,安装nuget打包工具,这个工具和我们在nuget.org网站下载的那个nuget.exe命令行工具应该是一样的(我猜的)。

    - name: 安装nuget 
            uses: nuget/setup-nuget@v1
            with:        
                nuget-version: '6.x' 

    第六段,使用nuget pack命令打包生成nuget package文件,这个命令我们在nuget.exe执行是一样的效果,见下图。

      后面的OutputDirectory用来指定输出的目录,可以使用相对路径,不指定这个参数的话,会生成在当前目录下。 

    - name: 打包nuget package
            run: |
                 nuget pack NugetPublish/Nancy.FixQueryDictionary.nuspec -OutputDirectory NugetPublish/Release/

    第七段,添加github源,参数name用来指定源的名称,这个名称下面会用到。说实话,我是没搞懂,为啥要设置这个源。这个命令如果你在系统上执行,就是会在你nuget源中新增一个源地址,你可以在vs的nuget package管理器中查看到这个源,也可以使用nuget命令nuget sources来查看,见下图。

    - name: 添加GitHub源        
      run: | dotnet nuget add source --name github "https://nuget.pkg.github.com/OWNER/index.json"

    第八段,这才是重点的一步,将nuget package发布到github上。发布完成之后,这里会有显示,见下图。

     点进去,是这样的。

     

     这里使用nuget push命令来推送,参数api-key用来指定github的PAT(Personal access tokens),毕竟你在脚本中总不能使用明文的github账户密码吧,当然要使用令牌来访问你的账户。参数source用来指定上面的github源,参数skip-duplicate用来指示当上传已经存在的相同版本的nuget package时就跳过推送,否则会报错。这里最大的坑莫过于这个PAT了,坑的我不要不要的。

    - name: 发布到Github
            run: |
                dotnet nuget push NugetPublish/Release/*.nupkg  --api-key ${{ secrets.GITHUB_TOKEN }} --source "github" --skip-duplicates

    申请PAT的流程如下所示:Settings>Developer settings>Personal access tokens

      

       

     

     选择 Generate new token,输入token名称,选择有效期,选择权限。

     

     我这里简单粗暴,直接选择了永不过期+全部权限(哈哈)。然后,你就可以得到一个PAT令牌了。原本我以为在脚本中配置这个令牌应该是这样的${{secrets.nuget_ApiKey}},结果呢,死活都不行,执行的过程中提示401。然而,我在nuget.exe中执行的时候,输入的明文令牌是可以的。后来的后来,我才发现,这里是要这样写才行。

    ${{ secrets.GITHUB_TOKEN }}

    真的是坑的我不要不要的!!!你们说,如果我再弄个令牌,想换一个同时还保留这个,应该怎么办呢?咱也不知道,咱也不敢问,也不纠结了。

    第九段,将nuget package推送到nuget.org,这里需要配置nuget.org申请的ApiKey,怎么申请?上一篇已经说过了,这里我们需要将它作为变量配置在我们的github里。配置过程,如下所示。

    首先,打开仓库的Settings。

     

     选择Secrets,点击New repository secret,输入ApiKey的名称和ApiKey保存即可。

     然后,我们在脚本中使用变量来绑定nuget的ApiKey。

    - name: 发布到NuGet
            run: |
                 dotnet nuget push NugetPublish/Release/Nancy.FixQueryDictionary.1.1.3.nupkg --api-key ${{secrets.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json --skip-duplicate

    第十段,用一个echo来输出任务的状态,查看任务是否完成。

    - run: echo "此作业的状态为${{job.status}}" 

     至此,我们已经对yml有了大概的了解。当你在Github的Actions里直接新建工作流yml文件时,右边会出现一些推荐的yml文件,你可以直接点击将其加入到你的yml。甚至,官方还有一个工作流的yml市场,你可以寻找和使用别人已经写好的各种工作流yml文件,详见https://github.com/marketplace?type=actions。工作流的文档地址https://docs.github.com/en/actions/learn-github-actions/creating-starter-workflows-for-your-organization

    开始演示

      接下来,我们把代码push到master分支,并将master合并到publish分支,以此来触发工作流的job执行。下面,我们介绍如何在Github上进行分支合并。当然,你也可以选择用git命令行操作或者用VS自带的管理分支功能进行合并,我比较喜欢这种图形化的操作,不容易出错。在Github上进行分支合并,我也是第一次操作,以下操作基于个人的理解和实践总结。

    首先,找到你的仓库中的Pull requests,点击New pull request。

     base选择publish,compare选择master。意思就是将master分支合并到publish分支,如果你是publish合并到master,则选择是相反,你懂得!如果版本之间无代码冲突的话,会显示Able to merge。正常情况来说,这里不会有冲突。因为我们修改的是master,然后合并到publish,不会单独修改publish,自然不会冲突。如果出现冲突,自然是需要处理好冲突文件的,有时间我来试一下github的冲突解决应该怎么操作。

     接下来,点击Create pull request,填写一下合并原因,变动内容,再次点击Create pull request,即可完成分支合并提交。

     

     这里,我有个疑问:实际上到此,我们的代码已经合并推送到publish分支了,为什么这里还需要再次确认合并,有点多此一举啊?知道的麻烦告诉我一声,谢谢!

     这时候,你打开Actions,会发现工作流已经准备启动了,有个黄色的点点标记了我们最新的一次提交。

    点进去,可以发现工作流已经处于loading状态,点击Explore-GitHub-Actions,可以查看到工作流job每一步的执行过程。

     我们可以看见工作流job已经都执行完成了,nuget package也已经成功推送到了github源和nuget.org源。

     我们打开nuget package的主页,点击Versions,可以发现最新的版本1.1.3已经推送过来了,处于验证状态,几分钟后就会收到nuget package发布成功的通知邮件。

     

     我们的最新版nuget package版本也已经处于正常对外发布状态了。

     最后,我们在仓库code页面,右侧找到Packages,可以发现已经显示了我们在github源上发布的nuget package。点进去,可以查看nuget package的详情。

     

     至此,我们的nuget package通过工作流job自动打包自动发布推送就完成了。可是我的疑问还是没有得到解答,为什么已经合并推送了代码,Pull requests里还有一个Merge pull request呢?让我们直接来点一下完事!

    结果呢,它又触发了工作流,job都重新来了一遍。由于推送的版本号已经存在,且push命令增加了相同版本号跳过的参数skip-duplicate,所以自动跳过了,没有报错。如果没有设置参数skip-duplicate,推送已存在的版本号工作流则会报错。

     

     写在最后

      本文主要简单介绍通过Github工作流,实现nuget package代码更新push到github仓库后的自动打包,同时推送到github源及nuget源(CI/CD),还有github的分支合并操作简单演示。对于我的疑问,欢迎大佬给予解答,在此谢过!

    本文来自博客园,作者:摇曳de风筝,转载请注明原文链接:https://www.cnblogs.com/pinzi/p/15743145.html

  • 相关阅读:
    java spring boot- freemarker 配置 yml使用流程
    layer 漂亮的弹窗
    react-native 打包apk 更新js和常见问题
    mysql 运行中 偶尔 报错 2002 也许是这个问题,内存不足导致的
    关于rsa公钥格式的处理,一行纯内容进行换行格式化
    第十篇、让UIScrollView的滚动条常显
    第九篇、自定义底部UITabBar
    第八篇、封装NSURLSession网络请求框架
    第二篇、Swift_自定义 tabbar 的 badgeValue显示样式
    第七篇、OC_图片的裁剪基于SDWebImage
  • 原文地址:https://www.cnblogs.com/pinzi/p/15743145.html
Copyright © 2020-2023  润新知