Search code examples
gitlabgitlab-cigitlab-ci-runner

Gitlab Ci unable to push on a branch from runner


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:xxxxxxxxxxxxxxxxxxxx@gitlab.mycompany.com/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


Solution

  • 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 "noreply@example.com" && 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.