AndroidStudioからGitLabにSSH接続する

# 概要
タイトル通りですが、AndroidStudioからGitLabにアクセスする方法です。
HTTPS接続は特に難しい設定はなかったのですが、SSHはそこそこ悩んだので簡単に説明します。

# SSH接続の設定

SSH接続用の鍵生成が済んでいる場合は飛ばしてください。

## 鍵の生成

まずは鍵を置く場所に移動します。
`cd ~/.ssh`

鍵生成コマンドを実行します。
`ssh-keygen -t ecdsa -b 256 -C "コメント"`

普通は「ecdsa」の部分を「rsa」、「256」を「2048」とするのが一般的ですが、
例の方が若干暗号強度が高いのと、鍵交換時にサーバの負荷が少ないということなので、
自前のサーバの場合はこちらが良さそうです。

参考：
[サーバ負荷をRSAとECDSAで比較](https://http2.try-and-test.net/ecdsa.html)


以下のように保存先を聞かれますので、適宜ファイル名を入力します。
（未入力の場合は「id_{暗号名}」という名前になります）

```
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ryo-4947123/.ssh/id_ecdsa): {ファイル名}  
```

パスフレーズの登録を求められます。
任意で入力しても良いですが、とりあえず未入力とします。
（GitHubで使用する場合は設定することを推奨します）

```  
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
``` 

無事生成できたら結果が出力されます。

``` 
Your identification has been saved in {ファイル名}.
Your public key has been saved in {ファイル名}.pub.
〜
```

## 鍵の設定

このままでは、ターミナルやAndroid Studioで鍵の確認やパスワードを求められるので、
特定URL・ユーザでアクセスした際に鍵を自動で読み込むように設定します。

リポジトリが以下の(SSHでクローン用の)URLの場合を仮定します。
`ssh://git@example.com:12345/ryo_4947123/test.git`

以下のファイルを開きます（ない場合はファイルを作成します）。
`vi ~/.ssh/config`

以下を追記します。

```
Host {識別名}
  User {ログインユーザ名}
  Port {ポート番号}
  HostName {GitLabのURL}
  Identitiesonly yes
  IdentityFile ~/.ssh/{秘密鍵のファイル名}
```

{識別名}にはFQDN（example.com)を指定します。
{ログインユーザ名}にはOSのログインユーザ名(git)を指定します。
{ポート番号}にはSSH接続のポート番号(12345)を指定します。
URLにポートの指定がない場合は「22」を指定します。
{GitLabのURL}にはFQDN（example.com）を指定します。
{秘密鍵のファイル名}には鍵の生成で作成されたファイルのうち、「.pub」が付いていない方を指定します。

**実は上記項目の一部は設定しなくても問題なく接続できます**

なぜならリポジトリのURLに必要な設定が書かれているためです。
(GitLabを構築時に設定をサボらなければ)
リポジトリのURLの、
「@」の前の「git」がconfigファイルの「User」に相当し、
「:」の後の「12345」が「Port」に相当するため記述不要です。

これは、configファイルから識別名とFQDNが一致している設定を読み込んで、
URL内に不足している情報のみ設定を反映するためです。

これを利用して複数ユーザ切り替えを実現することもできます。
例えば、識別名を「example_otheruser.com」に変更して、
「ssh://git@example_otheruser.com:12345/ryo_4947123/test.git」
とすればconfigに別の鍵ファイル（＝ユーザ）を設定できるようになります。
（AndroidStudioは現行ではGitLabのURLを1つしか登録できないので、コマンドライン限定の技となります。）

## GitLabに公開鍵を登録

GitLabにログイン後、右上のアイコンから「Settings」を選択します。
<img width="201" alt="pubkey_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/b004d492-5c1f-5c28-f46b-67dd7bc502ac.png">

左のメニューから「SSH Keys」を選択します。
<img width="1336" alt="pubkey_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/2cf5b66b-a016-6126-1048-fae2650597cc.png">


