【问题标题】:Is it possible to do a git push within a Gitlab-CI without SSH?是否可以在没有 SSH 的情况下在 Gitlab-CI 中执行 git push?
【发布时间】:2018-05-27 14:18:47
【问题描述】:

我们想知道在技术上是否可以像在 GitHub 中那样使用 https 协议而不是 ssh不使用 在 curl 请求中直接使用用户名和密码来执行 git push .

我见过一些人似乎认为这是可能的,但我们无法证明这一点。

是否有任何证据或证人可以确认允许您在 CI 中使用用户访问令牌或 gitlab-ci-token 推送此类功能?

【问题讨论】:

    标签: gitlab gitlab-ci gitlab-ci-runner gitlab-8


    【解决方案1】:

    我提供的before_script.sh 可以在任何.gitlab-ci.yml 中使用

    before_script:
      - ./before_script.sh
    

    您只需在项目中设置一个名为 GL_TOKENGITLAB_TOKEN 的受保护环境变量。

    if [[ -v "GL_TOKEN" || -v "GITLAB_TOKEN" ]]; then
      if [[ "${CI_PROJECT_URL}" =~ (([^/]*/){3}) ]]; then
        mkdir -p $HOME/.config/git
        echo "${BASH_REMATCH[1]/:\/\//://gitlab-ci-token:${GL_TOKEN:-$GITLAB_TOKEN}@}" > $HOME/.config/git/credentials
        git config --global credential.helper store
      fi
    fi
    

    它不需要更改默认的 git 策略,它可以在使用默认 gitlab-ci-token 的非受保护分支上正常工作。

    在受保护的分支上,您可以照常使用git push 命令。

    我们停止使用 SSH 密钥,Vít Kotačka 的回答帮助我们了解了它之前失败的原因。

    【讨论】:

      【解决方案2】:

      当我在由 gitlab-runner克隆的存储库中进行更改时,我无法通过 Docker 执行程序通过 https 推回>。因此,我使用以下解决方法:

      1. 通过 https 使用 用户访问令牌 将存储库克隆到某个临时位置。
      2. 做一些 Git 工作(如合并或标记)。
      3. 推回更改。

      我在.gitlab-ci.yml有一份工作:

      tagMaster:
        stage: finalize
        script: ./tag_master.sh
        only:
        - master
        except:
        - tags
      

      然后我有一个带有 Git 命令的 shell 脚本 tag_master.sh

      #!/usr/bin/env bash
      
      OPC_VERSION=`gradle -q opcVersion`
      CI_PIPELINE_ID=${CI_PIPELINE_ID:-00000}
      
      mkdir /tmp/git-tag
      cd /tmp/git-tag
      git clone https://deployer-token:$DEPLOYER_TOKEN@my.company.com/my-user/my-repo.git
      cd my-repo
      git config user.email deployer@my.company.com
      git config user.name 'Deployer'
      git checkout master
      git pull
      git tag -a -m "[GitLab Runner] Tag ${OPC_VERSION}-${CI_PIPELINE_ID}" ${OPC_VERSION}-${CI_PIPELINE_ID}
      git push --tags
      

      这很好用。

      【讨论】:

      • 谢谢,这有助于我们了解失败的地方,我们已经简化了所使用的脚本,以使其更加透明并减少耦合。
      【解决方案3】:

      仅供参考,个人访问令牌具有帐户级别的访问权限,这通常过于广泛。部署密钥更好,因为它仅具有项目级别的访问权限,并且可以在创建时授予写入权限。您可以提供公共 SSH 密钥作为部署密钥,而私有密钥可以来自 CI/CD 变量。

      这基本上是我用于标记的工作:

      release_tagging:
        stage: release
        image: ubuntu
        before_script:
          - mkdir -p ~/.ssh
          # Settings > Repository > Deploy Keys > "DEPLOY_KEY_PUBLIC" is the public key of the utitlized SSH pair
          # Settings > CI/CD > Variables > "DEPLOY_KEY_PRIVATE" is the private key of the utitlized SSH pair, type is 'File' and ends with empty line
          - mv "$DEPLOY_KEY_PRIVATE" ~/.ssh/id_rsa
          - chmod 600 ~/.ssh/id_rsa
          - 'which ssh-agent || (apt-get update -y && apt-get install openssh-client git -y) > /dev/null 2>&1'
          - eval "$(ssh-agent -s)"
          - ssh-add ~/.ssh/id_rsa > /dev/null 2>&1
          - (ssh-keyscan -H $CI_SERVER_HOST >> ~/.ssh/known_hosts) > /dev/null 2>&1
        script:
          # .gitconfig
          - touch ~/.gitconfig
          - git config --global user.name $GITLAB_USER_NAME
          - git config --global user.email $GITLAB_USER_EMAIL
          # fresh clone
          - mkdir ~/source && cd $_
          - git clone git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
          - cd $CI_PROJECT_NAME
          # Version tag
          - git tag -a "v$(cat version)" -m "version $(cat version)"
          - git push --tags
      

      【讨论】:

      • OP 已明确要求不要将 ssh 或 https 与 user/pass 一起使用
      • 这里没有用户/密码,使用部署密钥。 user.name 和 user.email 仅用于识别推送者,但它可以是任何值,这很简单。
      猜你喜欢
      • 2020-01-06
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      • 2020-03-22
      相关资源
      最近更新 更多