1. 程式人生 > >.NET Core下操作Git,自動提交程式碼到 GitHub

.NET Core下操作Git,自動提交程式碼到 GitHub

.NET Core 3.0 預覽版釋出已經好些時日了,部落格園也已將其用於生產環境中,可見 .NET Core 日趨成熟

迴歸正題,你想蓋大樓嗎?想 GitHub 首頁一片綠嗎?今天拿她玩玩自動提交程式碼至 GitHub。

安裝專案模板

dotnet new --install "Microsoft.DotNet.Web.ProjectTemplates.3.0"
dotnet new worker

建立專案

直接使用 .NET CLI 建立一個 Work Service 的專案

dotnet new worker -o AutomaticPush

用 Visual Studio 2019 開啟專案可以看到以下程式碼

// Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}
  • 從 3.0 起 WebHost 被 Host 取代了
  • CreateHostBuilder建立 Host 並在ConfigureServices中呼叫.AddHostedService<Worker>()
// Worker.cs
public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Worker 繼承了 BackgroundService,在 override ExecuteAsync 方法中完成自動提交的程式碼

.NET 下操作 Git 需要用到一個庫 LibGit2Sharp,同時支援 .NET Framework 及 .NET Core

在專案中安裝使用

Install-Package LibGit2Sharp

LibGit2Sharp 簡單使用

  • Repository.Init(@"D:\Work") 在指定路徑建立一個新的 Git 倉庫,相當於 git init

  • Repository.Clone("https://github.com/Meowv/Blog.git", @"D:\Work") 拉取一個遠端倉庫到本地,相當於 git clone

  • using (var repo = new Repository(@"D:\Blog")){} 開啟本地存在的 Git 倉庫

  • 獲取 Branch

    using (var repo = new Repository(@"D:\Blog"))
    {
        var branches = repo.Branches;
    
        foreach (var item in branches)
        {
        }
    }
  • 獲取 Commits

    using (var repo = new Repository(@"D:\Blog"))
    {
        foreach (var commit in repo.Commits)
        {
        }
    }
  • 獲取 Tags

    using (var repo = new Repository(@"D:\Blog"))
    {
        foreach (var commit in repo.Tags)
        {
        }
    }
  • 更多操作請移步 https://github.com/libgit2/libgit2sharp

自動 Push 程式碼蓋大樓

有了以上基礎,就可以實現自動生成檔案,push 程式碼到 GitHub 了。

新建一個配置檔案,存放我們 GitHub 倉庫以及賬號密碼等重要資訊

{
  "repository": "本地git倉庫絕對路徑",
  "username": "GitHub賬號",
  "password": "GitHub密碼",
  "name": "提交人",
  "email": "郵箱"
}

在ExecuteAsync中讀取配置檔案資訊

var configurationRoot = new ConfigurationBuilder().AddJsonFile("config.json").Build();

var path = configurationRoot["repository"];
var username = configurationRoot["username"];
var password = configurationRoot["password"];
var name = configurationRoot["name"];
var email = configurationRoot["email"];

git會自動檢測檔案變化,所以就先自動按日期建立.log檔案,不斷生成內容然後提交

while (!stoppingToken.IsCancellationRequested)
{
    var fileName = $"{DateTime.Now.ToString("dd")}.log";
    var content = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

    // 寫入內容
    WriteText(path, fileName, content);

    using (var repo = new Repository(path))
    {
        // Stage the file
        Commands.Stage(repo, "*");
        // Create the committer's signature and commit
        var author = new Signature(name, email, DateTime.Now);
        var committer = author;
        // Commit to the repository
        var commit = repo.Commit(content, author, committer);
        // git push
        var options = new PushOptions
        {
            CredentialsProvider = new CredentialsHandler((url, usernameFromUrl, types) =>
            {
                return new UsernamePasswordCredentials()
                {
                    Username = username,
                    Password = password
                };
            })
        };
        repo.Network.Push(repo.Branches["master"], options);
    }

    Console.WriteLine(content);

    // 等待60秒繼續執行...
    await Task.Delay(60000, stoppingToken);
}

private static void WriteText(string path, string fileName, string content)
{
    path = Path.Combine(path, DateTime.Now.ToString(@"yyyy\\MM"));
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }
    var filePath = Path.Combine(path, fileName);
    using var fs = new FileStream(filePath, FileMode.Append);
    using var sw = new StreamWriter(fs);
    sw.WriteLine(content);
}

至此,整個程式碼編寫部分結束,專案釋出後可以選擇sc.exe註冊為Windows服務,在這裡推薦使用nssm(一個服務封裝程式),好了,趕緊蓋大樓去吧~~