使你的ASP.Net Core项目支持git


Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383

Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383

你有时候是否想过,自己开发一套类似Gitea的项目?或者是自己项目加入Git服务端功能,来做一些自动化文件同步之类的操作?现在你有了一个选择,GitServerCore。

地址:https://github.com/fawdlstty/GitServerCore

GitServerCore是一个.NET Core开发的服务端中间件,可以非常便捷的在你的项目中加入git服务端功能,然后就能在远程电脑上随心所欲的git clone、git push。基于这个功能,你能轻松实现:

  • 一个基于.Net Core的Gitea或GitLab
  • 自动化文件同步
  • 自动化CI/CD插件

下面来一起试试吧。第一步,服务部署机与远程客户端机分别装上git,不限系统环境,打开命令行敲git能执行命令就行。如果在本地部署本地测试,那么装一个就可以了。

第二步,新建WebAPI项目,版本选.Net Core 3.1,并在nuget上面引用最新版本的Fawdlstty.GitServerCore

第三步,Configure加入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public void ConfigureServices (IServiceCollection services) {
    // ...
    services.AddGitServerCore (_cfg => {
        // URL匹配正则(比如:/username/reponame.git)
        _cfg.GitUrlRegex = "^/(\\S*)\\.git$";
 
        // URL地址如何转为仓库相对路径
        //比如如上正则匹配的URL将会转为:username/reponame
        _cfg.GitUrlSimplize = _url => _url [1..^4];
 
        // git裸仓库路径
        _cfg.GitRepoBareDir = "/data/repo_bare";
 
        // git文件释放路径
        _cfg.GitRepoExtractDir = "/data/repo_extract";
 
        // 登录校验
        _cfg.CheckAllowAsync = async (_path, _oper, _username, _password) => {
            if (string.IsNullOrEmpty (_username)) {
                // 用户名为空那么强制要求输入用户名
                return GitOperReturnType.NeedAuth;
            } else if (_username == "hello" && _password == "world") {
                // 用户名和密码验证通过
                return GitOperReturnType.Allow;
            } else {
                // 拒绝此次访问
                return GitOperReturnType.Block;
            }
        };
 
        // 操作完成通知
        _cfg.HasBeenOperationAsync = async (_path, _oper, _username) => await Task.Yield ();
    });
    // ...
}
 
public void Configure (IApplicationBuilder app, IWebHostEnvironment env) {
    // ...
    app.UseGitServerCore ();
    // ...
}

这一步代码有点多,不要被吓到。其实就是加入一些配置信息。简单来解释下参数。GitUrlRegex这参数含义是,匹配URL的正则表达式。比如我们搭建好服务后,可能想让下面这个地址作为一个仓库地址:

http://127.0.0.1/user_zhangsan/repo_testrepo.git

当然,格式可能不止这么简单,可能没有.git后缀,可能前面加一些奇奇怪怪的路径,这些都能支持,前提是你写个正则匹配到这个路径。比如上面这个仓库地址,我们需要匹配的地址为:/user_zhangsan/repo_testrepo.git

相应,正则表达式为:^/(\S*)\.git$

正则匹配到了路径,然后呢?找第二个参数,GitUrlSimplize,这个是传入一个函数,将匹配地址转为仓库相对路径,比如此处需要这么转:

/user_zhangsan/repo_testrepo.git -> user_zhangsan/repo_testrepo

看起来就像是去掉行首一个字符与行末四个字符,那么转换函数就写上:

_url => _url [1..^4]

注意,后者这个是仓库相对路径,同时也是回调函数里你需要判断的标识符,格式是文件夹相对路径格式,不限反斜线数量,写二十个或者不写,也就是只有一级相对路径,都没关系,全看需求。示例取值:“myrepo”、“zhangsan/repo”、“zhangsan/repo1/hello”、“a/b/c/d/e/f/g”

其他的几个参数比较简单了,按照上面的说明即可。

第四步,新建控制器,示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[ApiController]
[Route ("[controller]/[action]")]
public class MyGitCommandController: ControllerBase {
    // http://127.0.0.1:5000/MyGitCommand/Create?path=aaa/bbb
    [HttpGet]
    public string Create (string path) {
        if (GitServerAPI.CreateRepo (path)) {
            return "success";
        } else {
            return "failure";
        }
    }
 
    [HttpGet]
    public async Task<string> Extract (string path) {
        if (await GitServerAPI.ExtractFilesAsync (path)) {
            return "success";
        } else {
            return "failure";
        }
    }
}

第五步,启动服务,浏览器访问这个

http://127.0.0.1:5000/MyGitCommand/Create?path=user_zhangsan/repo_testrepo

地址、端口按照服务部署的来,后面这个路径就是相对路径,访问之后,会提示success,意思就是裸仓库创建成功。裸仓库的意思是,专为远程来服务的仓库。此时你就能开始自在的克隆提交了。执行命令:

git clone http://127.0.0.1:5000/user_zhangsan/repo_testrepo.git

提示需要输入用户名和密码,此处就是我们上面,登录校验填的参数了。如果你希望克隆操作不需验证,那么在CheckAllowAsync函数这儿,判断一下是否是克隆类型,是就直接通过。

上面我为了简单,没有查库,示例用户名和密码分别是“hello”、“world”,直接填上,顺利克隆。然后我们克隆下来后改改代码,提交,ok,一个完整的流程,实现。

说完了这个项目,说说这个项目的由来。由来是:

https://github.com/linezero/GitServer

这个项目原本是计划对标一个基于.Net Core的Gitea或GitLab,基本功能实现了,但易用性上还达不到主流的水准。另外因为项目耦合太紧,假如想单独实现Git服务端,用这项目就麻烦了。所以我就想着把这样的一个项目的Git服务端功能单独拧出来,最麻烦的地方用一个中间件来实现,后面如果有谁想要使用git服务端功能,也能单独使用此库基础上来开发。

发布者

fawdlstty

又一只萌萌哒程序猿~~

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注