cargoコマンドでプライベートなGitHubリポジトリのRustプロジェクトを参照できるようにしたい
cargoコマンドからプライベートリポジトリを参照できるようにするために、まずは https://doc.rust-lang.org/cargo/appendix/git-authentication.html を読む。
HTTPS を利用する前提でざっくり要約すると、
- 環境変数
CARGO_NET_GIT_FETCH_WITH_CLI=true
を設定する -
~/.gitconfig
にクレデンシャルの参照方法を記述する - クレデンシャルの詳細はこっちを見てね https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
.gitconfig
に設定するのは↓こんな書式。
[credential]
helper = store --file /mnt/thumbdrive/.git-credentials
helper = cache --timeout 30000
同じページの少し上に書いてある git config --global credential.helper store --file ~/.my-credentials
は手元 (rust:1.58.1-slim-bullseye イメージのコンテナ内) では usage: git config [<options>]...
が出力されて git config コマンドのオプションが認識されていないようだった。
.gitconfig
ファイルの配置場所は、実行ユーザーのホームディレクトリじゃないと、設定を読み込んでくれなかった。
プロジェクトルートにファイルを置いても反映されなかった。
クレデンシャルファイルは絶対パスを指定しておけば、readできる場所ならどこに置いても良さそうだった。
インストールする側の Cargo.toml
[package]
name = "crate-install-test"
version = "0.1.0"
authors = ["booink <booink.work@gmail.com>"]
repository = "https://github.com/booink/crate-install-test"
description = """
Crate install test
"""
edition = "2018"
[dependencies]
crate-test-1 = { git = "https://github.com/booink/private-crate" }
インストールされる側のファイル / フォルダ構成
- Cargo.toml
- crate-test-1/
- Cargo.toml
- src/lib.rs
- crate-test-2/
- Cargo.toml
- src/lib.rs
/Cargo.toml
[workspace]
resolver = "2"
members = ["crate-test-1", "crate-test-2"]
/crate-test-1/Cargo.toml
[package]
name = "crate-test-1"
version = "0.1.0"
authors = ["booink <booink.work@gmail.com>"]
repository = "https://github.com/booink/private-crate"
description = """
Crate test 1
"""
edition = "2018"
[dependencies]
anyhow = "1"
thiserror = "1"
/crate-test-1/src/lib.rs
pub struct Hoge;
以下 crate-test-1 と同様の構成の crate-test-2 を作る。
何の設定も無しに cargo build
を叩くと↓こんなふうに怒られる
root@665a8f6e3151:~# cargo build
Updating git repository `https://github.com/booink/private-crate`
error: failed to get `crate-test-1` as a dependency of package `crate-install-test v0.1.0 (/root)`
Caused by:
failed to load source for dependency `crate-test-1`
Caused by:
Unable to update https://github.com/booink/private-crate#6adc17f3
Caused by:
failed to fetch into: /usr/local/cargo/git/db/private-crate-29a491d060f6c1c8
Caused by:
failed to authenticate when downloading repository
* attempted to find username/password via git's `credential.helper` support, but failed
if the git CLI succeeds then `net.git-fetch-with-cli` may help here
https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli
Caused by:
failed to acquire username/password from local configuration
root@665a8f6e3151:~#
インストールする側の Dockerfile の例。
FROM rust:1.58.1-slim-bullseye
ENV CARGO_TARGET_DIR=/tmp/target \
DEBIAN_FRONTEND=noninteractive \
LC_CTYPE=ja_JP.utf8 \
LANG=ja_JP.utf8 \
CARGO_NET_GIT_FETCH_WITH_CLI=true
RUN apt-get update \
&& apt-get install -y -q \
ca-certificates \
locales \
libpq-dev \
gnupg \
apt-transport-https\
libssl-dev \
pkg-config \
curl \
build-essential \
git \
&& echo "ja_JP UTF-8" > /etc/locale.gen \
&& locale-gen
RUN echo "[credential]\n\
helper = store --file /root/.git-credential\n" > ~/.gitconfig
ARG GITHUB_USER
ARG GITHUB_TOKEN
RUN echo "https://${GITHUB_USER}:${GITHUB_TOKEN}@github.com" > /root/.git-credential
WORKDIR /app
COPY ./Cargo.toml Cargo.toml
-
CARGO_NET_GIT_FETCH_WITH_CLI=true
の環境変数は固定なので Dockerfile 内に定義してしまう。 -
.gitconfig
ファイルは、プロジェクト内に実ファイルとして持っていても良いが、間違って消してしまう可能性もあるので、Dockerfile 内で echo で実行ユーザーのホームに強制的に配置しておく。 - クレデンシャルファイルは
.gitconfig
に記述したパスに配置する。クレデンシャルファイルの書式はhttps://{github_user}:{github_token}@github.com
。-
GITHUB_USER
とGITHUB_TOKEN
を ARG で受け取るようにしておく。 - ビルド時には値が確定していないとならないので、ただの環境変数だと空文字になってしまう。
-
- apt-get で git をインストールは必須。gitコマンドが使えないと以下のエラーが出る。
root@6ebb90425cf5:/app# cargo build
Updating git repository `https://github.com/booink/private-crate`
error: failed to get `crate-test-1` as a dependency of package `crate-install-test v0.1.0 (/app)`
Caused by:
failed to load source for dependency `crate-test-1`
Caused by:
Unable to update https://github.com/booink/private-crate
Caused by:
failed to clone into: /usr/local/cargo/git/db/private-crate-f90e54980aa1ea32
Caused by:
could not execute process `git fetch --force --update-head-ok 'https://github.com/booink/private-crate' '+HEAD:refs/remotes/origin/HEAD'` (never executed)
Caused by:
No such file or directory (os error 2)
root@6ebb90425cf5:/app#
Cloud Build でコンテナイメージをビルドする場合は、GITHUB_USER
と GITHUB_TOKEN
を設定して、ビルドの引数に渡す。(未検証)
GitHub のトークンは Expiration を No expiration (無期限) にできるので、無期限にしておく。
日数の指定をしても良いが、ある日急にビルドできなくなるのをビクビクしながら、定期的に値を入れ替えないとならないのが煩わしい。
いざとなったら revoke すれば良いので、無期限で問題ないはず。
VSCode の rust-analyzer を使っていると同様の問題が発生するので、とりあえずエラーがなくなる設定を確認した。
プロジェクト以下のsettings.jsonで環境変数を設定する。
{
...
"rust-analyzer.server.extraEnv": {
"CARGO_NET_GIT_FETCH_WITH_CLI": "true"
}
}
プロジェクト以下のgitの設定を追記する。
[credential]
helper = store --file /path/to/.git/credential
クレデンシャル情報をファイルに保存する。
{GITHUB_USER}
, {GITHUB_TOKEN}
は実際の設定値で置換する。
https://{GITHUB_USER}:{GITHUB_TOKEN}@github.com