Search code examples
githubgitlabgitlab-cipipeline

Gitlab pipeline: stop looping the pipeline


I have come to find out, my pipeline goes on loop. here is my pipeline here is what happening,

Problem Summary

  1. Pipeline Stages and Goals: • Merge Request Submission: • When a Merge Request (MR) is submitted, the pipeline should run tests to ensure the changes are correct. • Merge to Master: • After merging an MR to the master branch: • The bump_version job should run to increment the version in app/meta.py. • The build-prod job should run to build and push Docker images. • The pipeline should stop after the build-prod job.
  2. Current Behavior: • When an MR is submitted, the tests run successfully. • When the MR is merged to master, the bump_version job runs, followed by the build-prod job. • The build-prod job runs again, leading to an infinite loop, causing the entire pipeline to re-trigger.
  3. Suspected Cause: • The bump_version job creates a commit on the master branch, which triggers the build-prod job. • The creation of a Git tag by the bump_version job also triggers the entire pipeline again.

Desired Behavior

• Ensure that the pipeline does not re-trigger itself after the bump_version and build-prod jobs. • The pipeline should stop after the build-prod job when the version bump commit and tag are created.

Requirements:

  1. Merge Request (MR) Submission: • Run tests.
  2. Merge to Master: • Run bump_version job. • Run build-prod job. • Stop the pipeline after build-prod without retriggering.

stages:
  - build-ci-image
  - lint
  - test
  - bump_version
  - build
  - deploy

variables:

build_ci_image:
  stage: build-ci-image
  image:
    name: gcr.io/kaniko-project/executor:v1.14.0-debug
    entrypoint: [""]
  script:
    - /kaniko/executor ...."
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - docker/Dockerfile
        - requirements.dev.txt
        - requirements.txt

.python_job:
  image: ....
  interruptible: true
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "dev"'
    - if: '$CI_COMMIT_TAG'

lint:
  stage: lint
  extends: .python_job
  script:
    - make lint

test:
  stage: test
  script:
    - make coverage

bump_version:
  stage: bump_version
  image: bump2version
  script:
    - git remote set-url ...
    - bump2version $VERSION_PART --current-version $(grep -oP '__VERSION__ = "\K[0-9.]+(?=")' app/meta.py) app/meta.py
    - git push origin HEAD:master --tags
  artifacts:
    paths:
      - app/meta.py
  rules:
    - if: $CI_COMMIT_MESSAGE =~ /^Bump\ version:/
      when: never
    - if: $CI_COMMIT_BRANCH == "master"

build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.14.0-debug
    entrypoint: [""]
  before_script:
    - ....
  script:
    - /kaniko/executor ..."
  rules:
    - if: '$CI_COMMIT_BRANCH == "dev"'
    - if: '$CI_COMMIT_TAG'

build-prod:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.14.0-debug
    entrypoint: [""]
  before_script:
    - ....
  script:
    - |
      new_version=$(grep -o '__VERSION__ = "[0-9.]\+"' app/meta.py | sed 's/__VERSION__ = "//;s/"//')
      /kaniko/executor ...."
  dependencies:
    - bump_version
  artifacts:
    paths:
      - app/meta.py
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"'
    - if: '$CI_COMMIT_TAG'

deploy-staging:
  stage: deploy
  environment:
    name: staging
    url: 
  image:
    name: bitnami/kubectl:latest
    entrypoint: ['']
  script:
    - kubectl ....
  rules:
    - if: $CI_COMMIT_BRANCH == "dev"
    - if: $CI_COMMIT_TAG

Solution

  • You can prevent the pipeline from retriggering after the bump_version and build-prod jobs, by making some adjustments to ensure that the new commit and tag created by bump_version do not trigger the pipeline again. I have modified your yaml file.

    stages:
      - build-ci-image
      - lint
      - test
      - bump_version
      - build
      - deploy
    
    variables:
    
    build_ci_image:
      stage: build-ci-image
      image:
        name: gcr.io/kaniko-project/executor:v1.14.0-debug
        entrypoint: [""]
      script:
        - /kaniko/executor ...."
      rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
          changes:
            - docker/Dockerfile
            - requirements.dev.txt
            - requirements.txt
    
    .python_job:
      image: ....
      interruptible: true
      rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
        - if: '$CI_COMMIT_BRANCH == "dev"'
        - if: '$CI_COMMIT_TAG'
    
    lint:
      stage: lint
      extends: .python_job
      script:
        - make lint
    
    test:
      stage: test
      script:
        - make coverage
    
    bump_version:
      stage: bump_version
      image: bump2version
      script:
        - git remote set-url ...
        - bump2version $VERSION_PART --current-version $(grep -oP '__VERSION__ = "\K[0-9.]+(?=")' app/meta.py) app/meta.py
        - git push origin HEAD:master --tags
      artifacts:
        paths:
          - app/meta.py
      rules:
        - if: '$CI_COMMIT_BRANCH == "master" && $CI_COMMIT_MESSAGE !~ /^Bump version:/ && $CI_PIPELINE_SOURCE == "push"'
    
    build:
      stage: build
      image:
        name: gcr.io/kaniko-project/executor:v1.14.0-debug
        entrypoint: [""]
      before_script:
        - ....
      script:
        - /kaniko/executor ..."
      rules:
        - if: '$CI_COMMIT_BRANCH == "dev" && $CI_PIPELINE_SOURCE != "tag"'
        - if: '$CI_COMMIT_TAG'
    
    build-prod:
      stage: build
      image:
        name: gcr.io/kaniko-project/executor:v1.14.0-debug
        entrypoint: [""]
      before_script:
        - ....
      script:
        - |
          new_version=$(grep -o '__VERSION__ = "[0-9.]\+"' app/meta.py | sed 's/__VERSION__ = "//;s/"//')
          /kaniko/executor ...."
      dependencies:
        - bump_version
      artifacts:
        paths:
          - app/meta.py
      rules:
        - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master" && $CI_COMMIT_MESSAGE !~ /^Bump version:/'
    
    deploy-staging:
      stage: deploy
      environment:
        name: staging
        url: 
      image:
        name: bitnami/kubectl:latest
        entrypoint: ['']
      script:
        - kubectl ....
      rules:
        - if: '$CI_COMMIT_BRANCH == "dev" && $CI_PIPELINE_SOURCE != "tag"'
        - if: '$CI_COMMIT_TAG'