Gitlab Ci unable to push on a branch from runner

10,769

To push to a repo from within a Gitlab CI runner you need to use a user that has push access to the branch you want to push to. We use the following set-up to accomplish this (we let Gitlab CI tag releases and push them).

  1. Create a new Gitlab user called gitlab-ci
  2. Create a SSH key-pair and add the public key to the gitlab-ci user's SSH keys in Gitlab
  3. Give the gitlab-ci user push access to your repo (developer role)
  4. Add the content of the private-key as a CI/CD secret variable called **SSH_PRIVATE_KEY**

This way the private key will be available in CI jobs, next the first part of my CI job looks like this:

script:
    # Install ssh-agent through openssh-client if not present
    - 'which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )'
    # Add the private key to this user
    - eval $(ssh-agent -s) && ssh-add <(echo "$SSH_PRIVATE_KEY") && mkdir -p ~/.ssh
    # Docker specific settings
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
    # Config git to avoid first usage questions. Set the identity
    - git config --global user.email "[email protected]" && git config --global user.name "Gitlab CI"
    # 
    # Do Git stuff, for example:
    #
    - git checkout $CI_COMMIT_REF_NAME
    - git tag my-release-1.0
    - git push -u origin my-release-1.0

Big fat disclaimer: Only use this in Gitlab CI runner setups that are disposed of, you are distributing private SSH keys with potential access to your repo so you must use this carefully.

Share:
10,769
mimiz
Author by

mimiz

Updated on June 14, 2022

Comments

  • mimiz
    mimiz almost 2 years

    I'm trying to settup a CI/CD pipelines with Gitlab Here is what I would like to do :

    NOTE: It's a typescript project

    1. unit tests && integration tests
    2. promote branch dev to branch integration
    3. Build docker image from branch integration
    4. deploy to integration env

    Here is the .gitlab-ci.yml I am using (i:

    stages:
      - test
      - promote
      - build
      - deploy
    cache:
      paths:
        - node_modules/
    test:
      image: node
      stage: test
      before_script:
        - yarn
      script:
        - yarn test
    promote:
      image: node
      stage: promote
      only:
        - dev
      script:
        - git push origin HEAD:integration
    build
      image: node
      stage: build
      only: 
        - integration
      script: 
        - echo "build docker image from integration"
    deploy:
      image: node
      stage: deploy
      only:
        - integration
      script:
        - echo "deploy integration"
    

    My problem is that this line git push origin HEAD:integration can not be done from the gitlab runner, here is the output console :

    Running with gitlab-runner 10.1.0 (c1ecf97f)
      on RUNNER (ce8757c9)
    Using Docker executor with image node ...
    Using docker image sha256:fb8322a7cefdf2b3ba1c15218187bb65f9d4d4ab4e27dc3a91bb4eba38964429 for predefined container...
    Pulling docker image node ...
    Using docker image node ID=sha256:c1d02ac1d9b4de08d3a39fdacde10427d1c4d8505172d31dd2b4ef78048559f8 for build container...
    Running on runner-ce8757c9-project-907-concurrent-0 via VERD842...
    Fetching changes...
    Removing node_modules/
    HEAD is now at 63cccc5 update ci - dev
    From https://gitlab.mycompany.com/project1/ci-demo
       63cccc5..98d347e  dev        -> origin/dev
    Checking out 98d347e5 as dev...
    Skipping Git submodules setup
    Checking cache for default...
    Successfully extracted cache
    $ git push origin HEAD:integration
    remote: You are not allowed to upload code for this project.
    fatal: unable to access 'https://gitlab-ci-token:[email protected]/project1/ci-democi-demo.git/': The requested URL returned error: 403
    ERROR: Job failed: exit code 1
    

    I have read the docs, and some example, but I cant figure out on how to make this work ? Should I create a user gitlab-ci-token ? Should I do branch promotion in a bash script ?

    Feel free to give me any feedback on the pipeline I try to do...

    Regards

    • Kalpa Gunarathna
      Kalpa Gunarathna over 6 years
      1. have you provided git credentials to this pipeline? 2. is git credentials right ? 3. What does git debugging says when GIT_TRACING=2 and GIT_CURL_VERBOSE=1 are set ? 4. Is the remote branch you are trying to push a protected one ?
  • mimiz
    mimiz over 6 years
    Thanks a lot ! This worked for me, and I used a script here : github.com/IlyaSemenov/gitlab-ci-git-push
  • Caleb
    Caleb over 6 years
    Creating a separate user is a bit of a hack, Gitlab has a deploy key system by which you can enable push access via without having a dummy user.
  • Damir Porobic
    Damir Porobic about 5 years
    Is there a way to use a different username instead of gitlab-ci?
  • Stefan van Gastel
    Stefan van Gastel about 5 years
    Sure, it doesn't matter what you call the user. It is identified by the key.
  • DarkFranX
    DarkFranX about 5 years
    It doesn't. This is used for hostname resolution.
  • Caleb
    Caleb over 4 years
    @Ced The documentation is a good place to start.