画面のKey欄に鍵の生成で作成したファイルのうち、
「{ファイル名}.pub」の方の内容を貼り付けます。

macの場合は以下のコマンドでクリップボードにコピーできます。
`pbcopy < {ファイル名}.pub`
(因みにpbはPasteBoardの略みたいです。)

タイトルには鍵生成コマンドのコメントが自動で設定されます。
問題なければ「Add key」で登録完了です。

## 鍵の有効化
**2017/12/17追記**

鍵の有効化（正確にはsshのknownhostに登録）が必要です。
これをしないとAndroidStudioでGitLabのリポジトリにアクセスした時に、
`Could not read from remote repository.`
エラーが発生してしまいます。

有効化は簡単でターミナルから接続するだけです。
リポジトリへのアクセスができるかのテストも兼ねて以下のように実行します。
`ssh://git@example.com:12345/ryo_4947123/test.git`
(あらかじめGitLabにプロジェクトを新規作成しておいてください)

この時、初めてのサーバへにアクセスの場合以下のように質問が表示されます。

```
The authenticity of host '[example.com]:12345 ([123.45.67.89]:12345)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)?
```

質問にyesを設定すると、
`Warning: Permanently added '[example.com]:12345' (ECDSA) to the list of known hosts.`
となりknownhostに登録されます。

# Android Studioの設定

## GitLabを使用できるようにする

まずは、設定画面を表示します。
<img width="1134" alt="as_setting_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/708ceb5b-723e-ae71-f0bb-8f4a62f89900.png">

左のメニューから「Plugins」を選択します。
その後、「Browse repositories...」を押下します。
<img width="936" alt="as_setting_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/676724e8-86ea-2a8a-3e7c-cc4bcc16ee9a.png">

検索ボックスに「gitlab」と入力して、
「GitLab Projects」が表示されたらインストールを行います。

## SSHクライアントの設定（Mac）

Gitで使用するSSHクライアントを「Built-in」から「Native」に変更します。
<img width="1134" alt="as_setting_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/a4340338-f2c4-f216-0f77-ae893c9ec262.png">

ここはかなり悩んだポイントです。
ターミナルからssh-keygenを行って作成した鍵を使用してAndroid StudioでPushしようとすると
「Invalid PEM structure, '-----BEGIN...' missing」のようなエラーが発生してしまいます。
調べてみると、OpenSSHで作成した鍵と形式が違う場合に発生するようです。
ターミナルからは問題なくPushできるので、もしかして使用しているSSHクライアントが違う？
と思って設定を見たらありました。
Built-inと動作が違うということはMacは独自仕様ということでしょうか・・・

WindowsはSSHのネイティブクライアントがない(OpenSSH一択)のでおそらく関係ないと思います。

## GitLabに接続

プラグインのインストールが完了している場合は、以下のようにメニューに「GitLab」が追加されますので選択します。
<img width="430" alt="as_gitlab_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/e1ad25a3-e096-e978-6d38-7f5c2713c399.png">

設定ボタンを押下します。
GitLabのURLを入力すると、地球儀ボタンが活性化するので押下します。
<img width="459" alt="as_gitlab_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/909125c9-6bc4-00bf-3c16-6e052c45af2a.png">

ブラウザが立ち上がりGitLabに接続されます。
ログインすると、以下の画面が表示されますので、「Name」に適当な名称を設定し、
「Scopes」をチェックして「Create personal access token」を押下します。
<img width="1243" alt="as_gitlab_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/145504/fb826362-17bb-373a-27b4-96af0dcc9f9f.png">

画面が切り替わり、アクセストークンが表示されますので、
Android Studioに戻って設定します。
※アクセストークンが表示されている画面を閉じると二度と参照できなくなるので注意してください。
（何度でも作成できるので、忘れてしまった場合は再作成してください）

これで無事、GitLabからチェッックアウトできるようになります。