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

  • 2019 年 10 月 3 日
  • 筆記

.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(一個服務封裝程式),好了,趕緊蓋大樓去吧~~