zoukankan      html  css  js  c++  java
  • 【NuGet】使用NuGet打包并发布至ProGet过程 (步骤详细,附python脚本)【上篇】

    一、基本知识

    (1)NuGet :

          NuGet是一个为大家所熟知的Visual Studio扩展,通过这个扩展,开发人员可以非常方便地在Visual Studio中安装或更新项目中所需要的第三方组件,同时也可以通过NuGet来安装一些Visual Studio的插件等。作为一名开发人员,您可能也会开发一些公共组件以供他人使用,本文将一步步介绍如何以最简单的方式将自己所开发的类库包发布到nuget上,以供更多的人使用[1]

    (2)ProGet:

           非常优秀的库创建服务器,用于放置packages。支持nuget命令行上传。其下载方式已经不用像站长大人[2]那么繁琐了,本身已自带推荐安装方式,一步一步去安装即可。安装完:

          首次登陆的默认用户名与密码都为:Admin

    二、NuGet.exe生成包包并上传至ProGet步骤[1,3]
    (1) 获取APIKey

              去NuGet官网上注册一个新的账号,然后在My Account页面,获取一个API Key。 别忘了这个Apikey不然以后很麻烦的[4]

              作用详解:因为包包需要发布并共享,NuGet.exe专门提供了一条发布命令。在发布之前,需要在NuGet上创建一个账号,然后得到ApiKey。在库上载包包之前,该命令将验证库的API密钥。

    (2) 下载NuGet.exe

              NuGet.exe为NuGet专用的命令行工具,去官网下载,官网首页的下载包并一定适合你,最好在Download中选择相应版本。下载完后还必须将其放在环境变量中。方法:右键“计算机”,“属性”,“高级属性设置”,“高级”中的“环境变量" , ”Path“,”编辑“,将NuGet.exe的路径放进去。

    (3) 用命令行设置ApiKey:

             nuget setApiKey 你的key值,使其存储在安全的位置。

    (4) 准备好自己的类库项目

             程序包大多数情况下仅包含一个程序集。这里主要针对.csproj或者.vbproj文件创建程序包。

             务必打开AssemblyInfo.cs文件以更新程序集的元数据。

             在AssemblyInfo.cs文件中填写好相应的信息,主要注意四个(信息全填上当然更好,后面修改nuspec文件还方便点儿):

             [assembly:Description("XXXX")]

             [assembly:ComVisible(false)]

             [assembly:Guid("XXXXXX")]

             [assembly:AssemblyVersion("X.X.X.X")]         

            

    (5) 产生与修改nuspec文件

             nuspec是程序包清单文件,包含与程序包有关的重要元数据,例如:Id,版本,标题,作者,licenseUrL,projectUrl,描述,版权等等,此类信息大多数来自AssemblyInfo.cs。nuspec可以通过nuget spec命令产生。在命令提示符下,进入TestForm.csproj文件所在目录,然后执行:

               nuget spec    

            注意:我在TestForm.csproj中添加了依赖项Castle.Core,但是清单文件不会显示这个依赖项,只有打成nupkg才会显示出来。nuspec的作用只是元数据清单显示。

    (6) 修改产生的nuspec文件

              用记事本打开TestForm.nuspec文件,把需要替换的信息替换掉,不需要的tag全部删掉,注意里面的$xxx$宏,这些就是引用了AssemblyInfo.cs中的设置值,在编译产生package的时候,会使用AssemblyInfo.cs中的相应值进行替换。

             注意:1. <tags>标签不能为默认

                       2. <description>标签不能为默认

                       3. <releaseNotes>标签不能为默认

    (7) 在TestForm.csproj路径下使用命令行nuget pack 进行打包。

              基本命令:nuget pack TestForm.csproj

              NuGet会使用默认的项目配置所产生的程序集进行打包。如果项目默认是Debug,而你需要用Release打包,则使用下面的命令:

            Nuget pack TestForm.csproj -Prop Configuration=Release

            注意:1.如果同一个目录中只有一个项目文件,则在运行命令时可以省略项目文件名称。

                    2.如果是尚未编译项目,可先用Build标记编译项目,然后压缩它。这将在运行pack命令之前编译项目:nuget pack TestForm.csproj -Build

     

            Nupkg包究竟包含哪些文件:

                    1. libs文件,里面包含生成的dll或者exe文件

                    2. .rels文件

                    3. Content_type.xml文件

                    4. nuspec清单文件

                    5. package文件夹,主要包含core-properties

                    6. 其他

            

            如果项目中含有依赖,生成的nupkg也会显示出来:

            

            

    (8) 发布自己的包包到ProGet

            包包打包完就可以上传至ProGet了[5]

            命令行: nuget push "你的包包完整路径"  你的ApiKey -Source 你的ProGetURL -ApiKey 你的用户名:你的密码

           最后浏览你的ProGet:

           我们随便打开一个项目,打开NuGet安装包管理器,显示 TestForm:

        

     

    (9) 更新自己的包包到ProGet

            更新包包相对容易,只要你更改AssemblyInfo.cs中的信息,尤其是版本信息,然后重复(7)与(8)即可:

            观察ProGet:

          

    三、ProGet使用方法 

            ProGet是一个非常全面的库,该库中主要包括三项:Feed,Packages,Connector。

            Feed用于建立仓库,能建立Universal(通用库)、NuGet库、Chocolatey、Maven、npm、Bower六种库。

            1. 建立Feed时首先选择库的类型,然后命名Feed名称,然后出现配置画面,如果设置好其中的NuGet ApiKey,以后nuget push 时就不用最后加一句-APIKey Username:Password了。

            DropPath应该是个缓存路径,其原文翻译:每次会扫描该路径下的包包用以Import,如果Import成功,则会删除该路径下的所有包包。

             建立完Feed时记住它的Package Source URL:

             2. 建立Packages

            建立完Feed就可以上传你的packages了:

            3. Connectors

            Connector的作用是再连接一个包源,比如你当前的包源为A,你可以再设置一个Connector指向包源B,这样在NuGet服务器上浏览你的包源A会发现包源B的资源也在。

            4. 使用NuGet安装包管理器下载包包

            包包上传完之后,我们需要连接到该ProGet库用以共享包包,在NuGet包管理器—>程序包管理器设置—>添加一个库,就是点“+”,输入名称和源即可,点击确定即可。

          5. 使用包包:

          NuGet包管理器—>管理解决方案的NuGet程序包—>联机,找到你定义的名称即可:

     

    四、融入Jenkins(python脚本) 

           流程图:

     

           python脚本代码:

    # coding=gbk
    import os
    import sys
    import re
    
    def getdisc(projectpath):                   #获得项目文件的当前盘
        disc = projectpath.split(':',1)[0]
        disc = disc+":"
        return disc
    
    def getAssemblyVersion(projectpath):       #根据Assembly获取版本号
        assemblyInfoFile = projectpath+"/Properties/AssemblyInfo.cs"
        lines= open(assemblyInfoFile,'r+',encoding='iso-8859-15').readlines()
        flen=len(lines)-1
        for i in range(flen):
             if lines[i].startswith("[assembly: AssemblyVersion"):
                versioncode = lines[i].split('"',2)[1]
                break
        return versioncode
    
    def modifynuspec(projectfilepath,projectname):   #修改nuspec文件内容
        li = os.listdir(projectfilepath)
        for filename in li:
          if filename.endswith(".nuspec"):
             nuspecfile = filename.replace(".nuspec",".xml")      #nuspec->xml
             nuspecfile = projectfilepath+"/"+nuspecfile
             filename = projectfilepath+"/"+filename
             os.rename(filename,nuspecfile)
             break
    count=0 for filecsproj in li: if filecsproj.endswith(".csproj"): count+=1 if count==1: tfile = projectfilepath+"/"+projectname+".xml" else: tfile = projectfilepath+"/"+"Package.xml" f = open(tfile,'r') xmldata = f.read() xmldata = re.sub('<description>(.*?)</description>','<description>'+projectname+'</description>',xmldata) xmldata = re.sub('<tags>(.*?)</tags>','',xmldata) xmldata = re.sub('<releaseNotes>(.*?)</releaseNotes>','',xmldata) f.close() f = open(tfile,'w') f.write(xmldata) f.close() li = os.listdir(projectfilepath) for filename in li: if filename.endswith("Package.xml") or filename.endswith(''+projectname+'.xml'): nuspecfile = filename.replace(".xml",".nuspec") #xml->nuspec nuspecfile = projectfilepath+"/"+nuspecfile filename = projectfilepath+"/"+filename os.rename(filename,nuspecfile) break return if __name__ == '__main__': if len(sys.argv)!=8: sys.exit(-1) NuGetpath = sys.argv[1] Projectfilepath = sys.argv[2] Projectname = sys.argv[3] ProGetSourceUrl = sys.argv[4] ProGetAdmin =sys.argv[5] ProGetPassword =sys.argv[6] myApikey =sys.argv[7] NuGetdisc = getdisc(NuGetpath) ProjectDisc = getdisc(Projectfilepath) Projectnuspec =Projectfilepath+"/"+Projectname+".nuspec" if not os.path.exists(Projectnuspec): os.system(''+NuGetdisc+'&&cd '+NuGetpath+'&&nuget setApiKey '+myApikey+'') os.system(''+ProjectDisc+'&&cd '+Projectfilepath+'&&nuget spec') modifynuspec(Projectfilepath,Projectname) Projectnamecsproj = Projectname+".csproj" os.system(''+ProjectDisc+'&&cd '+Projectfilepath+'&&nuget pack '+Projectnamecsproj+'') ConvertProjectfilepath = Projectfilepath.replace("/","\") Nupkgpath = ConvertProjectfilepath+"\"+Projectname+"."+getAssemblyVersion(Projectfilepath)+".nupkg" os.system(''+NuGetdisc+'&&cd '+NuGetpath+'&&nuget push '+Nupkgpath+' '+myApikey+' -Source '+ProGetSourceUrl+' -ApiKey '+ProGetAdmin+':'+ProGetPassword+'')

    注意:如果项目路径下有多个.csproj文件,那么进行nuget spec操作会产生一个名为Package.nuspec的nuspec文件,而不是<项目名.nuspec>文件,千万注意这点。

     

    后记:

    刚参加工作一月多,之前一直都是写的C#代码。组长让我写脚本去完成公司内项目文件的打包工作,一开始什么都不知道,虽然平时用P4V和Git,可是发现自己并不了解分布式控制的内涵,经过一星期组长对我的洗脑,摆正了许多错误的概念。那个星期我觉得我就是个智障,什么都听不懂,有时候好像懂了,可是和组长讨论后又发现是错了。还好,现在总算是明白了。根据组长对我的教育,我画了个流程图并自己开始写代码。

    这篇博文的前部分参考了Reference的前三篇文章,他们的文章对我有很多的帮助,在他们的基础上我进一步详细说明了下。希望这篇博文对大家有帮助,欢迎留言讨论。最后,感谢已经被我整奔溃的组长。

     

    References:

    [1] http://www.cnblogs.com/daxnet/archive/2013/05/07/3064577.html

    [2] http://www.cnblogs.com/dudu/p/5147284.html

    [3] http://blog.csdn.net/dandanzmc/article/details/42012429#comments

    [4] https://www.nuget.org/

    [5] http://inedo.com/proget

     

    作者:airforce094

    出处:http://www.cnblogs.com/lovecsharp094/p/5527204.html

    转载请注明原文出处 , 谢谢合作

     

     

  • 相关阅读:
    C/C++定义全局变量/常量几种方法的区别
    可变参数宏__VA_ARGS__
    mysql 命令重命名表RENAME TABLE 句法
    贝尔实验室的历史
    SVN代码回滚
    linux下查看进程占用端口和端口占用进程命令
    php操作mongodb中的ISODate格式日期
    Vim多行缩进技巧
    关于XCode工程中PrefixHead.pch文件的使用
    Object C函数指针@selector
  • 原文地址:https://www.cnblogs.com/lovecsharp094/p/5527204.html
Copyright © 2011-2022 走看看