6

We want to know if it's technically possible like in GitHub, to do a git push using https protocol and not ssh and without using directly an username and password in the curl request.

I have seen people that seem to think it is possible, we weren't able to prove it.

Is there any proof or witness out there than can confirm such a feature that allow you to push using a user access token or the gitlab-ci-token within the CI?

1615903
  • 32,635
  • 12
  • 70
  • 99
Dimitri Kopriwa
  • 13,139
  • 27
  • 98
  • 204

3 Answers3

2

I am giving my before_script.sh that can be used within any .gitlab-ci.yml

before_script:
  - ./before_script.sh

All you need is to set a protected environment variable called GL_TOKEN or GITLAB_TOKEN within your project.

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

It doesn't require to change the default git strategy and it will work fine with non protected branch using the default gitlab-ci-token.

On a protected branch, you can use the git push command as usual.

We stopped using SSH keys, Vít Kotačka answers helped us understand why it was failing before.

Dimitri Kopriwa
  • 13,139
  • 27
  • 98
  • 204
1

I was not able to push back via https from a Docker executor when I did changes in the repository which was cloned by gitlab-runner. Therefore, I use following workaround:

  1. Clone a repository to some temporary location via https with a user access token.
  2. Do some Git work (like merging, or tagging).
  3. Push changes back.

I have a job in the .gitlab-ci.yml:

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

and then I have a shell script tag_master.sh with Git commands:

#!/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

This works well.

Vít Kotačka
  • 1,472
  • 1
  • 15
  • 40
  • Thanks, this helped us understand where it was failing, we have simplified the script used in order to make it more transparent and less coupled. – Dimitri Kopriwa Jul 16 '18 at 09:02
1

Just FYI, personal access tokens have account level access, which is generally too broad. The Deploy Key is better as it only has project-level access and can be given write permissions at the time of creation. You can provide the public SSH key as the deploy key and the private key can come from a CI/CD variable.

Here's basically the job I use for tagging:

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
GoForth
  • 573
  • 7
  • 10
  • OP has specifically asked for not using ssh or https with user/pass – Hussam Jan 17 '22 at 08:22
  • There's no user/pass here, deploy keys are used. The user.name and user.email are just used for identifying who does the push but it could be any value, it's trivial. – GoForth Jan 25 '22 at 18:00