パッケージレジストリのPyPIパッケージ
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
Python Package Index(PyPI)は、Pythonの公式サードパーティソフトウェアリポジトリです。GitLab PyPIパッケージレジストリを使用して、GitLabプロジェクト、グループ、および組織でPythonパッケージを公開および共有します。このインテグレーションにより、コードとともにPythonの依存関係を管理し、GitLab内でのPython開発のためのシームレスなワークフローを提供できます。
パッケージレジストリは以下と連携します:
pipクライアントとtwineクライアントが使用する特定のAPIエンドポイントのドキュメントについては、PyPI APIドキュメントを参照してください。
PyPIパッケージをビルドする方法について説明します。
パッケージリクエストの転送に関するセキュリティ通知
GitLabパッケージレジストリを使用する場合、GitLabレジストリで見つからないパッケージリクエストは、自動的にpypi.orgに転送されます。この動作により、pypi.orgからパッケージがダウンロードされる可能性があります。--index-urlフラグを使用している場合でも同様です。
プライベートパッケージを使用する場合は、最大限のセキュリティを確保するために以下を実行します:
- グループの設定でパッケージ転送をオフにします。
- パッケージのインストール時に、
--index-urlフラグと--no-indexフラグの両方を使用します。
前提要件:
- グループのオーナーロールを持っている必要があります。
パッケージリクエストのパッケージ転送をオフにするには、次のようにします:
- 左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
- 設定 > パッケージとレジストリを選択します。
- パッケージ転送で、Forward PyPI package requests(PyPIパッケージリクエストの転送)チェックボックスをオフにします。
管理者エリアでパッケージ転送をオフにする方法については、パッケージ転送の制御を参照してください。
GitLabパッケージレジストリで認証する
GitLabパッケージレジストリを操作する前に、認証する必要があります。
次の方法で認証できます:
- スコープが
apiに設定されたパーソナルアクセストークン。 - スコープが
read_package_registryとwrite_package_registryのどちらか、または両方に設定されたデプロイトークン。 - CI/CDジョブトークン。
ここにドキュメント化されている方法以外の方法は使用しないでください。ドキュメント化されていない方法は、将来削除される可能性があります。
GitLabトークンで認証するには:
TWINE_USERNAMEおよびTWINE_PASSWORD環境変数を更新します。
次に例を示します:
run:
image: python:latest
variables:
TWINE_USERNAME: <personal_access_token_name>
TWINE_PASSWORD: <personal_access_token>
script:
- pip install build twine
- python -m build
- python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*run:
image: python:latest
variables:
TWINE_USERNAME: <deploy_token_username>
TWINE_PASSWORD: <deploy_token>
script:
- pip install build twine
- python -m build
- python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*run:
image: python:latest
variables:
TWINE_USERNAME: gitlab-ci-token
TWINE_PASSWORD: $CI_JOB_TOKEN
script:
- pip install build twine
- python -m build
- python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*グループの認証
グループのパッケージレジストリで認証するには:
- パッケージレジストリに対して認証しますが、プロジェクトURLの代わりにグループURLを使用します:
https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypiPyPIパッケージを公開する
twineを使用してパッケージを公開できます。
前提要件:
- パッケージレジストリで認証する必要があります。
- バージョン文字列が有効である必要があります。
- パッケージ:
- 5 GiB以下です。
descriptionは4,000文字以下です。長いdescription文字列は切り詰められます。- パッケージレジストリにまだ公開されていません。同じバージョンのパッケージを公開しようとすると、
400 Bad Requestが返されます。
PyPIパッケージは、プロジェクトIDを使用して公開されます。プロジェクトがグループにある場合、プロジェクトレジストリに公開されたPyPIパッケージはグループレジストリでも利用できます。詳細については、グループからインストールするを参照してください。
パッケージを公開するには:
リポジトリソースを定義し、
~/.pypircファイルを編集して、以下を追加します:[distutils] index-servers = gitlab [gitlab] repository = https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypitwineでパッケージをアップロードします:
python3 -m twine upload --repository gitlab dist/*パッケージが正常に公開されると、次のようなメッセージが表示されます:
Uploading distributions to https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi Uploading mypypipackage-0.0.1-py3-none-any.whl 100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.58k/4.58k [00:00<00:00, 10.9kB/s] Uploading mypypipackage-0.0.1.tar.gz 100%|███████████████████████████████████████████████████████████████████████████████████████████| 4.24k/4.24k [00:00<00:00, 11.0kB/s]
パッケージはパッケージレジストリに公開され、パッケージとレジストリページに表示されます。
インライン認証で公開する
.pypircファイルを使用してリポジトリソースを定義しなかった場合は、インライン認証でリポジトリに公開できます:
TWINE_PASSWORD=<personal_access_token, deploy_token, or $CI_JOB_TOKEN> \
TWINE_USERNAME=<username, deploy_token_username, or gitlab-ci-token> \
python3 -m twine upload --repository-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi dist/*名前とバージョンが同じパッケージを公開する
名前とバージョンが同じパッケージがすでに存在する場合、パッケージを公開できません。まず既存のパッケージを削除する必要があります。同じパッケージを複数回公開しようとすると、400 Bad Requestエラーが発生します。
PyPIパッケージをインストールする
デフォルトでは、PyPIパッケージがGitLabパッケージレジストリで見つからない場合、リクエストはpypi.orgに転送されます。リクエスト転送を防止する方法の詳細については、パッケージリクエストの転送とセキュリティに関する注意を参照してください。
この動作の仕様は、次のとおりです:
- すべてのGitLabインスタンスでデフォルトで有効になっている
- グループのパッケージとレジストリ設定で構成できる
--index-urlフラグを使用している場合でも適用される
管理者は、継続的インテグレーション設定でこの動作をグローバルに無効にできます。グループオーナーは、グループ設定のパッケージとレジストリセクションで、特定のグループに対してこの動作を無効にできます。
--index-urlオプションを使用する場合は、デフォルトポートの場合はポートを指定しないでください。http URLはデフォルトで80になり、https URLはデフォルトで443になります。
プロジェクトからインストールする
パッケージの最新バージョンをインストールするには、次のコマンドを使用します:
pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple --no-deps <package_name><package_name>は、パッケージ名です。<personal_access_token_name>は、read_apiスコープを持つパーソナルアクセストークン名です。<personal_access_token>は、read_apiスコープを持つパーソナルアクセストークンです。<project_id>は、プロジェクトのURLエンコードされたパス(例:group%2Fproject)またはプロジェクトのID(例:42)です。
これらのコマンドでは、--index-urlの代わりに--extra-index-urlを使用できます。ガイドに従っていて、MyPyPiPackageパッケージをインストールする場合は、次を実行します:
pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simpleこのメッセージは、パッケージが正常にインストールされたことを示しています:
Looking in indexes: https://<personal_access_token_name>:****@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
Collecting mypypipackage
Downloading https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/files/d53334205552a355fee8ca35a164512ef7334f33d309e60240d57073ee4386e6/mypypipackage-0.0.1-py3-none-any.whl (1.6 kB)
Installing collected packages: mypypipackage
Successfully installed mypypipackage-0.0.1グループからインストールする
グループからパッケージの最新バージョンをインストールするには、次のコマンドを使用します:
pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple --no-deps <package_name>このコマンドの要素は、次のとおりです:
<package_name>は、パッケージ名です。<personal_access_token_name>は、read_apiスコープを持つパーソナルアクセストークン名です。<personal_access_token>は、read_apiスコープを持つパーソナルアクセストークンです。<group_id>、はグループIDです。
これらのコマンドでは、--index-urlの代わりに--extra-index-urlを使用できます。ガイドに従っていて、MyPyPiPackageパッケージをインストールする場合は、次を実行します:
pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simpleパッケージ名
GitLabは、Python正規化名(PEP-503)を使用するパッケージを探します。文字-、_、および.はすべて同じように扱われ、繰り返される文字は削除されます。
my.packageのpip installリクエストは、my-package、my_package、およびmy....packageなど、3つの文字のいずれかに一致するパッケージを探します。
セキュリティ上の注意点
PyPIパッケージのインストール時に--extra-index-urlと--index-urlを使用することによるセキュリティへの影響は重大であり、詳細に理解する価値があります:
--index-url: このオプションは、デフォルトのPyPIインデックスURLを指定されたURLに置き換えます。デフォルトでオンになっているGitLabパッケージ転送設定では、パッケージレジストリに見つからないパッケージがPyPIからダウンロードされる可能性があります。パッケージがGitLabのみからインストールされるようにするには、次のいずれかを実行します:- グループ設定でパッケージ転送を無効にする
--index-urlフラグと--no-indexフラグを一緒に使用する
--extra-index-url: このオプションは、デフォルトのPyPIインデックスに加えて、検索する追加のインデックスを追加します。デフォルトのPyPIと追加のインデックスの両方でパッケージがチェックされるため、セキュリティが低く、依存関係に関する混乱攻撃を受けやすくなります。
プライベートパッケージを使用する場合は、次のベストプラクティスに留意してください:
- グループのパッケージ転送設定を確認します。
- プライベートパッケージをインストールするときは、
--no-indexフラグと--index-urlフラグを一緒に使用します。 pip debugを使用してパッケージソースを定期的に監査します。
requirements.txtを使用する
pipでパブリックレジストリにアクセスする場合は、レジストリのURLとともに--extra-index-urlパラメータをrequirements.txtファイルに追加します。
--extra-index-url https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple
package-name==1.0.0これがプライベートレジストリである場合は、いくつかの方法で認証できます。次に例を示します:
requirements.txtファイルの使用:--extra-index-url https://gitlab-ci-token:<personal_token>@gitlab.example.com/api/v4/projects/<project_id>/packages/pypi/simple package-name==1.0.0~/.netrcファイルの使用:machine gitlab.example.com login gitlab-ci-token password <personal_token>
PyPIパッケージのバージョニング
PyPIパッケージを効果的に管理するには、適切なバージョニングが重要です。パッケージが正しくバージョニングされるように、これらのベストプラクティスに従ってください。
セマンティックバージョニング(SemVer)を使用する
パッケージにセマンティックバージョニングを採用します。バージョン番号は、MAJOR.MINOR.PATCH形式にする必要があります:
- 互換性のないAPI変更の場合は、
MAJORバージョンをインクリメントします。 - 下位互換性のある新機能の場合は、
MINORバージョンをインクリメントします。 - 下位互換性のあるバグ修正の場合は、
PATCHバージョンをインクリメントします。
例: 1.0.0、1.1.0、1.1.1。
新しいプロジェクトの場合は、バージョン0.1.0から開始します。これは、APIがまだ安定していない初期開発段階を示しています。
有効なバージョン文字列を使用する
バージョン文字列がPyPI規格に従って有効であることを確認してください。GitLabは、特定の正規表現を使用してバージョン文字列を検証します:
\A(?:
v?
(?:([0-9]+)!)? (?# epoch)
([0-9]+(?:\.[0-9]+)*) (?# release segment)
([-_\.]?((a|b|c|rc|alpha|beta|pre|preview))[-_\.]?([0-9]+)?)? (?# pre-release)
((?:-([0-9]+))|(?:[-_\.]?(post|rev|r)[-_\.]?([0-9]+)?))? (?# post release)
([-_\.]?(dev)[-_\.]?([0-9]+)?)? (?# dev release)
(?:\+([a-z0-9]+(?:[-_\.][a-z0-9]+)*))? (?# local version)
)\z}xiこの正規表現エディタを使用して、正規表現を実験したり、バージョン文字列を試したりできます。
正規表現の詳細については、Pythonドキュメントを参照してください。
サポートされているCLIコマンド
GitLab PyPIリポジトリは、次のCLIコマンドをサポートしています:
twine upload: パッケージをレジストリにアップロードします。pip install: レジストリからPyPIパッケージをインストールします。
トラブルシューティング
パフォーマンスを向上させるため、pipコマンドはパッケージに関連するファイルをキャッシュします。Pipはデータを自動的に削除しません。新しいパッケージがインストールされるにつれて、キャッシュは増加します。問題が発生した場合は、次のコマンドでキャッシュをクリアします:
pip cache purge複数のindex-urlパラメータまたはextra-index-urlパラメータ
複数のindex-urlパラメータとextra-index-urlパラメータを定義できます。
異なる認証トークンを使用して同じドメイン名(gitlab.example.comなど)を複数回使用すると、pipがパッケージを見つけられない場合があります。この問題は、コマンド実行中にpipがトークンを登録および保存する方法が原因です。
この問題を回避するには、index-url値とextra-index-url値をターゲットとするすべてのプロジェクトまたはグループの共通の親グループから、スコープread_package_registryを持つグループデプロイトークンを使用できます。
予期しないパッケージソース
GitLabレジストリのみを使用する予定だった場合に、パッケージがPyPIからインストールされている場合:
- グループのパッケージ転送設定を確認します。
- PyPIフォールバックを防ぐために、
--no-indexフラグと--index-urlフラグを組み合わせて使用します。 pip debugを使用してパッケージソースを定期的に監査します。