Gitlab CI Only run on merge request on master or development

I am learning on how to setup a pipeline. I basically have everything working, but I am left with one question which I am unable to get an answer to.

What I want:

I have two branches. A “development” branch and a “master” branch. Both are protected i.e. you cannot push but have to make a merge request.

When someone makes a merge request, I want to do three things.

  1. Build the project (npm run build, working atm)
  2. Test my code (working atm)
  3. Deploy to my server through FTP and SSH (working atm).

If I merge into master, I only want to deploy to the master server.
If I merge into development, I only want to deploy to the master server.

At the moment that I make a push (without branch protection), everything is working but is deployed to both the mater and development branch.

The moment I put branch protection on, the build and test process are skipped and only the build method is ran (detached it says), but both of the builds are run i.e. Master and Development, while only one of those should run.

Can someone please help me out and explain to me how to fix this? Been trying to get this fixed for the past 3 days without any luck.

Basically what I want:

  1. Always build the project and keep the artifacts
  2. Test the project and keep the artifacts
  3. Build to master or development depending on where the merge request goes to i.e. Master or Development branch

My code is below:

stages:
    - build
    - test
    - deploy

build project:
    stage: build
    image: node:10
    only:
        - merge_requests
    script:
        - npm install --progress=false
        - npm run build
    artifacts:
        paths:
            - ./dist

test build:
    stage: test
    image: alpine
    only:
        - merge_requests
    script:
        - cd dist
        - grep -q "<title>my website</title>" index.html

deploy development:
    stage: deploy
    only:
        - development
        - merge_requests
    before_script:
        - 'which ssh-agent || ( apt-get install -qq openssh-client )'
        - eval $(ssh-agent -s)
        - ssh-add <(echo "$SSH_PRIVATE_KEY")
        - mkdir -p ~/.ssh
        - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

    script:
        - apt-get update -qq && apt-get install -y -qq lftp
        - lftp -c "some command here";

deploy master:
    stage: deploy
    only:
        - master
        - merge_requests
    before_script:
        - 'which ssh-agent || ( apt-get install -qq openssh-client )'
        - eval $(ssh-agent -s)
        - ssh-add <(echo "$SSH_PRIVATE_KEY")
        - mkdir -p ~/.ssh
        - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

    script:
        - apt-get update -qq && apt-get install -y -qq lftp
        - lftp -c "some command here";

In terms of configuration:

  1. Pipelines must succeed is on
  2. Both Master and Development branches are protected, no push is allowed only merging

In conjunction with your use of only:merge_requests, add a rules:if filter to check for the value of the target branch set by the merge request: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME

The description for the above variable is:

The target branch name of the merge request if the pipelines are for merge requests. Available only if only: [merge_requests] or rules syntax is used and the merge request is created.

For example:

deploy master:
  ...
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
1 Like