The source code continues the integration of the Mendix application with the GitLab Pipeline

Automate the integration of Mendix Team Server with GitLab Pipeline for continuous deployment to Kubernetes. Follow the process to fetch changes from Team Server, merge them with the Gitlab repository, and publish the code. Check out the GitLab Pipeline code and execute your CI/CD workflow.

Mendix supports the use of a centralized version control repository based on Subversion (SVN), which is the Mendix Team Server. Every project built using the Mendix Platform comes with the Team Server version control system.

The infrastructure technology stack was deployed on-premises, including Kubernetes and Gitlab as two of its main components. The aim was to deploy the Mendix application to Kubernetes in a continuous integration/continuous delivery fashion using the help of GitLab Pipeline.

Git is a distributed version control system, but Subversion (SVN) is a centralized version control system. Developers may find it difficult to create a Continuous Integration/Continuous Deployment pipeline that converts SVN to Git, as there is no suitable way to implement it in a declarative paradigm.

The application code should be present in the Gitlab repository so that another pipeline process can make it Kubernetes-friendly. This involves preparing a Docker image for deployment and publishing it to the Docker repository, and deploying an application through a Helm chart to the Kubernetes environment.

๐Ÿ‘‡ Here are the step-by-step process of implementing this pipeline.

  • Fetch the changes from Mendix Team Server
  • Clone the counterpart repository from Gitlab
  • Merge the changes from Mendix SVN to the Gitlab repository locally.
  • Publish it to Gitlab's respective repository.
๐Ÿš€ You can find the GitLab Pipeline code at Source code continues integration of Mendix application with Gitlab Pipeline ยท GitHub

Base configuration to start with GitLab Pipeline

# pipeline.yaml
image: alpine
stages:
  - fetch
  - sync
  - push
  - clean

๐Ÿ‘†

  • image is to define docker-in-docker based image to execute Gitlab pipeline stages.
  • and stages is to divide the complete process into multiple steps.

Fetch the changes from Mendix Team Server

# pipeline.yaml
variables:
  SVN_SRC_PATH: ${CI_BUILDS_DIR}/${CI_PROJECT_PATH}/svnsrc
  SVN_REPO_PATH: "<path to team server>"
  SVN_USERNAME: "<team server username>"
  SVN_PASSWORD: "<team server password>"
  SVN_TRUNK_FOLDER: "trunk"

