简体   繁体   English

Pip 使用 Gitlab-CI 上的个人访问令牌从 Gitlab 安装私有仓库

[英]Pip install a private repo from Gitlab with Personal Access Token on Gitlab-CI

I'm using Gitlab to hosts two private Python packages.我正在使用 Gitlab 来托管两个私有 Python 包。 One, say package B, depends on the other, say A.一个,比如说 package B,取决于另一个,比如说 A。

I would like to setup correctly package B, so I have a setup.py with我想正确设置 package B,所以我有一个 setup.py

install_requires=[
    'packagea @ git+https://gitlab.com/me/packagea.git',
    ...
]

as well as a requirement.txt containing以及一个 requirements.txt 包含

git+https://gitlab.com/me/packagea.git@v1.0.1

And that works well when a user installs package B with pip install git+https://gitlab.com/me/packageb.git , or when a user clones package B and then run pip install -r requirements.txt . And that works well when a user installs package B with pip install git+https://gitlab.com/me/packageb.git , or when a user clones package B and then run pip install -r requirements.txt .

However, I would like to setup continuous integration on package B. My gitlab-ci.yml looks like但是,我想在 package B 上设置持续集成。我的 gitlab-ci.yml 看起来像

image: python:3.7
before_script:
  - pip install -r requirements.txt

pylint:
  script:
    - pylint **/*.py

This fails because the Gitlab-CI runner does not have any username/password to authenticate and pull package A repo.这失败了,因为 Gitlab-CI 运行器没有任何用户名/密码来进行身份验证和提取 package A repo。 I've read that I could generate a Personal Access Token for the CI runner to authenticate, but this would mean that setup.py and requirements.txt contain the token.我读过我可以为 CI 运行器生成一个个人访问令牌以进行身份​​验证,但这意味着 setup.py 和 requirements.txt 包含该令牌。 This seems ugly to me (I'd like the other users to still use their own username/password).这对我来说似乎很难看(我希望其他用户仍然使用他们自己的用户名/密码)。

How can I achieve this?我怎样才能做到这一点?

Since package A is a private repo, you will need permissions to access it in any scenario.由于包 A 是私有存储库,因此在任何情况下您都需要访问它的权限。

You might consider using GitLab Deploy Keys .您可以考虑使用GitLab 部署密钥 That way, any user (including the ci) with the deploy key can read or write to the repo (depending on the access you give the key).这样,任何拥有部署密钥的用户(包括 ci)都可以读取或写入存储库(取决于您授予密钥的访问权限)。 This ties the key to the repo, rather than to your user account.这将密钥与 repo 相关联,而不是与您的用户帐户相关联。

It is important to note that this deploy key gives access to the private repo, so it is a secret and should be treated as such.需要注意的是,这个部署密钥可以访问私有仓库,因此它是一个秘密,应该被如此对待。

Secrets management is a complex, subjective topic with solutions varying significantly based on many factors, including how secure you need your project to be, ease of use, and team size. 机密管理是一个复杂的主观主题,解决方案因许多因素而异,包括您需要项目的安全性、易用性和团队规模。 A common way to avoid storing passwords in plaintext is to use custom environment variables .避免以明文形式存储密码的常见方法是使用自定义环境变量 If you are looking for recommendations on how to set up a project this way, this post might be a good place to start.如果您正在寻找有关如何以这种方式设置项目的建议, 这篇文章可能是一个不错的起点。

In case anyone is like me and gets lost trying to address this pipeline issue, the solution that helped me was this Gitlab issue and the discussion below .万一有人像我一样在尝试解决这个管道问题时迷路了,帮助我的解决方案是这个 Gitlab 问题和下面的讨论

To summarize:总结一下:

In .gitlab-ci.yml add these lines to your before_script section:.gitlab-ci.yml将这些行添加到您的before_script部分:

before_script
  - ...
  - echo "machine gitlab.com" > ~/.netrc
  - echo "login gitlab-ci-token" >> ~/.netrc
  - echo "password ${CI_JOB_TOKEN}" >> ~/.netrc
  - if [ -f "requirements.txt" ]; then pip install -r requirements.txt ; fi

In your requirements.txt file, specify the private dependency with the name, url, and egg (the egg must be the package name).在您的requirements.txt文件中,使用名称、url 和egg(egg必须是包名称)指定私有依赖项。 eg例如

thispackageisonpip>=1.2.3
soisthisone==1.0.0
...
privatepackage @ git+https://gitlab.com/user/repository.git@tag#egg=privatepackage

where tag is eg 'v1.3.3' (note that there must be a tagged version to check out).其中 tag 是例如“v1.3.3”(注意必须有一个标记版本才能签出)。

The private package should now be checked out successfully by the pipeline.现在应该通过管道成功检出私有包。 I haven't been able to get this to work where requirements are specified in install_requires of setup.py , but at least this is workable.我无法在setup.py install_requires中指定要求的情况下使其工作,但至少这是可行的。

In place of personal access token, I figured it out with the generated token when a CI Pipeline is triggered.在触发 CI 管道时,我用生成的令牌代替了个人访问令牌。

In this way, I solved this problem by using the user from pipeline (gitlab-ci-token) and also the token from pipeline (CI_JOB_TOKEN).这样,我通过使用管道中的用户(gitlab-ci-token)和管道中的令牌(CI_JOB_TOKEN)解决了这个问题。

Then, inside the Dockerfile, I added the following commands before the pip install -r requirements.然后,在 Dockerfile 内部,我在 pip install -r 要求之前添加了以下命令。

... 

ARG CI_JOB_TOKEN 
RUN sed -i 's/<GITLAB_URL>/gitlab-ci-token:${CI_JOB_TOKEN}@<GITLAB_URL>/g' requirements.txt

...

After that I build the container in the.gitlab-ci.yml with the following command.之后,我使用以下命令在 .gitlab-ci.yml 中构建容器。

docker build . --build-arg CI_JOB_TOKEN=${CI_JOB_TOKEN} -t <REGISTRY_URL>:<TAG>

I hope that can help someone我希望这可以帮助某人

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM