【AWS】S3を利用した Git LFS サーバを作成する【cli版】

# S3をLFSサーバにしてCodeCommitでGitLFSを使えるようにする

## 目標

- gitlfsの基本を学ぶ

- [Amazon S3 に Git LFS サーバを超簡単に立てる](https://qiita.com/kanemu/items/d66bfd174a011d8dffdf)のcli版を作る

## 環境

- AWSアカウント所有済み
- IAMを自由に操れる権限を持っている

## 手順

### AWS-CLI の設定

- codecommit の権限があるIAMユーザのクレデンシャルを登録する

```
$ aws configure
```

- 認証情報ヘルパーを設定する

```
$ git config --global credential.helper '!aws codecommit credential-helper $@'
$ git config --global credential.UseHttpPath true

$ cat .gitconfig 
...
[credential]
        helper = !aws codecommit credential-helper $@
        UseHttpPath = true
...
```

- 確認

```
$ aws codecommit get-repository --repository-name lfs-test
REPOSITORYMETADATA      arn:aws:codecommit:ap-northeast-1:571357558873:lfs-test 571357558873    https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/lfs-test   ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/lfs-test     2021-08-03T12:56:22.920000+00:00        2021-08-03T12:56:22.920000+00:00        700b35cc-9dcd-4f5a-909d-6b3fbca448ab    lfs-test

$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/lfs-test
Cloning into 'lfs-test'...
warning: You appear to have cloned an empty repository.

$ ls
lfs-test
```

### lfsサーバ構築用のファイルを保存するS3バケット作成

```
$ aws s3 mb s3://gitlfs-test --region ap-northeast-1
make_bucket: gitlfs-test

$ aws s3 ls
2021-08-03 13:42:11 gitlfs-test
```

- 準備

バケットにyamlファイルとZipファイルを入れておく
git-lfs.yamlのオブジェクトURLをコピーしておく

### Cloud Formation を構成する

#### jsonファイル作成

パラメータで指定するユーザ名とパスワードを記載したJSONを用意しておく

```json:params.json
[
    {
        "ParameterKey": "GitLfsUsername",
        "ParameterValue": "[ユーザ名を入れる]"
    },
    {
        "ParameterKey": "GitLfsPassword",
        "ParameterValue": "[パスワードを入れる]"
    }
]
```

#### コマンド

```
$ aws cloudformation create-stack --stack-name gitlfs-server \
--template-url 'https://yamlを保管しているS3バケットのURL/git-lfs.yaml' \
--parameters file://[path/to/params.json] \
--capabilities CAPABILITY_IAM
```

- 各パラメータについて
  - --stack-name : スタック名を指定(任意)
  - --template-url : スタック作成のためのyamlファイル(さっきメモしておいたURL)
  - --parameters : gitlfsuser と password を指定する必要がある。 今回はjsonファイルを別で作成してそれを指定
  - --capabilities : スタック作成時にIAMによってアカウントに変更が加えられる可能性があることへの承認
  - CAPABILITY_IAM : --capabilities の 値

- コマンドを実行するユーザは以下の権限が必要
  - API Gateway
  - IAM
  - Lambda
  - S3
  - CloudFormation

- 確認コマンド

```
$ aws cloudformation describe-stacks --stack-name gitlfs-server
STACKS  2021-08-03T14:28:58.312000+00:00        False   False   arn:aws:cloudformation:**********************    gitlfs-server   CREATE_COMPLETE
CAPABILITIES    CAPABILITY_IAM
DRIFTINFORMATION        NOT_CHECKED
OUTPUTS The Git LFS endpoint to use     LfsEndpoint     https://**********************.ap-northeast-1.amazonaws.com/lfs
PARAMETERS      GitLfsUsername  ********
PARAMETERS      GitLfsPassword  ********
```
CREATE_COMPLETEになってたらOK
LfsEndpointの値をコピーする

### LFS設定

#### .lfsconfig作成

さっきコピーしたエンドポイントを設定する
git clone の時に自動的にLFSを使ってくれるようになるらしい
    →git clone にはLFSサーバを指定するオプションがないため
    (参考):[Unity のプロジェクトで Git LFS を使い始めた記録](https://chiepomme.gitbook.io/chiepomme/tips/other/unity-git-lfs)

```
$ vi .lfsconfig
[lfs]
    url = https://**********************.execute-api.ap-northeast-1.amazonaws.com/lfs
```
リポジトリルートで作成

#### 初期化

- git lfsを利用できるように初期化する

```
$ git lfs install
Updated git hooks.
Git LFS initialized.
```
hookスクリプトとかが追加される

#### トラック対象追加

```
$ git lfs track "*.jpg"
$ git lfs track "*.JPG"
$ git lfs track "*.jar"
...

$ cat .gitattributes
*.jpg filter=lfs diff=lfs merge=lfs -text
*.JPG filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
```
jpg と JPG は区別されちゃうので、両方登録する

#### .gitattributes push

.gitattributesを add,commit,push しておく

```
$ git add .gitattributes
$ git commit -m ".gitattributes"
$ git push
```

### 確認

#### ファイル追加

今回はローカルリポジトリに画像ファイルとjarファイルを用意してみた

```
$ tree
.
└── binaries
    ├── jar
    │   ├── optifabric-1.11.9.jar
    │   └── preview_OptiFine_1.17_HD_U_G9_pre26.jar
    └── photos
        ├── Z6_188.JPG
        ├── Z6_20.JPG
        ├── Z6_24.JPG
        ├── Z6_30.JPG
        ├── Z6_33.JPG
        ├── Z6_71.JPG
        └── Z6_74.JPG
```

#### コミット＆プッシュしてみる

```sh
$ git status
$ git add .
$ git commit -m "Add binary files"

$ git push
Uploading LFS objects:   0% (0/1), 0 B | 0 B/s # ←LFSと認識してpushしている！
```

#### リポジトリ確認

AWSコンソールにて、CodeCommit、S3をそれぞれ確認する

- CodeCommit

リポジトリのファイルを見てみると

```
version https://git-lfs.github.com/spec/v1
~~
size 15245006
```
みたいな情報が保存されている

- S3

ハッシュ化された名前だが、実際のサイズが元ファイルと同じもの(=実体)が保存されている

## 完了

GitLFSの基本と、LFSサーバをS3に作成する方法を同時に学べた
lambdaで利用している関数の.NETcore2.1がサポート切れる(2021/09/20)らしいので、
次はこれを.NETcore3.1にアップデートしてみる
 →[できた](https://qiita.com/c0ba1t_coke/items/1f5b7b14f39884008a18)

## おまけ

gitlfsの基本を全く知らなかったので、
「[Git LFS をちょっと詳しく](https://qiita.com/ikmski/items/5cc8b8832336b8d85429)」を参考にさせていただいたけど、
なにも指定せず`$ git lfs`を実行すると最後に使い方が出てきた(;^_^A

```
$ git lfs

...

Examples
--------

To get started with Git LFS, the following commands can be used.

 1. Setup Git LFS on your system. You only have to do this once per
    repository per machine:

        git lfs install

 2. Choose the type of files you want to track, for examples all ISO
    images, with git lfs track:

        git lfs track "*.iso"

 3. The above stores this information in gitattributes(5) files, so
    that file need to be added to the repository:

        git add .gitattributes

 4. Commit, push and work with the files normally:

        git add file.iso
        git commit -m "Add disk image"
        git push
```