我设置了GitLab和GitLab CI来托管和测试我的一些私人回购。对于我在这个系统下的作曲家模块,我设置了Satis来解析我的私人包。
显然这些私有包需要一个ssh密钥来克隆它们,我在终端中工作 - 我可以运行composer install并获取这些包,只要我在shell中添加了ssh-add
的密钥。
但是,当在GitLab CI中运行我的测试时,如果项目具有任何这些依赖项,则测试将无法完成,因为我的GitLab实例需要身份验证才能获得deps(显然),并且测试无法说Host key verification failed
。
我的问题是如何设置它以便当跑步者运行测试时它可以在没有密码的情况下对gitlab进行身份验证?我已经尝试在我的跑步者~/.ssh
文件夹中放入无密码的ssh-key,但是构建甚至不会添加密钥,“eval ssh-agent -s
”后面跟ssh-add似乎失败说代理没有运行...
我发布这个作为答案,因为其他人不完全清楚和/或详细的恕我直言
从GitLab 8.12+开始,假设子模块repo与请求它的服务器位于同一服务器中,您现在可以:
git submodule add git@somewhere:folder/mysubmodule.git
).gitmodules
文件,如下所示
[submodule "mysubmodule"]
path = mysubmodule
url = ../../group/mysubmodule.git
其中`../../group/mysubmodule.git'是从您的存储库到子模块的相对路径。gitlab-ci.yml
variables:
GIT_SUBMODULE_STRATEGY: recursive
指示运行器在构建之前获取所有子模块。警告:如果你的跑步者似乎忽略了GIT_SUBMODULE_STRATEGY
指令,你应该考虑updating it。
另见其他解决方案:
这里有一个完整的SSH密钥:
生成一对没有密码的公钥和私钥SSH密钥:
ssh-keygen -b 4096 -C "<name of your project>" -N "" -f /tmp/name_of_your_project.key
您需要将密钥作为安全环境变量添加到项目中,如下所示:
https://<gitlab_host>/<group>/<project_name>/variables
Key
填充文本字段SSH_PRIVATE_KEY
Value
为了使您的私钥可用于测试脚本,您需要将以下内容添加到.gitlab-ci.yml
文件中:
before_script:
# install ssh-agent
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# run ssh-agent
- eval $(ssh-agent -s)
# add ssh key stored in SSH_PRIVATE_KEY variable to the agent store
- ssh-add <(echo "$SSH_PRIVATE_KEY")
# disable host key checking (NOTE: makes you susceptible to man-in-the-middle attacks)
# WARNING: use only in docker container, if you use it with shell you will overwrite your user's ssh config
- mkdir -p ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
Code Snippet comes from GitLab documentation
您需要将公共SSH密钥作为部署密钥注册到所有私有依赖项,如下所示:
https://<gitlab_host>/<group>/<dependency_name>/deploy_keys
Title
Key
如果您不想使用ssh键或子模块,可以在git的配置中覆盖repo以使用作业令牌进行身份验证(在gitlab-ci.yml
中):
before_script:
- git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/group/repo.git".insteadOf [email protected]:group/repo.git
通过使用ssh-keyscan -H 'localgitlab.co.uk' >> ~gitlab_ci_runner/.ssh/known_hosts
将密钥添加到已知主机来解决此问题
我使用deploy tokens来解决这个问题,因为为测试运行器设置SSH密钥似乎有点长。
git clone http://<username>:<deploy_token>@gitlab.example.com/tanuki/awesome_project.git
部署令牌是每个项目并且是只读的。
currently accepted answer将Gitlab特定的要求嵌入到我的.gitmodules
文件中。这会强制特定目录布局进行本地开发,并且会使移动到另一个版本控制平台变得复杂。
相反,我遵循了Juddling's answer的建议。这是一个更完整的答案。
我的.gitmodules
文件包含以下内容:
[submodule "myproject"]
url = [email protected]:mygroup/myproject.git
在我的gitlab-ci.yml
中,我有以下内容:
build:
stage: build
before_script:
- git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@git.myhost.com/".insteadOf "[email protected]:"
- git submodule sync && git submodule update --init
由于我们正在从SSH身份验证映射到HTTPS,因此/
和:
的尾随在git config
行中是至关重要的。这让我误解了一段“非法端口号”错误。
我喜欢这个解决方案,因为它将Gitlab特定的需求嵌入到特定于Gitlab的文件中,其他所有文件都会忽略它。
我有一个场景,我必须在3个不同的脚本中使用我的ssh密钥,因此我将ssh密钥放在一个shell脚本中,并在其他3个脚本之前调用它。这最终无法正常工作,我认为由于ssh-agent
不会在shell脚本之间持久存在,或者是某种效果。实际上我只是将私钥输出到~/.ssh/id_rsa
文件中,这肯定会持久存储到其他脚本中。
.gitlab-ci.yml
script:
- ci/init_ssh.sh
- git push # or whatever you need ssh for
ci / init_ssh.sh
# only run in docker:
[[ ! -e /.dockerenv ]] && exit 0
mkdir -p ~/.ssh
echo "$GITLAB_RUNNER_SSH_KEY" > ~/.ssh/id_rsa
chmod 400 ~/.ssh/id_rsa
echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > /.ssh/config
它就像一个魅力!
似乎终于有一个reasonable solution。
简而言之,就像GitLab 8.12一样,你需要做的就是在.submodules
中使用相对路径,而git submodule update --init
只需要工作