๐Ÿ‘† Above mentioned are some variables defined for SVN to use later in the stage

  • SVN_SRC_PATH where SVN trunk will download
  • SVN_REPO_PATH the complete path to SVN Team Server. That usually starts with [https://teamserver.sprintr.com/](https://teamserver.sprintr.com/).
  • SVN_USERNAME User Name to access the Team Server.
  • SVN_PASSWORD Password to access the Team Server.
  • SVN_TRUNK_FOLDER Folder path on SVN to fetch changes from. Mostly it's the trunk folder.

๐Ÿ‘Œ Let's define the stage to download code from Team Server

fetch-svn:
  image: nbrun/svn-client:latest
  stage: fetch
  when: always
  before_script:
    - svn --version
    - mkdir -p $SVN_SRC_PATH
  script:
    - echo "svn fetching"
    - svn checkout $SVN_REPO_PATH $SVN_SRC_PATH --trust-server-cert --non-interactive --no-auth-cache --username $SVN_USERNAME --password "$SVN_PASSWORD";
    - cd $SVN_SRC_PATH
    - svn info > ${SVN_TRUNK_FOLDER}/svn.info
  artifacts:
    name: "$CI_JOB_NAME-svnsrc"
    paths:
      - svnsrc/${SVN_TRUNK_FOLDER}/
    expire_in: 1 day

๐Ÿ‘† What is happening here?

  • image SVN CLI docker image.
  • svn checkout will check out the latest changes from the Team server without saving the credentials on the Gitlab runner server.
  • svn info will save information on the latest fetches from the Team Server to svn.info. It would help to compare the git commit to the SVN release information.

Clone the counterpart repository from Gitlab

variables:
# append below variables in `variables`
  GIT_SRC_PATH: ${CI_BUILDS_DIR}/${CI_PROJECT_PATH}/gitsrc
  GIT_USERNAME: "<git username>"
  GIT_PASSWORD: "<git password>"
  GIT_REPO_BRANCH: "develop"
  GIT_SRC_FOLDER: "mxsrc"
  GIT_REPO_HTTP_PATH: "http://${GIT_USERNAME}:${GIT_PASSWORD}@example.com.ae/test-group/example.git"
  • GIT_REPO_BRANCH is the branch where SVN changes will merge, which could be the "development" or "integration" environment branch.

The next stage is to clone the Gitlab counter repository

fetch-git:
  image: pallet/git-client:latest
  stage: fetch
  when: always
  before_script:
    - git --version
    - mkdir -p $GIT_SRC_PATH
  artifacts:
    name: "$CI_JOB_NAME-gitsrc"
    paths:
      - gitsrc/
    expire_in: 1 day
  script:
    - echo "git fetching"
    - git clone --single-branch --branch ${GIT_REPO_BRANCH} ${GIT_REPO_HTTP_PATH} ${GIT_SRC_PATH}
    - cd $GIT_SRC_PATH
    - git config user.email ${GIT_USERNAME}
    - git config user.name "Safoor Safdar"

๐Ÿ‘† What is happening here?

  • image git client docker-in-docker based image.
  • Script to clone the git repository is pretty straight forward and it will only download a single branch based on the variable GIT_REPO_BRANCH.

Merge the changes from Mendix Team Server to the Gitlab repository

The GitLab runner server would have two folders, one for Git at $GIT_SRC_PATH and the second for SVN source code at $SVN_SRC_PATH.

To keep it simple, it can merge into a cloned branch with rsync.

merge-svn-to-git:
  image: eeacms/rsync:latest
  when: always
  stage: sync
  dependencies:
    - fetch-git
    - fetch-svn
  before_script:
    - rsync --version
    - ls -lah svnsrc/
    - ls -lah gitsrc/
  artifacts:
    name: "$CI_JOB_NAME-sync"
    paths:
      - gitsrc/
    expire_in: 1 day
  script:
    - echo "merging svn into git"
    - rsync -av --progress --delete svnsrc/${SVN_TRUNK_FOLDER}/ gitsrc/${GIT_SRC_FOLDER}
  • rsync will keep the Git repo code as exact as it is on the SVN source folder.
  • dependencies this stage should happen after downloading of Gitlab counterpart repository code and Mendix Team Server code.

Publish it to the Gitlab repository

pushToGit:
  image: pallet/git-client:latest
  stage: push
  when: always
  dependencies:
    - merge-svn-to-git
  before_script:
    - git --version
    - ls -lah gitsrc/${GIT_SRC_FOLDER}
    - cat gitsrc/${GIT_SRC_FOLDER}/svn.info
  script:
    - echo "pushing to git"
    - cd gitsrc/
    - git add --all .
    - git commit -m "auto commit $(date) by:${SVN_USERNAME}"
    - git push ${GIT_REPO_HTTP_PATH} ${GIT_REPO_BRANCH}

๐Ÿ‘† It will commit the changes with a custom commit message and push it to the Gitlab repo. This step is only dependent on the merge-svn-to-git stage.

๐Ÿ“ Communication on Gitlab runner should be open to access SVN Team Server and Gitlab.

Whenever this pipeline is executed, it should be able to fetch the latest changes from Mendix Team Server and push them to the Gitlab repo.

For the final stage, You can "Clean" the temp directories or docker images from the GitLab runner server.

garbag-collector:
  image: docker:19.03.1
  stage: clean
  when: always
  script:
  - echo "cleaning"image: alpine
  - rm -rf ./*

๐Ÿ’ฅ You may want to create a temp branch during the process after "rsync" the SVN and Gitlab repository, and based on that temp branch, anyone can open the PR to follow the proper practices to graduate your changes to the Kubernetes environment.

#devops, #on-premises, #gitlab-pipeline, #mendix, #process-automation


Dive into our blog and let knowledge ignite your curiosity on Deploy Mendix apps to Kubernetes with Gitlab


Hi! I am Safoor Safdar a Senior SRE. Read More. Don't hesitate to reach out! You can find me on Linkedin, or simply drop me an email at me@safoorsafdar.com