C#でGitLabを操作するライブラリGitLabApiClientを使ってみた

# はじめに

本記事では、C#でGitLabを操作するGitLabApiClientを使ってGitLab上のプロジェクト、ブランチ、フォルダ、ファイル等を取得する方法をまとめました。
GitLabApiClientのリポジトリは[こちら](https://github.com/nmklotas/GitLabApiClient)。


# 事前準備

GitLabApiClientをNugetからプロジェクトにインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562946/49fffbd4-498e-87e4-6a41-a94b50cea9bd.png)

個人用アクセストークンが必要ですので、[こちら](https://www.gitlab.jp/blog/2021/12/06/access-token/#%E3%83%91%E3%83%BC%E3%82%BD%E3%83%8A%E3%83%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B,-GitLab%E3%81%AE%E3%83%88%E3%83%83%E3%83%97)を参考にして、トークンを取得しておいてください。
```read_api```権限で様々な情報の取得は行えました。
個人用アクセストークンの他にプロジェクトアクセストークンなどもあります。個人用アクセストークンはその個人が参照できるすべてのプロジェクトに対してアクセスできますが、プロジェクトアクセストークンはそのプロジェクトだけにアクセスを制限できます。
他にもトークンの種類がありますので、用途に応じて使い分けが必要です。
今回は個人用アクセストークンを使用します。

# アクセスと認証

GitLabにアクセスするには、GitLabApiClientライブラリの`GitLabClient`オブジェクトを作成する必要があります。
このクライアントから、プロジェクト、ブランチ、フォルダ、ファイルへアクセスができます。

```cs

// コンストラクタの第1引数にはアクセスしたいGitLabのサーバー名、第2引数にはアクセストークンを指定します
var client = new GitLabClient("https://gitlab.example.com", "XXXXXXXXXX");

// ユーザー名とパスワードでもオブジェクトを作成できる
// ただし、2FA認証を有効にしていたり、SNS認証でパスワードなしにしていたりすると、パスワードでのログインができないため、アクセストークンが必要
var client =  new GitLabClient("https://gitlab.example.com");
await client.LoginAsync("username", "password");

```

# データの取得

プロジェクト、ブランチ、フォルダ、ファイルへのアクセス方法をスニペットで説明します。

## プロジェクトの取得

GitLabClient.ProjectClientを使用します。
スニペットに出てくるプロジェクトIDは、GitLabでプロジェクト画面を開いたときの、プロジェクト名のすぐ下に記載されています


```cs
// クライアントを取得
var client = new GitLabClient("https://gitlab.example.com", "XXXXXXXXXX");

// アクセス対象プロジェクトを取得

// サーバーのプロジェクトすべて取得
var projects = await client.Projects.GetAsync();

// オプションで、プロジェクト名でフィルタすれば、そのプロジェクトを取得できる
var filterdProjects = await client.Projects.GetAsync(options =>
{
    options.Filter = "extension-development-tutorial";
});

// プロジェクトに表示されているIDでも取得できる
var targetProject = await client.Projects.GetAsync(251);
```

## ブランチの取得

GitLabClient.BranchClientを使用します。スニペットは上記からの続きになります。

```cs
// デフォルトブランチを取得
var defaultBranche = targetProject.DefaultBranch;

// Branchのクエリに何も設定しないと、すべてのブランチを取得できる
var branches = await client.Branches.GetAsync(targetProject, options => { });

// Searchオプションにブランチ名を指定すると、指定した文字列を含むブランチ名のブランチを取得できる
var searchedBranches = await client.Branches.GetAsync(targetProject, options => 
{
    options.Search = "XXXXX";
});
```

## ファイルの取得

GitLabClient.FileClientを使用します。スニペットは上記からの続きになります。

```cs
// プロジェクトのデフォルトブランチの指定パスのファイルを取得。
// 第2引数には、ファイルのパスが入る
var file = await client.Files.GetAsync(targetProject, "docs/XXXXXX.md");

// プロジェクトのデフォルトブランチ以外のブランチのファイルを取得
// 第3引数でブランチを指定する
var subBranchFile = await client.Files.GetAsync(targetProject,
    "src/XXXXXX.cs", "main_/feature/XXXXX");

// あるコミット時点のファイルを取得
// 第3引数にコミットハッシュを指定する
var commitFile = await client.Files.GetAsync(targetProject,
    "docs/XXXXXX.md", "d88d42d332e999dd3eff7d423cc802bb192c44d1");

// ------------ファイルをローカルに取得する--------------

// 文字列をバイト配列に変換
// File.Contentプロパティにはバイナリデータをbase-64でエンコードした文字列が入っています
var fileContent = Convert.FromBase64String(file.Content);

// 保存する
// テンポラリフォルダに保存しています
var saveFilePath = Path.Combine(Path.GetTempPath(), @"{保存先のパス}");
File.WriteAllBytes(saveFilePath, fileContent);
```

## フォルダ・ファイルツリーの取得

GitLabClient.TreeClientを利用します。スニペットは上記からの続きになります。

```cs

// 指定したプロジェクト直下のフォルダおよびファイルのメタデータを取得できる
var trees = await client.Trees.GetAsync(targetProject);
var firstTree = trees.FirstOrDefault();

// メタデータとして、ファイルあるいはフォルダであるか(Type)、そのファイルまたはフォルダまでのパス(Path)などが取得できる
// フォルダの場合はTypeに文字列で"tree"が設定されている
// ファイルの場合はTypeに文字列で"blob"が設定されている
if (tree.Type == "tree") 
{
    // オプションでPathを指定することで、そのパス直下のファイル・フォルダを取得できる
    // オプションでReferenceを指定すると、ブランチも指定できる 
    var childTrees= await client.Trees.GetAsync(project, options => 
    {
        options.Path = tree.Path;
        options.Reference = "ブランチ名";
    });
}

```

# さいごに

GitLabからもGitHubやSubversionと同様にC#で様々な情報が簡単に取得できることがわかりました。
GitLabを利用したい場合はぜひ参考にしてください。