zoukankan      html  css  js  c++  java
  • 从一次解决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

  • 相关阅读:
    Redis源代码分析(十三)--- redis-benchmark性能測试
    kvm中运行kvm
    umount.nfs device busy day virsh extend diskSpace, attachDisk
    ultravnc
    openNebula dubug
    maintenance ShellScripts
    virsh VMI deploy data serial xml
    cloud computing platform,virtual authentication encryption
    基于C 的libvirt 接口调用
    storage theory
  • 原文地址:https://www.cnblogs.com/pinzi/p/15743145.html
Copyright © 2011-2022 走看看