GitHubにプッシュすると、CodeCommitへ自動で同期させる方法

#はじめに
GitHubにプッシュするとCodecommitへ自動的に反映させる方法をまとめました。

ミラーリングの詳細です。↓

https://github.com/pixta-dev/repository-mirroring-action

#流れ
1. IAMユーザー作成
- SSHキー作成
- ローカルのconfigの設定
- codecommitリポジトリ作成し、クローンする
- Githubでの設定
- GitHubのActionでミラーリング設定
- GitHubでアクセストークンを作成
- Githubにpushし、ミラーリングの確認

#IAMユーザー作成
下記3つのポリシーをアタッチしたIAMユーザーを作成します。

- IAMUserSSHKeys
- IAMReadOnlyAccess
- AWSCodeCommitFullAccess

#SSHキー作成
ローカルでSSHキーを作成します。

```
$ cd ~/.ssh

$ ssh-keygen -t rsa -b 4096 -m PEM -C <githubのメールアドレス>

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/user/.ssh/id_rsa): codecommit_rsa
[ Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in codecommit_rsaa.
Your public key has been saved in codecommit_rsaa.pub.
〜〜〜以下省略
```
3行目にファイル名を入力します。今回は、`codecommit_rsa`です。
4行目、5行目のパスフレーズは空で登録します。
何かしらの値を入れると`Github Actionsでエラー`になります。

SSHキーの公開鍵（codecommit_rsa.pub）と
SSHキーの秘密鍵（codecommit_rsa）が作成されました。



先程作成したIAMユーザーから、`認証情報タブ ＞ AWS CodeCommitのSSHキーにある「SSHパブリックキーのアップロード」`を選択します。

SSHキーの公開鍵（codecommit_rsa.pub）の中身をそのまま`SSH パブリックキーのアップロード`に貼り付けます。

```
$ cat codecommit_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD5DmZ/NJ/YDMq9Ux0ZHkABUFGtYyLxaR8
〜〜〜以下省略
```

![スクリーンショット 2022-01-05 22.23.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4266cdaa-7216-c303-cb26-66a63467dc92.png)

`SSHキーID`（APK....）が発行されましたが、使用しますので、コピーしてください。

#ローカルのconfigの設定

ローカルの`~/.ssh/configファイル`に以下の設定を追記します。

```config:config
Host git-codecommit.*.amazonaws.com
  User APKXXXXXXXXXXXXX
  IdentityFile ~/.ssh/codecommit_rsa
```

HOSTは、`Host git-codecommit.*.amazonaws.com`です。

Userは、IAMに公開鍵を登録した際に発行されたSSHキーID（APK....）を設定してください。


IdentityFileは、秘密鍵（codecommit_rsa）の名前です。

![スクリーンショット 2022-01-05 22.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/7b47945e-1c59-3864-5781-58d757f2f2ba.png)

#codecommitリポジトリ作成し、クローンする

CodeCommitのリポジトリを作成します。
名前は、`slot`にします。
`SSHのクローン`をクリックすると、コピーされます。


![スクリーンショット 2022-01-05 22.35.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/7729e597-073e-2164-14f1-0fcc6f20a8ed.png)

```
$ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/slot
```
これでクローンできます。（空ですが）

適当に1つファイルを作成し、ブランチ`main`と`develop`を作成しておきます。
![スクリーンショット 2022-01-05 22.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/90108314-3367-f6be-fd3f-6d93f0b94e31.png)

#GitHubでの設定

slotという名前のリポジトリを作成し、`slotリポジトリ ＞ Settings ＞ Secrets`をクリックします。
![スクリーンショット 2022-01-05 23.30.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/18e032e3-9429-db23-c22e-7ecee0827ca5.png)

`New Repository secret`をクリックし、2つ作成します。

- CODECOMMIT_SSH_PRIVATE_KEY：秘密鍵(codecommit_rsa)の中身
- CODECOMMIT_SSH_PRIVATE_KEY_ID：SSHキーID（APK....）
-　![スクリーンショット 2022-01-05 22.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/cb054a79-d6d1-517e-bbcb-ef7e659c2b6c.png)

