はじめに
こんにちは、インティメート・マージャー開発本部の岡田です。
今日も昨日に引き続きuv関連のお話です。
皆さんは自作のPythonパッケージをどのように利用していますか?
今回は、自作のPythonパッケージをGARで管理、社内向け利用できるようにして、uvによるパッケージ管理に載せて実際に利用できるようにしたので、その事例をご紹介します。
事前に断っておきますが、長くなりすぎるためGoogleCloud周りの設定等に関しては必要な設定のみ記載して、詳細な説明を省略することがあります。
GARって何?
GAR(Google Cloud Artifact Registry)とは、パッケージとDockerコンテナイメージを1か所で保管し管理できる、Google Cloudのサービスの一つです。
こちらを使用することで、Pythonなどのパッケージやコンテナイメージを保存、利用することができます。
環境
パッケージ側
- github-actionsを利用
パッケージ利用側
- github-actionsを利用
- docker,docker-composeを利用
パッケージアップロード
事前準備として、アップロード先になるGARのリポジトリの作成と、作成したGARリポジトリへのpush権限を持ったサービスアカウントの作成、workload_identity連携のための設定を行いました。
GARへのアップロードのためにtwine、認証を通すためにkeyrings.google-artifactregistry-authをそれぞれ使用しています。
コードサンプル
GithubActionsの、workflowファイルのアップロード周りの設定部分を載せておきます
steps:
- uses: actions/checkout@v4
- id: "auth"
uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/{project番号}/locations/global/workloadIdentityPools/{workloadidentitypool名}/providers/{workload identity provider名}}
service_account: {権限借用をするサービスアカウントのサービスアカウント名}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Build package
run: uv build
- name: push package
run: |
# $GAR_REGISTRYにアップロード先のURLを貼っておく
uvx --with keyrings.google-artifactregistry-auth twine upload --verbose --repository-url $GAR_REGISTRY dist/*
パッケージインストール
GARの公開リポジトリであれば問題ありませんが、プライベートリポジトリの場合はインストールの際もいくつか注意が必要で、コンテナをビルドする際と、uv sync等のuvのコマンドを打つ際にGARへの認証を通す必要があります。
環境によって認証の通し方が少しづつ異なるため、それら全てで整合性を保ちつつ認証を通すのは大変でした。
keyringを用いた認証では、デフォルト認証情報を用いて認証を行いますが、認証情報にはいくつか種類があってより優先度の高い認証情報が自動的に使用されてしまうため、複数の認証情報が存在する環境では公式ドキュメントで使用している認証方法と違う方法を使うことがあります
uvの設定
まず、uvの管理に乗せるための設定をします。
インストールしたいパッケージは、PyPIからインストールする場合と同様に、dependencies内に設定をそのまま書けばいいです。それに加えて、パッケージ取得先のindexの設定、パッケージのsourcesの設定、認証のためのkeyring-providerの設定を追加します。
認証するサービスアカウントには、忘れずにGARのpull権限をつけておきましょう。
explicit = trueの設定は、必ずしも必要なものではありませんが、パッケージインストールの参照元(デフォルトではPyPI)に、同名のパッケージがある場合そちらを優先してインストールしてしまうため、うっかり思っていたのと違うパッケージをインストールしてしまうことを防ぐために設定しておきます。
dependencies = [
"packagename"
]
[tool.uv]
keyring-provider = "subprocess"
[tool.uv.sources]
packagename = [{ index = "indexname"}]
[[tool.uv.index]]
name = "indexname"
url = "https://oauth2accesstoken@{region名}-python.pkg.dev/{project名}/{リポジトリ名}/simple/"
explicit = true
開発環境にGCPのVMを利用している等で認証情報が既にある場合を除き、
gcloud auth application-default login コマンド等で認証情報を取得する必要があります。
また、uv自体にkeyringを使う設定を追加します。
uv tool install keyring --with keyrings.google-artifactregistry-auth
初めてuv tool installを使用する場合は、uv tool update-shellコマンドを忘れずに!
dockerの設定
次にDockerイメージのビルドの設定をします。
dockerfileの、uvインストール~uv sync周りの設定をこのようにしました。
ENV GOOGLE_APPLICATION_CREDENTIALS=${HOME}/.config/gcloud/application_default_credentials.json \
# uv tool update-shellの代わり
PATH=$PATH:${HOME}/.local/bin
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/
RUN uv tool install keyring --with keyrings.google-artifactregistry-auth
RUN --mount=type=secret,id=google_credentials,target=${GOOGLE_APPLICATION_CREDENTIALS} \
uv sync --frozen --no-editable --no-dev
開発環境でuvを使う時と異なり、コンテナのビルド時に認証情報が必要なため、少し手順を変える必要があります。
設定を反映させるためにシェルの再起動が必要なuv tool update-shellコマンドの代替として直接$PATHにuv toolを使うためのパスの追加と、--mount=type=secretでのファイルマウントを行っています。
actionsの設定
次にgithub actionsでのワークフローの設定をします。
ここでは、workload identityの設定、uvのインストール、認証、secretでのファイルマウントをしてのビルドを行います。
permissions:
contents: 'read'
id-token: 'write'
steps:
- name: checkout
uses: actions/checkout@v3
- id: 'auth'
uses: google-github-actions/auth@v1
with:
workload_identity_provider: ${{ vars.WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ vars.WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}
- run: gcloud auth configure-docker asia-northeast1-docker.pkg.dev
- name: Install uv
uses: astral-sh/setup-uv@v5
- uses: docker/build-push-action@v4
with:
secret-files: google_credentials=${{ env.GOOGLE_APPLICATION_CREDENTIALS }}
workload_identity認証によって取得した認証情報は、env.GOOGLE_APPLICATION_CREDENTIALSの指す先に格納される
おわりに
DockerイメージをGARで管理する記事は沢山あったものの、pythonパッケージをGARで管理する記事はほとんど見かけず、動くようにするのは大変でした。
まだまだインティメート・マージャー アドベントカレンダーは続きます!
また、インティメート・マージャーでは、新卒から中途採用まで幅広く採用募集中です!
記事を読んで弊社に興味を持ってくれた方は、下記より採用情報をチェックしてみて下さい!