『入る学科間違えた高専生』の日記

プログラミングのコードを書いたりする予定です。あとは日記等。あといつまで高専生やねん

CircleCI 上で fastlane match の認証を GitHub Personal Access Token で行う

はじめに

CircleCI で fastlane match を実行するときに SSH による接続を使用する際には特に問題は発生しないが、 GitHub Personal Access Token (以下、 GitHub PAT )を使用する際に、正常に clone ができない現象に遭遇したのでその解決した方法とかを紹介する。
なお、 Medium (resource_class: medium) では発生しておらず、 Medium Gen2 (resource_class: macos.x86.medium.gen2) で発生しているのは確認できた。

SSH キーでの接続については今回の趣旨ではないが一応、備忘録として後述する。

結論

fastlane match で証明書リポジトリを取得する前に以下を行う前に以下のコマンドを実行する

$ git config --global --unset url.ssh://git@github.com.insteadof

前提

環境によっては全く同じ状態であっても発生しない可能性があるが私のもとでは発生したので書いている

エラー

+----------------------------------------+---------------------------------------------------+
|                                 Summary for match 2.210.1                                  |
+----------------------------------------+---------------------------------------------------+
| type                                   | development                                       |
| app_identifier                         | ["com.example.com.App"]                           |
| git_url                                | https://github.com/username/certs.git             |
| readonly                               | true                                              |
| generate_apple_certs                   | true                                              |
| skip_provisioning_profiles             | false                                             |
| storage_mode                           | git                                               |
| git_branch                             | certs                                             |
| shallow_clone                          | true                                              |
| clone_branch_directly                  | true                                              |
| git_basic_authorization                | ********                                          |
| skip_google_cloud_account_confirmation | false                                             |
| keychain_name                          | fastlane_tmp_keychain                             |
| force                                  | false                                             |
| force_for_new_devices                  | false                                             |
| include_all_certificates               | false                                             |
| force_for_new_certificates             | false                                             |
| skip_confirmation                      | false                                             |
| safe_remove_certs                      | false                                             |
| skip_docs                              | false                                             |
| platform                               | ios                                               |
| derive_catalyst_app_identifier         | false                                             |
| fail_on_name_taken                     | false                                             |
| skip_certificate_matching              | false                                             |
| skip_set_partition_list                | false                                             |
| verbose                                | false                                             |
+----------------------------------------+---------------------------------------------------+

[01:43:29]: Cloning remote git repo...
Cloning into '/var/folders/0g/q82ptqlj20j9gx25yv10w1m80000gn/T/tmp.94prrvw2'...
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
[01:43:30]: Exit status: 128
[01:43:30]: Error cloning certificates repo, please make sure you have read access to the repository you want to use
[01:43:30]: You passed 'certs' as branch in combination with the `clone_branch_directly` flag. Please remove `clone_branch_directly` flag on the first run for _match_ to create the branch.
[01:43:30]: Run the following command manually to make sure you're properly authenticated:
[01:43:30]: $ git clone https://github.com/username/certs.git /var/folders/0g/q82ptqlj20j9gx25yv10w1m80000gn/T/tmp.94prrvw2 -c http.extraheader='Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -b certs --depth 1 --no-single-branch

非公開リポジトリや情報を保護するために各所変更はしているが、上記のようなエラーが発生した。

実際には git clone で失敗を受けているという情報が見て取れた。
https://github.com/username/certs.gitcerts ブランチはアクセス可能であり、 GitHub PAT もアクセスが可能な状態。

$ git clone https://github.com/username/certs.git $(mktemp -d) -c http.extraheader='Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -b certs --depth 1 --no-single-branch

上記をローカルで実行して確認したところ git clone ができることが確認できた。
また、 CircleCI 上で上記のコマンドを直接実行すると同様に git clone ができないことも確認ができた。

原因究明

GitHub PAT が間違っていないか

まず疑ったのは GitHub PAT である。
今回使用しているのは実際には GitHub PAT ではなく最近 GitHub に導入されて Beta 運用中の fine-grained Personal Access Token (以下、 GitHub fine-grained PAT) である。

docs.github.com

この GitHub fine-grained PAT と GitHub PAT を切り替えるだけで同じコマンドをローカルで実行したところ、実際に git clone を完了することができた。
どうやらおかしいところはなさそうだ。

またここでは以下の環境変数を使い実際にどのようなリクエストが発生しているかも確認していた。

export GIT_TRACE=1
export GIT_CURL_VERBOSE=1

CircleCI の VM マシンでなにかしていないか

怪しいと思ったのは、これが失敗しているのに他のリポジトリ(以下、リポジトリB)では成功ができている。なぜ...
リポジトリB は SSH キーでの接続も許可する設定をしていた。
しかしながら、 fastlane match に与えていた git_urlhttps:// から始まるリポジトリの URL を設定している。
ここで、試しに SSH キーを食わせないように設定を変更して試してみた。
同様にエラーが発生するようになった。

そろそも、 https プロトコルなのに SSH 接続ができている時点で何かが怪しいと睨んだ。

VMSSH 接続する

ジョブに対して Rerun Job with SSHVM マシンに SSH 接続することができる機能が CircleCI にはある。

circleci.com

優秀だなって思ったのは、 GitHub ユーザの SSH キーの公開鍵を読み取って VM マシンに追加してくれるので安全にジョブを公開できる(公開という言い方がちょっと曖昧)
ジョブは Rerun し動いたところで当たり前のように同じエラーが発生し失敗するところまで確認した。
随分と飛躍するが、 Git 周りで何かなかったけなぁと踏んで git config を確認することにした

[url "ssh://git@github.com"]
        insteadOf = https://github.com
[gc]
        auto = 0

( ゚д゚)ハッ!

これは、つまりは https://github.com をすべて ssh://git@github.com に置き換えるという記述である...

原因判明

ということで

$ git config --global --unset url.ssh://git@github.com.insteadof

をすることで万事解決!!!

(おまけ)SSH キーを使用する

証明書リポジトリAllow write access を追加して適宜 fastlane match を実行して証明書を更新する際に VM マシンに追加すると良いでしょう。

CircleCI への SSH キー (秘密鍵)の登録は以下を参考

circleci.com

また、 .circleci/config.yml に記述例は以下のようになる

jobs:
  match:
    macos:
      xcode: "14.2.0"
    resource_class: medium
    steps:
      - checkout
      - add_ssh_keys:
          fingerprints:
            - "SO:ME:FIN:G:ER:PR:IN:T" # ここに CircleCI Web アプリケーション側で追加した際に表示される fingerprint を設定する
      - run: echo "do something..."

最後に

一応 CircleCI サポートに今回の件について問い合わせてみたが、特に問題は発生していないというような回答が得られたので原因はわかっていないが無事解決ができてよかった...

github.com

過去にも同じ問題に遭遇した人がいたらしいが、この方は CircleCI の User Key を導入することで解決したらしい(?)