#GitHubのActionでミラーリング設定
`Actions`タブから、`New workflow`をクリックし、`set up a workflow yourself`をクリックする。
![スクリーンショット 2022-01-05 23.01.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/bdae73a4-d05b-3011-fa6a-32d1ea6ba6cf.png)
![スクリーンショット 2022-01-05 23.00.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0221eb69-0744-d459-eb33-5ffef19dc9c5.png)

`mirroring.yml`に下記のとおりにコピペします。
ファイル名は、`main.yml`でもよいです。
今回は、②パターン用意しました。自身にあったほうをコピペしてください。


`target_repo_url`のSSHリンク箇所は、各自修正してください。

##パターン①：GitHubのすべてのブランチをCodeCommitに同期させる場合

```yml:mirroring.yml
name: Mirroring

on: [ push, delete ]

jobs:
  to_codecommit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: pixta-dev/repository-mirroring-action@v1
        with:
          target_repo_url:
            ssh://git-codecommit.~~~~（**codecommitのミラーリング先リポジトリSSHリンク）**
          ssh_private_key:
            ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY }}
          ssh_username:
            ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY_ID }}
```
![スクリーンショット 2022-01-05 23.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f80b8919-84e0-3dd7-23cc-dffca977fa3d.png)

##パターン②：GitHubの`main`と`develop`のみ、CodeCommitに同期させる場合

```yml:mirroring.yml
name: Mirroring

on:
  push:
    branches: [main, develop]

jobs:
  to_codecommit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: pixta-dev/repository-mirroring-action@v1
        with:
          target_repo_url:
            ssh://git-codecommit.~~~~（**codecommitのミラーリング先リポジトリSSHリンク）**
          ssh_private_key:
            ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY }}
          ssh_username:
            ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY_ID }}
```



修正後、`Start commit`から　`commit new file`をクリックすると、`main`ブランチにファイルが作成されます。
mainブランチにコミットするか、ブランチを新たに作成し、プルリクを出すかが選べます。

![スクリーンショット 2022-01-05 23.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/57951e82-58e6-a7fa-c57f-a21614cdc4a9.png)

ちなみに、`.github/workflows/mirroring.yml`を任意のブランチ内で作成してもミラーリングできます。

###`fetch-depth: 0`の役割
>actions/checkout@v2ではチェックアウト時の時間短縮のために指定されたブランチの先頭コミットしか取得(fetch)してきません。
fetch-depth: 0を指定してあげることにより、全タグ・全ブランチ・全履歴を取得するようになるため、次のgit checkoutが意図通り動く、という仕掛けです。

https://zenn.dev/satococoa/articles/e026c0689e5678

#GitHubでアクセストークンを作成
pushする際、アクセストークンが必要になりますが、`workflow`を加えるようにしてください。
今回は、`repo`と`workflow`を選択しました。
![スクリーンショット 2022-01-05 22.49.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/15054160-3131-349c-0802-0d75f9bb5954.png)


#Githubにpushし、ミラーリングの確認
Githubのmainブランチをローカルにクローン後、適当にプッシュし、Githubの`Actions`タブのコミットIDをクリックすると、codecommitへのミラーリングができていることが確認できます。

![スクリーンショット 2022-01-05 23.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/26429337-1c7d-bafc-3621-ef64154b3807.png)
![スクリーンショット 2022-01-05 23.16.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/b71de6e6-29db-32c9-9b9f-b19fc5d4f8a9.png)

developブランチには、`mirroring.yml`ファイルがないため、マージ等を行うことで、developもcodecommitに同期されるようになります。

#エラー①

```
remote: error: refusing to delete the current default branch 'refs/heads/master'.
```

codecommitのデフォルトブランチが`master`、
githubのデフォルトブランチが`main`だった場合に、発生します。

codecommitのデフォルトブランチを`main`にするとよいです。

#エラー②


```
remote: error: refusing to delete the current default branch 'refs/heads/main'.
```
`mirroring.yml`に`fetch-depth: 0`の記載がないためです。必ず加えましょう。

#参考

https://qiita.com/Ueken3pei/items/403f47b5e73014541a02

https://zenn.dev/itouuuuuuuuu/articles/3d9ba9cd92cc33