⬆️ ⬇️

GitLab CI: branches are no longer needed





Week GitLab CI on Habré! In 2015, we already wrote about the Continuous Integration system built into GitLab. GitLab is often blamed for betraying the ideals of the UNIX way and integrating too many functions into one application. But how convenient is it to use these functions! During the one and a half years that have passed since our publication, the guys made Environments, added the ability to make a button “roll out to food” and many other improvements. Under the cut, I’ll tell you about my experience, how small teams automatically collect and upload not only Voximplant scripts for telephony, but also other projects, sites and services, to the prod / stage.



Branches or environments?



When we make an automatic assembly and display of our projects, then at the entrance we get the question: how to determine what and where to lay out? There are several approaches. And in the last article I described the simplest one: the CI system collects and spreads depending on the branch. We push in "master" (or in "dev", if we have "master stable"), and our assembly is laid out on staging. Merdjim in “prod” (or in “master”, if we have “master stable”), and the build is laid out on the prod. The approach has pros and cons. Personally, in this approach, I don’t really like the double purpose of branches, for many microservices one “master” is enough for the eyes, and the “prod” turns into the “put on prod” button. Plus, testing branches turns into an interesting story.



The second option, which the authors of GitLab suggested in version 8.9, is a separate abstraction for "how to build and where to upload." The abstraction is called “environments” and allows you to roll out the assembly at the touch of a button in the GitLab user interface. It looks like this: in the YAML configuration file of Continuous Integration, we set an arbitrary name Environment and write the code for the assembly and display:

')





build-dev:
image: 'node:8.0.0' # Docker контейнер, в котором выполнится script
environment:
name: dev
script:
- 'node --version' # тут мы как бы собрались и раскатались на стейдж :)
build-prod:
image: 'node:8.0.0'
environment:
name: prod
when: manual # автоматически не выполнять, только по нажатию на кнопку
script:
- 'node --version' # тут - на прод!
view raw .gitlab-ci.yml hosted with ❤ by GitHub
build-dev:
image: 'node:8.0.0' # Docker , script
environment:
name: dev
script:
- 'node --version' # :)
build-prod:
image: 'node:8.0.0'
environment:
name: prod
when: manual # ,
script:
- 'node --version' # - !
view raw .gitlab-ci.yml hosted with ❤ by GitHub


All that abstraction does is add a “roll over here” button to the GitLab interface. It is very convenient to roll out automatically on staging, and on the prod - by pressing a button. You can automatically roll out the styling from the “master” (when: manual is absent and only: master is indicated), and to other environments and from branches - by pressing the button:





Fight with copy-paste



Continuous Integration script is written in YAML. This is such a Python-shaped JSON with a few bonuses. One of these bonuses, the support of which appeared in recent versions, is anchors - to mark a part of the config with an identifier, and then reuse it elsewhere. This allows you to write a generic build and rolling script, and then “copy-paste” it for different environments, modifying only the environment variables. For example, on the Voximplant NDFLka.ru platform, a service was assembled that automatically distributes incoming calls according to complex business logic. For such a service, you can make dev and prod applications with different phone numbers (for dev you can use the phone number in Gotem City, which costs one cent per month), and then roll the dev automatically, and prod - manually, a responsible person according to test results:



build: &build
image: 'node:8.0.0'
script:
- 'echo $BUILD_ENV' # собираем и раскатываем в зависимости от BUILD_ENV
build-dev:
environment:
name: dev
variables:
BUILD_ENV: dev
<<: *build # боремся с копи-пастой
build-prod:
environment:
name: prod
variables:
BUILD_ENV: prod
<<: *build # боремся с копи-пастой
view raw .gitlab-ci.yml hosted with ❤ by GitHub
build: &build
image: 'node:8.0.0'
script:
- 'echo $BUILD_ENV' # BUILD_ENV
build-dev:
environment:
name: dev
variables:
BUILD_ENV: dev
<<: *build # -
build-prod:
environment:
name: prod
variables:
BUILD_ENV: prod
<<: *build # -
view raw .gitlab-ci.yml hosted with ❤ by GitHub


We use Docker for assembly



Like all modern CIs, GitLab asks you to run “runner” on any computer, and the scripts that you write to “script” run on this machine. If you have many different projects, then to build and deploy them you may need different, often incompatible versions of the toolchains. GitLab offers a solution to this issue, seamlessly integrating with docker. It is enough to set the image of the desired container in the “image” field, and GitLab will execute the “script” commands in the specified container. Moreover, for different assembly steps, you can use different containers, passing the results of the assembly between them as “artifact”. In practice, it is convenient to write your own Docker-container to build the project, keep it in the same Git-repository as the project itself, and specify via git url:



image: registry.gitlab.com/username/projectname:tag
view raw .gitlab-ci.yml hosted with ❤ by GitHub
image: registry.gitlab.com/username/projectname:tag
view raw .gitlab-ci.yml hosted with ❤ by GitHub


What to expect?



Gitlab is developing very fast. Over the past few months, we received a real-time CI display, the first test implementations of automatic deployment to kubernetes, and many other minor improvements. A huge combine is not always good. But in the case of GitLab, I believe in the guys, if they continue to develop the product, then we can get a better CI solution, seamlessly integrated with source control and task management system. Your opinion?

Source: https://habr.com/ru/post/332792/



All Articles