Working on Proof of Concept (POC) with a very basic/simple pipeline flow: feature → dev → qa → uat → production.
The Problem:
Merging a feature branch into dev runs as detached (which, if I understand correctly, isn’t ideal) and (I think) because it is detached, the pipeline can’t read the env vars (to access AWS).
But, when I merge dev branch into qa, the MR and pipeline run successfully and not detached
The Question
What am I doing wrong / how do I merge a feature branch into dev (and start the pipeline correctly).
Details - gitlab-ci.yml
The feature branch doesn’t have a stage or job in the pipeline. Once it is ready, I want to merge the feature into dev, which should then kick off the pipeline.
The below script works (does not run detached) if I merge from dev into qa:
stages:
- dev
- qa
dev-jobs:
stage: dev
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "dev" || $CI_COMMIT_BRANCH == "dev"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
before_script:
- # omitted for clarity
script:
- serverless deploy --stage dev --verbose
environment:
name: dev/$CI_COMMIT_REF_NAME
qa-job:
stage: qa
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "qa"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never # do not run a commit push if there is an open merge request
- if: "$CI_COMMIT_BRANCH == 'qa'"
before_script:
- # script things that work on push to dev
script:
- serverless deploy --stage qa --verbose
environment:
name: qa/$CI_COMMIT_REF_NAME
What troubleshooting steps have you already taken?
I protected the feature branch - it wasn’t initially nor do I think it should be?
In your CI env vars (on the /settings/ci_cd page of your project, see Variables), you need to make sure that the AWS env vars you need are not marked protected. This will ensure that the variables will be available on all branches, not just protected branches.
It would be wise to mask the variables, if possible, then they won’t leak into your pipeline logs.
Those two things might solve your issues, but if not, please do post more details.
The workflow rules above don’t prevent a detachment when placed a file top.
But, changing the variables from protected to not protected (but masked) does allow a merge.
Not directly related to the problem, but related to my understanding, I don’t follow the case change from when: never to when: always. I’ve not found a explanation of how/why such a sequence works. I read it as: if a merge_request_id then never run and always apply this rule. I suspect I"m wrong though.
The reason for that rule, is that by default, when you push a new commit to a branch GitLab will start a pipeline for the branch. When you push a new commit to a branch with an associated merge request, GitLab will start a pipeline for the merge request.
So, without the workflow rules you will get two pipelines for each push to a branch with an associated MR.
There are two templates available for tweaking this, one gives you MR pipelines only:
By default, if a rule does not have a when key, GitLab will infer when: on_success. Personally, I’d prefer to write that in because I think it’s easier for new developers if each rule is self-documenting.
You might want to play with these rules and see where you get…
# other stages/jobs removed but resemble the above dev job for now
How I think The Above Works
This took me a while to wrap my head around (overall structure of the workflow rules, stages, jobs, job rules.
Is my understanding correct the first if CI_Pipeline_Source == "merge_request_event" runs a merge based on a matching CI_Commit_Branch because the 3rd if CI_Commit_Branch? If there was no third if, the merge wouldn’t know what to run.
I understand what the 2nd if in the workflow: rules: does (don’t run pipeline on a branch if an open merge exists on a push).
So, if you don’t have a when clause in your rule, the default is on_success. If the job does not have a preceding stage in the pipeline, then on_sucess defaults to true.
In this example, the if: $CI_COMMIT_TAG clause is only necessary if you also want pipelines for Git tags.
The last clause if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH ensures that once an MR has been merged into the default branch, a new pipeline is run on the merged code.