Net Core-Nuget包私有管理

最近需要在平台中搭建属于自己的Nuget包管理功能,对Nuget包做统一的管控,利于在内网环境下拉取Nuget包,提升CICD速度。

查了些资料,从开源项目Baget入手。Baget源码地址:https://github.com/loic-sharma/BaGet,能够搭建私有的Nuget服务器,对Nuget包上传,下载,安装进行管理,以及支持dotnet cli命令。

1.运行Baget

打开Baget项目,文档结构如下:

 

 设置Baget为启动项

启动成功后,即可上传Nuget包:

通过命令行上传:

dotnet nuget push -s http://localhost:50561/v3/index.json mailkit.3.1.1.nupkg

其中50561是项目端口号,mailkit.3.1.1.nupkg是上传的Nuget包名

推送成功:

2.分析和整合

A.源服务索引

上传Nuget不是我们这次的重点,需要研究如何配置Nuget包源,常见的是index.json和指定文件夹目录的形式。

先来配置Baget对应的索引信息,在Nuget包管理中添加如下:

 

刷新后,加载出Baget管理的Nuget包详情列表:

 

 

为什么会这么配置呢?读取的index.json是什么文件?

浏览器访问:http://localhost:50561/v3/index.json

结果如下:

{
    "version": "3.0.0",
    "resources": [
        {
            "@id": "http://localhost:50561/api/v2/package",
            "@type": "PackagePublish/2.0.0"
        },
        {
            "@id": "http://localhost:50561/api/v2/symbol",
            "@type": "SymbolPackagePublish/4.9.0"
        },
        {
            "@id": "http://localhost:50561/v3/search",
            "@type": "SearchQueryService"
        },
        {
            "@id": "http://localhost:50561/v3/search",
            "@type": "SearchQueryService/3.0.0-beta"
        },
        {
            "@id": "http://localhost:50561/v3/search",
            "@type": "SearchQueryService/3.0.0-rc"
        },
        {
            "@id": "http://localhost:50561/v3/registration",
            "@type": "RegistrationsBaseUrl"
        },
        {
            "@id": "http://localhost:50561/v3/registration",
            "@type": "RegistrationsBaseUrl/3.0.0-rc"
        },
        {
            "@id": "http://localhost:50561/v3/registration",
            "@type": "RegistrationsBaseUrl/3.0.0-beta"
        },
        {
            "@id": "http://localhost:50561/v3/package",
            "@type": "PackageBaseAddress/3.0.0"
        },
        {
            "@id": "http://localhost:50561/v3/autocomplete",
            "@type": "SearchAutocompleteService"
        },
        {
            "@id": "http://localhost:50561/v3/autocomplete",
            "@type": "SearchAutocompleteService/3.0.0-rc"
        },
        {
            "@id": "http://localhost:50561/v3/autocomplete",
            "@type": "SearchAutocompleteService/3.0.0-beta"
        }
    ]
}

分析:Json的内容比较像注册的路由。

把Baget的v3/index.json的路由改成v3/index1.json试试,结果如下:

分析:说明Baget提供了/v3/index.json的get请求接口,给Nuget包管理器读取配置信息

通过网络抓包,验证了该猜测

那么举一反三,通过命令行上传包信息,也是http请求:

上传时通过/api/v2/package路由对应的接口

所以我们要做的就是实现对应路由的接口里的逻辑

B.Api项目创建

创建WabApi项目NugetMangeApi,基于.Net Core 3.1。

在WeatherForecastController,添加如下代码:

[HttpGet("/v3/index.json")]
        public async Task<ServiceIndexResponse> GetIndex()
        {
            var resources = new List<ServiceIndexItem>();

            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/api/v2/package",
                Type = "PackagePublish/2.0.0"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/api/v2/symbol",
                Type = "SymbolPackagePublish/4.9.0"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/search",
                Type = "SearchQueryService/3.0.0-beta"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/search",
                Type = "SearchQueryService/3.0.0-rc"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/registration",
                Type = "RegistrationsBaseUrl"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/registration",
                Type = "RegistrationsBaseUrl/3.0.0-rc"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/registration",
                Type = "RegistrationsBaseUrl/3.0.0-beta"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/package",
                Type = "PackageBaseAddress/3.0.0"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/autocomplete",
                Type = "SearchAutocompleteService"
            });

            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/autocomplete",
                Type = "SearchAutocompleteService/3.0.0-rc"
            });
            resources.Add(new ServiceIndexItem()
            {
                ResourceUrl = "http://localhost:5192/v3/autocomplete",
                Type = "SearchAutocompleteService/3.0.0-beta"
            });

            var result = new ServiceIndexResponse
            {
                Version = "3.0.0",
                Resources = resources,
            };

            return await Task.FromResult(result);
        }

修改启动配置文件,使其端口为5192

在Nuget包管理器中添加我们的配置"MyNuget"

B.Nuget包查询列表

配置完成后,刷新,出现如下异常:

分析:还需要配置/v3/search对应的路由

在Api项目中实现,并添加一条假数据,代码如下:

 [HttpGet("/v3/search")]
        public async Task<ActionResult<SearchResponse>> SearchAsync(

          [FromQuery] string q,
           [FromQuery] string semVerLevel,
           [FromQuery] string packageType,
           [FromQuery] string framework,
          int skip = 0,
         int take = 20,
         bool prerelease = false,
           CancellationToken cancellationToken = default)
        {
            List<SearchResultVersion> versiolist = new List<SearchResultVersion>();
            SearchResultVersion version = new SearchResultVersion();
            version.RegistrationLeafUrl = "http://localhost:50561/v3/registration/mailkit/3.1.1.json";
            version.Version = "3.1.1";
            version.Downloads = 1;
            versiolist.Add(version);

            SearchResponse searchResponse = new SearchResponse();
            searchResponse.Context = new SearchContext();
            searchResponse.Context.Vocab = "http://schema.nuget.org/schema#";
            searchResponse.Context.Base = "http://localhost:50561/v3/registration";
            searchResponse.TotalHits = 1;
            searchResponse.Data = new List<SearchResult>();
            searchResponse.Data.Add(new SearchResult()
            {
                PackageId = "MailKit",
                Version = "3.1.1",
                Description = "",
                Authors = new List<string>() { "Jeffrey Stedfast" },
                Title = "MailKit",
                Versions = versiolist
            });
            return await Task.FromResult(searchResponse);
        }

刷新Nuget包源,结果如下,可以看到我们发布的Nuget包

终于成功了!!

由此可以发现Baget配置的路由,对应了实际Nuget包管理器的路由请求,也就是我们/v3/index.json里配置的路由。

 

然而,在Baget里是如何配置路由和实现的呢?

通过搜寻源码,在Baget包里找到对应的路由配置:

在"BaGetEndpointBuilder.cs"中发现了Baget的相关配置,涉及到安装,卸载等操作的路由。

 

总结一下:

Baget用了Web作为页面UI展示

类库BaGet中封装了Nuget包管理器对应的操作路由,

类库Baget.Web中对路由进行接收和实现,

Baget.Core中封装了对NugetPackage包读取的操作,核心是封装了Nuget.Version和Nuget.Protocol

 

以上,仅用于学习和总结!

posted @ 2022-03-27 13:58  y_w_k  阅读(258)  评论(0编辑  收藏  举报