Ssh 让GitLab CI克隆私有存储库

Ssh 让GitLab CI克隆私有存储库,ssh,continuous-integration,gitlab,gitlab-ci,gitlab-ci-runner,Ssh,Continuous Integration,Gitlab,Gitlab Ci,Gitlab Ci Runner,我已经设置了GitLab和GitLab CI来托管和测试我的一些私人回购。对于此系统下的composer模块,我设置了Satis来解析我的私有包 显然,这些私有软件包需要一个ssh密钥来克隆它们,我在终端中也有这个功能——我可以运行composer安装并获取这些软件包,只要我在shell中添加了带有ssh add的密钥 但是,在GitLab CI中运行我的测试时,如果项目具有任何这些依赖项,测试将不会完成,因为我的GitLab实例需要身份验证才能获得DEP(显然),并且测试失败,原因是主机密钥验

我已经设置了GitLab和GitLab CI来托管和测试我的一些私人回购。对于此系统下的composer模块,我设置了Satis来解析我的私有包

显然,这些私有软件包需要一个ssh密钥来克隆它们,我在终端中也有这个功能——我可以运行composer安装并获取这些软件包,只要我在shell中添加了带有
ssh add
的密钥

但是,在GitLab CI中运行我的测试时,如果项目具有任何这些依赖项,测试将不会完成,因为我的GitLab实例需要身份验证才能获得DEP(显然),并且测试失败,原因是主机密钥验证失败


我的问题是如何设置它,以便在运行测试时,它可以在没有密码的情况下向gitlab进行身份验证?我已经尝试在runners
~/.ssh
文件夹中放置一个无密码的ssh密钥,但是构建甚至不会添加密钥,“eval
ssh-agent-s
”后面的ssh-add似乎失败了,因为代理没有运行…

另请参阅其他解决方案:

  • git子模块权限(请参阅)
  • git配置中的作业令牌和重写repo(请参阅)

下面是使用SSH密钥的完整方法:

总体设计
  • 生成一对SSH密钥
  • 将专用变量添加为项目的安全环境变量
  • 在GitLab CI上使私有脚本可用于测试脚本
  • 在每个私有依赖项上添加公共密钥作为部署密钥
生成一对公共和私有SSH密钥 生成一对不带密码短语的公共和私有SSH密钥:

ssh-keygen -b 4096 -C "<name of your project>" -N "" -f /tmp/name_of_your_project.key

将公共SSH密钥作为部署密钥添加到所有私有依赖项 您需要将公共SSH密钥注册为所有私有密钥的部署密钥 依赖项如下所示:

build:
  stage: build
  before_script:
    - git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@git.myhost.com/".insteadOf "git@git.myhost.com:"
    - git submodule sync && git submodule update --init
  • 浏览
    https://///deploy_keys
  • 单击“新部署密钥”
  • 用项目名称填充文本字段
    标题
  • 用SSH公钥本身填充文本字段
    Key
  • 单击“创建部署密钥”
    • 似乎终于有了一个新的解决方案


      简而言之,在GitLab 8.12中,您所需要做的就是在
      .submodules
      中使用相对路径,
      git子模块更新--init
      将简单地工作

      我将此作为一个答案发布,因为其他人并不完全清楚和/或详细

      从GitLab 8.12+开始,假设子模块repo与请求它的服务器位于同一台服务器上,现在您可以:

    • 像往常一样使用git子模块设置repo(
      git子模块添加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
      
      指示运行程序在生成之前获取所有子模块

    • 请注意:如果你的跑步者似乎忽略了<代码> GITY-SudiMeuleEngult指令,你应该考虑。


      (来源:)

      我有一个场景,我必须在3个不同的脚本中使用ssh密钥,因此我将ssh密钥内容放在一个shell脚本中,并在其他3个脚本之前首先调用它。我想,这是因为
      ssh代理在shell脚本之间没有持久化,或者类似的东西。实际上,我只是将私钥输出到
      ~/.ssh/id\u 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
      

      它就像一个符咒

      如果您不想摆弄ssh密钥或子模块,您可以在git的配置中重写repo以使用作业令牌进行身份验证(在
      gitlab ci.yml
      中):

      我曾经解决过这个问题,因为为测试运行程序设置SSH密钥似乎有点冗长

      git clone http://<username>:<deploy_token>@gitlab.example.com/tanuki/awesome_project.git
      
      git clone http://:@gitlab.example.com/tanuki/awome_project.git
      
      部署令牌是每个项目的,并且是只读的。

      将Gitlab特定的需求嵌入到我的
      .gitmodules
      文件中。这将强制本地开发使用特定的目录布局,并将使迁移到另一个版本控制平台变得复杂

      相反,我听从了他的建议。这里有一个更完整的答案

      我的
      .gitmodules
      文件包含以下内容:

      [submodule "myproject"]
          url = git@git.myhost.com:mygroup/myproject.git
      
      在my
      gitlab ci.yml
      中,我有以下内容:

      build:
        stage: build
        before_script:
          - git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@git.myhost.com/".insteadOf "git@git.myhost.com:"
          - git submodule sync && git submodule update --init
      
      尾随的
      /
      git config
      行中非常重要,因为我们正在从SSH身份验证映射到HTTPS。这让我有一段时间被“非法端口号”错误绊倒了


      我喜欢这个解决方案,因为它将特定于Gitlab的需求嵌入到特定于Gitlab的文件中,其他任何东西都会忽略它。

      在不改变git存储库结构的情况下解决这个问题的一个方法是执行以下步骤:

      1.获取ssh主机密钥 获取正在运行的服务器的ssh主机密钥。对于
      gitlab.com

    • 运行
      ssh keyscan gitlab.com>known_hosts
    • 检查
      ssh keygen-lf known_hosts
      是否与报告的指纹一致
    • 复制
      known_hosts
      的内容,并将其粘贴到存储库中名为
      SSH\u known_hosts
      的变量上
    • 这个步骤只需要一次

      2.将作业配置为使用ssh
      ”ssh://git@gitlab.com“
      bit如果您尝试进行
      git克隆,可能会有所不同git@gitlab.com:
      pip安装-e git+ssh://git@gitlab.com/…
      ;根据您的需要进行相应的调整

      此时,您的CI可以使用ssh从另一个(私有)存储库获取

      3.[干红] 用于一般性地编写:

      .enable_ssh: &enable_ssh |-
          git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf "ssh://git@gitlab.com"
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
          chmod 644 ~/.ssh/known_hosts
      
      并在作业上启用它
      before_script:
          - git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf "git@gitlab.com:"
          - mkdir -p ~/.ssh
          - chmod 700 ~/.ssh
          - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
          - chmod 644 ~/.ssh/known_hosts
      
      .enable_ssh: &enable_ssh |-
          git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf "ssh://git@gitlab.com"
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
          chmod 644 ~/.ssh/known_hosts
      
      test:
          stage: test
          before_script:
              - *enable_ssh
          script:
              - ...
      
      before_script:
          echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
      
      before_script:
          - apk add --no-cache openssh-client git
          - mkdir -p /.ssh && touch /.ssh/known_hosts
          - ssh-keyscan gitlab.com >> /.ssh/known_hosts
          - echo $SSH_KEY | base64 -d >> /.ssh/id_rsa && chmod 600 /.ssh/id_rsa
          - git clone git@git.myhost.com:mygroup/myproject.git