Кафедра ИСиТ УО ВГТУ
  • Специальности
    • Экономика электронного бизнеса
    • Информационные системы
    • Information Control Systems
  • Каталог
  • Сайт кафедры
  • Сервисы
    • GitLab
    • JupyterHub
    • Soft
  1. ИСиТ
  2. ИППРПО
  3. Практика
  4. Лаб. работа “CI/CD с GitLab”
  • ИСиТ
    • АОС
      • Теория
        • Введение в операционные системы
        • Управление памятью
        • Управление процессами
        • Система ввода-вывода
        • Информационная безопасность
        • Виртуализация
      • Практика
    • РВПсИПП
      • Теория
        • Настройка среды разработки для PHP
        • Разработка web-приложений на базе фреймворков
        • Основы Laravel
        • Шаблоны в Laravel
        • Модели и базы данных в Laravel
        • Формы и валидация в Laravel
        • Аутентификация и авторизация в Laravel
        • Создание REST API в Laravel
        • Работа с файлами и изображениями в Laravel
        • Тестирование и отладка в Laravel
        • Введение в фреймворк Symfony
        • Маршруты и контроллеры в Symfony
        • Шаблоны и Twig в Symfony
        • Формы и валидация в Symfony
        • Доступ к базам данных в Symfony
        • Аутентификация и авторизация в Symfony
        • Сервисы и зависимости в Symfony
        • Создание REST API в Symfony
        • Работа с файлами и медиа в Symfony
        • Сравнение и выбор фреймворка
        • Развертывание веб-приложения
      • Практика
        • Лаб. работа 1 “Создание нового приложения Laravel”
        • Лаб. работа 2 “Добавление главной страницы и базовых маршрутов”
        • Лаб. работа 3 “Создание моделей, миграций и сидеров”
        • Лаб. работа 4 “Создание индексных страниц и пагинация”
        • Лаб. работа 5 “Создание форм для работы с сущностями”
        • Лаб. работа 6 “Работа с файлами (эмуляция S3-хранилища)”
        • Лаб. работа “Создание маршрутов в Laravel”
        • Лаб. работа “Работа с базами данных в Laravel”
        • Лаб. работа “Работа с формами в Laravel”
        • Лаб. работа “Аутентификация и авторизация в Laravel”
        • Лаб. работа “Работа с файлами в Laravel”
        • Лаб. работа “Тестирование и оптимизация в Laravel”
        • Лаб. работа “Создание REST API в Laravel”
        • Лаб. работа “Основы Symfony”
        • Лаб. работа “Шаблоны и представления в Symfony”
        • Лаб. работа “Работа с базами данных в Symfony”
        • Лаб. работа “Фомы и аутентификация в Symfony”
        • Лаб. работа “Сервисы и зависимости в Symfony”
        • Лаб. работа “REST API в Symfony”
        • Лаб. работа “Работа с медиа контентом в Symfony”
        • Лаб. работа “Создание и развертывание проекта”
        • Расчетно-графическая работа: Разработка веб-приложения с использованием Laravel
          • Методические рекомендации по выполнению работы
          • Варианты заданий для расчетно-графической работы
    • ПСП
      • Теория
        • Введение
        • Протокол HTTP
        • Программирование с использованием сокетов
        • Введение в PHP
        • Работа с базами данных в PHP
        • Объектно-ориентированные возможности PHP
        • Настройка среды разработки для PHP
        • Разработка web-приложений на базе фреймворков
      • Практика
        • Программное обеспечение
        • Регистрация в JupyterHub
        • Лаб. работа “Почтовые протоколы”
        • Лаб. работа “Протокол FTP”
        • Лаб. работа “Протокол HTTP”
        • Лаб. работа “Программирование сетевых приложений с использованием сокетов”
        • Лаб. работа “Основы PHP”
        • Лаб. работа “Массивы в PHP”
        • Лаб. работа “Создание веб-приложений с использованием Slim”
      • Темы курсовых проектов по дисциплине “Программирование сетевых приложений”
    • Компьютерные сети
      • Теория
        • Введение в компьютерные сети
        • Топологии сетей
        • Кодирование и мультиплексирование
        • Стеки протоколов
        • Адресация в компьютерных сетях
        • Система доменных имен (DNS)
        • Программирование с использованием сокетов
        • Введение в PHP
        • Протокол HTTP
        • Введение в компьютерные сети
      • Практика
        • Программное обеспечение
        • Регистрация в JupyterHub
        • Лаб. работа “Почтовые протоколы”
        • Лаб. работа “Протокол FTP”
        • Лаб. работа “Протокол HTTP”
        • Лаб. работа “Программирование сетевых приложений с использованием сокетов”
        • Лаб. работа “Основы PHP”
        • Лаб работа “Массивы в PHP”
    • РиОИИС
      • Теория
        • Классификация оптимизационных задач
        • Генетические алгоритмы
        • Системы массового обслуживания
        • Теория игр
        • Машинное обучение
        • Глубокое обучение (Deep learning)
        • Основы функционального программирования
        • Основы программирования на Haskell
        • Введение в логическое программирование
        • Инференция и рассуждения в логическом программировании
        • Разработка экспертных систем
        • Интеллектуальные системы и их архитектура
        • Веб-скрэйпинг
        • Сбор данных с открытых API
      • Практика
        • JupyterHub
        • Лаб. работа "Методы одномерной оптимизации"
          • Лаб. работа “Методы одномерной оптимизации”
        • Лаб. работа “Методы многомерной оптимизации”
        • Лаб. работа “Основы программирования на Python”
        • Лаб. работа “Функции в Python”
        • Лаб. работа “Рекурсия в Python”
        • Лаб. работа “Итераторы в Python”
        • Лаб. работа “Генетические алгоритмы”
        • Лаб. работа “Haskell”
        • Лаб. работа “Логическое программирование”
        • Лаб. работа “Сбор данных с помощью веб-скрейпинга”
        • Лаб. работа “Предобработка данных”
        • Лаб. работа “Машинное обучение: классификация”
        • Лаб. работа “Создание и обучение простейших нейронных сетей”
        • Лаб. работа “Системы массового обслуживания”
        • Лаб. работа “Обработка естественного языка”
        • Лаб. работа “Компьютерное зрение”
        • Лаб. работа “Нейросети и глубокое обучение”
    • КСКР
      • Практика
        • Лаб. работа “Одномерные и двумерные массивы в C#”
        • Лаб. работа “Обращение матриц в C#”
    • Системное программирование
      • Теория
        • Управление памятью в Windows
        • Файловые операции в Windows
        • Управление процессами в Windows
        • Графический интерфейс Windows
        • ОС Unix
      • Практика
        • Лаб. работа “Работа с динамической памятью в Windows”
        • Лаб. работа “Операции с файлами в Windows”
        • Лаб. работа “Управление процессами в Windows”
        • Лаб. работа “Работа с виртуальной машиной Linux”
        • Лаб. работа “Язык командного энтерпритатора Shell”
        • Лаб. работа “Работа с файлами в Linux”
        • Лаб. работа “Работа с процессами в Linux”
    • ИППРПО
      • Теория
      • Практика
        • Лаб. работа “Язык командного энтерпритатора Shell”
        • Лаб. работа “Управление процессами в Shell”
        • Лаб. работа “Управление файловой системой в Shell”
        • Лаб. работа “Управление пакетами в ОС Linux”
        • Лаб. работа “Сетевые инструменты в Linux”
        • Лаб. работа “Мониторинг и анализ системы Linux”
        • Лаб. работа “Основы Docker. Управление контейнерами”
        • Лаб. работа “Docker: Сети”
        • Лаб. работа "Docker: Образы"
        • Лаб. работа “Docker Compose: Управление многоконтейнерными приложениями”
        • Лаб. работа “CI/CD с GitLab”

Содержание

  • Лабораторная работа по теме “CI/CD с GitLab”
    • Цель работы
    • Краткие теоретические сведения
    • Краткий справочник по .gitlab-ci.yml
    • Требования к окружению
    • Порядок выполнения работы
    • Задания для самостоятельного выполнения
    • Контрольные вопросы
    • Требования к отчету
  1. ИСиТ
  2. ИППРПО
  3. Практика
  4. Лаб. работа “CI/CD с GitLab”

Лаб. работа “CI/CD с GitLab”

Инструменты промышленной разработки
Практика
Автор

Бизюк Андрей

Дата публикации

16 декабря 2025 г.

Лабораторная работа по теме “CI/CD с GitLab”

Цель работы

Изучить практические аспекты настройки и использования системы непрерывной интеграции и развертывания (CI/CD) с использованием GitLab. Получить навыки создания пайплайнов, настройки автоматического тестирования, сборки и развертывания приложений.

Краткие теоретические сведения

GitLab CI/CD — это встроенная в GitLab система непрерывной интеграции и развертывания, которая позволяет автоматизировать процессы разработки, тестирования и развертывания приложений.

Ключевые концепции GitLab CI/CD:

  • Runner — агент, который выполняет задачи пайплайна. Может быть общим, групповым или специфичным для проекта.
  • Pipeline — набор задач (jobs), объединенных в стадии (stages), которые выполняются в определенном порядке.
  • Job — минимальная единица выполнения в пайплайне, содержит скрипты для выполнения.
  • Stage — группа jobs, которые выполняются параллельно. Стадии выполняются последовательно.
  • Artifacts — файлы, создаваемые job’ом и передаваемые между стадиями.
  • Variables — переменные окружения для конфигурации пайплайна.
  • Cache — механизм кэширования зависимостей для ускорения сборок.

Преимущества GitLab CI/CD: * Полная интеграция с GitLab * Встроенная поддержка Docker * Автоматическое обнаружение .gitlab-ci.yml * Богатые возможности визуализации * Поддержка множественных раннеров * Встроенный registry для Docker образов

Краткий справочник по .gitlab-ci.yml

Основная структура

stages:                    # Определение стадий
  - build
  - test
  - deploy

variables:                 # Глобальные переменные
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

job_name:                  # Имя job'а
  stage: build            # Стадия выполнения
  image: node:18          # Docker образ
  script:                 # Команды для выполнения
    - npm install
    - npm run build
  artifacts:              # Артефакты
    paths:
      - dist/
    expire_in: 1 week
  only:                   # Условия запуска
    - main
    - develop

Основные ключевые слова

  • stages — список стадий пайплайна
  • stage — стадия для конкретного job’а
  • image — Docker образ для выполнения job’а
  • services — дополнительные Docker сервисы
  • script — команды для выполнения
  • before_script — команды перед основным скриптом
  • after_script — команды после основного скрипта
  • artifacts — файлы для сохранения
  • cache — кэширование файлов
  • only/except — условия запуска job’а
  • variables — переменные окружения
  • dependencies — зависимости от других job’ов
  • allow_failure — разрешение на неудачу
  • when — условие выполнения (on_success, on_failure, always)

Типы пайплайнов

  • Branch Pipelines — запускаются при push в ветки
  • Merge Request Pipelines — запускаются при создании MR
  • Scheduled Pipelines — запускаются по расписанию
  • Manual Pipelines — запускаются вручную
  • Triggered Pipelines — запускаются через API

Требования к окружению

  • Доступ к GitLab серверу: it.vstu.by/gitlab
  • Учетная запись в GitLab
  • Git установлен локально
  • Docker установлен локально (для локального тестирования)
  • Базовые знания Git
  • Текстовый редактор

Порядок выполнения работы

Часть 1. Подключение к GitLab

  1. Регистрация/вход в GitLab Перейдите по адресу http://it.vstu.by/gitlab и войдите в систему под своей учетной записью.

  2. Настройка SSH ключей (рекомендуется) Сгенерируйте SSH ключ для безопасной работы с Git:

    ssh-keygen -t ed25519 -C "your.email@example.com"

    Добавьте публичный ключ в GitLab: Profile → SSH Keys → Add new key

  3. Настройка Git локально Настройте Git с вашими данными:

    git config --global user.name "Ваше Имя"
    git config --global user.email "your.email@example.com"

Часть 2. Создание проекта

  1. Создание нового проекта В GitLab создайте новый проект:

    • Нажмите “New project”
    • Выберите “Create blank project”
    • Введите название: cicd-lab-work
    • Описание: Лабораторная работа по CI/CD
    • Установите видимость: Private
    • Нажмите “Create project”
  2. Клонирование репозитория Склонируйте созданный репозиторий:

    git clone http://it.vstu.by/gitlab/ваш-username/cicd-lab-work.git
    cd cicd-lab-work

Часть 3. Создание простого приложения

  1. Создание Node.js приложения Создайте простое веб-приложение:

    # package.json
    {
      "name": "cicd-lab-app",
      "version": "1.0.0",
      "description": "Simple app for CI/CD lab",
      "main": "app.js",
      "scripts": {
        "start": "node app.js",
        "test": "jest",
        "test:watch": "jest --watch",
        "lint": "eslint .",
        "build": "npm run lint && npm test"
      },
      "dependencies": {
        "express": "^4.18.2"
      },
      "devDependencies": {
        "jest": "^29.7.0",
        "supertest": "^6.3.3",
        "eslint": "^8.50.0"
      },
      "jest": {
        "testEnvironment": "node"
      }
    }
  2. Создание основного файла приложения Создайте app.js:

    const express = require('express');
    const app = express();
    const PORT = process.env.PORT || 3000;
    
    app.use(express.json());
    
    // Health check endpoint
    app.get('/health', (req, res) => {
      res.json({ 
        status: 'healthy', 
        timestamp: new Date().toISOString(),
        version: '1.0.0'
      });
    });
    
    // Main endpoint
    app.get('/', (req, res) => {
      res.json({
        message: 'Hello from CI/CD Lab App!',
        environment: process.env.NODE_ENV || 'development',
        timestamp: new Date().toISOString()
      });
    });
    
    // API endpoint with basic functionality
    app.get('/api/data', (req, res) => {
      res.json({
        data: [
          { id: 1, name: 'Item 1', status: 'active' },
          { id: 2, name: 'Item 2', status: 'inactive' },
          { id: 3, name: 'Item 3', status: 'active' }
        ],
        total: 3,
        timestamp: new Date().toISOString()
      });
    });
    
    // Error handling middleware
    app.use((err, req, res, next) => {
      console.error(err.stack);
      res.status(500).json({ 
        error: 'Something went wrong!',
        timestamp: new Date().toISOString()
      });
    });
    
    app.listen(PORT, () => {
      console.log(`Server is running on port ${PORT}`);
    });
    
    module.exports = app;
  3. Создание тестов Создайте папку tests и файл app.test.js:

    const request = require('supertest');
    const app = require('../app');
    
    describe('API Endpoints', () => {
      test('GET / should return welcome message', async () => {
        const response = await request(app)
          .get('/')
          .expect('Content-Type', /json/)
          .expect(200);
    
        expect(response.body).toHaveProperty('message');
        expect(response.body.message).toContain('Hello from CI/CD Lab App!');
      });
    
      test('GET /health should return health status', async () => {
        const response = await request(app)
          .get('/health')
          .expect('Content-Type', /json/)
          .expect(200);
    
        expect(response.body).toHaveProperty('status', 'healthy');
        expect(response.body).toHaveProperty('timestamp');
      });
    
      test('GET /api/data should return data array', async () => {
        const response = await request(app)
          .get('/api/data')
          .expect('Content-Type', /json/)
          .expect(200);
    
        expect(response.body).toHaveProperty('data');
        expect(response.body).toHaveProperty('total', 3);
        expect(Array.isArray(response.body.data)).toBe(true);
      });
    
      test('GET /nonexistent should return 404', async () => {
        await request(app)
          .get('/nonexistent')
          .expect(404);
      });
    });
    
    describe('Application Logic', () => {
      test('should handle missing environment variables', () => {
        delete process.env.PORT;
        const testApp = require('../app');
        expect(testApp).toBeDefined();
      });
    });
  4. Создание Dockerfile Создайте Dockerfile:

    # Build stage
    FROM node:18-alpine AS builder
    
    WORKDIR /app
    
    # Copy package files
    COPY package*.json ./
    
    # Install dependencies
    RUN npm ci --only=production
    
    # Production stage
    FROM node:18-alpine
    
    WORKDIR /app
    
    # Copy built application
    COPY --from=builder /app/node_modules ./node_modules
    COPY . .
    
    # Create non-root user
    RUN addgroup -g 1001 -S nodejs
    RUN adduser -S nodejs -u 1001
    
    # Change ownership
    RUN chown -R nodejs:nodejs /app
    USER nodejs
    
    # Expose port
    EXPOSE 3000
    
    # Health check
    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
      CMD node healthcheck.js
    
    # Start application
    CMD ["node", "app.js"]
  5. Создание healthcheck.js Создайте healthcheck.js:

    const http = require('http');
    
    const options = {
      hostname: 'localhost',
      port: process.env.PORT || 3000,
      path: '/health',
      method: 'GET',
      timeout: 2000
    };
    
    const req = http.request(options, (res) => {
      if (res.statusCode === 200) {
        process.exit(0);
      } else {
        process.exit(1);
      }
    });
    
    req.on('error', () => {
      process.exit(1);
    });
    
    req.on('timeout', () => {
      req.destroy();
      process.exit(1);
    });
    
    req.end();

Часть 4. Создание базового .gitlab-ci.yml

  1. Создание простого пайплайна Создайте файл .gitlab-ci.yml в корне проекта:

    stages:
      - install
      - test
      - build
      - deploy
    
    variables:
      NODE_VERSION: "18"
      DOCKER_DRIVER: overlay2
    
    # Install dependencies
    install_dependencies:
      stage: install
      image: node:${NODE_VERSION}
      script:
        - npm ci
      cache:
        paths:
          - node_modules/
      artifacts:
        paths:
          - node_modules/
        expire_in: 1 hour
    
    # Run tests
    test:
      stage: test
      image: node:${NODE_VERSION}
      dependencies:
        - install_dependencies
      script:
        - npm test
      coverage: '/Coverage: \d+\.\d+%/'
      artifacts:
        reports:
          junit: junit.xml
        paths:
          - coverage/
        expire_in: 1 week
    
    # Build Docker image
    build_docker:
      stage: build
      image: docker:latest
      services:
        - docker:dind
      dependencies:
        - install_dependencies
      script:
        - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
        - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      only:
        - main
        - develop
        - merge_requests
    
    # Deploy to staging (manual)
    deploy_staging:
      stage: deploy
      image: alpine:latest
      script:
        - echo "Deploying to staging environment..."
        - echo "Application version: $CI_COMMIT_SHA"
        - echo "Deployed at: $(date)"
      environment:
        name: staging
        url: https://staging.example.com
      when: manual
      only:
        - main
  2. Первый коммит и push Добавьте файлы в Git и отправьте в GitLab:

    git add .
    git commit -m "Initial commit: Add basic application and CI/CD pipeline"
    git push origin main
  3. Проверка пайплайна Перейдите в GitLab → CI/CD → Pipelines и посмотрите на выполнение пайплайна.

Часть 5. Расширение пайплайна

  1. Добавление линтинга Обновите .gitlab-ci.yml, добавив стадию линтинга:

    stages:
      - install
      - lint
      - test
      - build
      - deploy
    
    # Lint code
    lint:
      stage: lint
      image: node:${NODE_VERSION}
      dependencies:
        - install_dependencies
      script:
        - npm run lint
      allow_failure: false
  2. Добавление security сканирования Добавьте job для проверки безопасности:

    # Security scan
    security_scan:
      stage: test
      image: node:${NODE_VERSION}
      dependencies:
        - install_dependencies
      script:
        - npm audit --audit-level moderate
      allow_failure: true
      only:
        - main
        - merge_requests
  3. Добавление интеграционных тестов Создайте интеграционные тесты в файле tests/integration.test.js:

    const request = require('supertest');
    const app = require('../app');
    
    describe('Integration Tests', () => {
      let server;
    
      beforeAll((done) => {
        server = app.listen(0, () => {
          done();
        });
      });
    
      afterAll((done) => {
        server.close(done);
      });
    
      test('should handle concurrent requests', async () => {
        const promises = [];
        for (let i = 0; i < 10; i++) {
          promises.push(request(app).get('/api/data'));
        }
    
        const responses = await Promise.all(promises);
    
        responses.forEach(response => {
          expect(response.status).toBe(200);
          expect(response.body).toHaveProperty('data');
        });
      });
    
      test('should maintain data consistency', async () => {
        const response1 = await request(app).get('/api/data');
        const response2 = await request(app).get('/api/data');
    
        expect(response1.body.total).toBe(response2.body.total);
        expect(response1.body.data.length).toBe(response2.body.data.length);
      });
    });
  4. Обновление package.json Добавьте скрипт для интеграционных тестов:

    {
      "scripts": {
        "test": "jest",
        "test:integration": "jest --testPathPattern=integration",
        "test:unit": "jest --testPathPattern=unit"
      }
    }
  5. Обновление .gitlab-ci.yml Добавьте job для интеграционных тестов:

    # Integration tests
    integration_tests:
      stage: test
      image: node:${NODE_VERSION}
      dependencies:
        - install_dependencies
      script:
        - npm run test:integration
      artifacts:
        reports:
          junit: junit-integration.xml
        paths:
          - coverage-integration/
        expire_in: 1 week
      only:
        - main
        - merge_requests

Часть 6. Работа с артефактами и кэшем

  1. Улучшение кэширования Обновите настройки кэша в .gitlab-ci.yml:

    cache:
      paths:
        - node_modules/
        - .npm/
      key: 
        files:
          - package-lock.json
      policy: pull-push
  2. Настройка артефактов Добавьте более детальные настройки артефактов:

    test:
      stage: test
      image: node:${NODE_VERSION}
      dependencies:
        - install_dependencies
      script:
        - npm test
      coverage: '/Coverage: \d+\.\d+%/'
      artifacts:
        when: always
        reports:
          junit: junit.xml
          coverage_report:
            coverage_format: cobertura
            path: coverage/cobertura-coverage.xml
        paths:
          - coverage/
          - junit.xml
        expire_in: 30 days
      coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'

Часть 7. Настройка окружений

  1. Добавление окружений Обновите .gitlab-ci.yml с настройками окружений:

    # Deploy to staging
    deploy_staging:
      stage: deploy
      image: alpine:latest
      script:
        - echo "Deploying to staging..."
        - echo "Environment: staging"
        - echo "Version: $CI_COMMIT_SHA"
        - echo "Branch: $CI_COMMIT_REF_NAME"
        - echo "Author: $GITLAB_USER_NAME"
      environment:
        name: staging
        url: https://staging.example.com
        on_stop: stop_staging
      when: manual
      only:
        - main
    
    # Stop staging environment
    stop_staging:
      stage: deploy
      image: alpine:latest
      script:
        - echo "Stopping staging environment..."
      environment:
        name: staging
        action: stop
      when: manual
      only:
        - main
    
    # Deploy to production
    deploy_production:
      stage: deploy
      image: alpine:latest
      script:
        - echo "Deploying to production..."
        - echo "Environment: production"
        - echo "Version: $CI_COMMIT_SHA"
      environment:
        name: production
        url: https://production.example.com
      when: manual
      only:
        - tags
      dependencies:
        - build_docker

Часть 8. Создание merge request

  1. Создание feature ветки Создайте новую ветку для добавления функции:

    git checkout -b feature/add-user-endpoint
  2. Добавление нового endpoint Обновите app.js, добавив новый endpoint:

    // Add user endpoint
    app.post('/api/users', (req, res) => {
      const { name, email } = req.body;
    
      if (!name || !email) {
        return res.status(400).json({
          error: 'Name and email are required'
        });
      }
    
      const newUser = {
        id: Date.now(),
        name,
        email,
        createdAt: new Date().toISOString()
      };
    
      res.status(201).json({
        message: 'User created successfully',
        user: newUser
      });
    });
  3. Добавление тестов Создайте тесты для нового endpoint в tests/users.test.js:

    const request = require('supertest');
    const app = require('../app');
    
    describe('User Endpoints', () => {
      test('POST /api/users should create a new user', async () => {
        const userData = {
          name: 'John Doe',
          email: 'john@example.com'
        };
    
        const response = await request(app)
          .post('/api/users')
          .send(userData)
          .expect('Content-Type', /json/)
          .expect(201);
    
        expect(response.body).toHaveProperty('message', 'User created successfully');
        expect(response.body).toHaveProperty('user');
        expect(response.body.user).toHaveProperty('name', userData.name);
        expect(response.body.user).toHaveProperty('email', userData.email);
      });
    
      test('POST /api/users should return 400 for missing data', async () => {
        const response = await request(app)
          .post('/api/users')
          .send({ name: 'John Doe' })
          .expect(400);
    
        expect(response.body).toHaveProperty('error');
      });
    });
  4. Коммит и push bash git add . git commit -m "feat: Add user creation endpoint" git push origin feature/add-user-endpoint

  5. Создание Merge Request В GitLab создайте Merge Request:

    • Нажмите “Create merge request”
    • Выберите source branch: feature/add-user-endpoint
    • Target branch: main
    • Добавьте описание изменений
    • Нажмите “Create merge request”
  6. Проверка MR пайплайна Посмотрите, как запустился пайплайн для Merge Request.

Часть 9. Настройка scheduled пайплайнов

  1. Добавление scheduled job Добавьте в .gitlab-ci.yml:

    # Nightly security scan
    security_scan_nightly:
      stage: test
      image: node:${NODE_VERSION}
      script:
        - npm audit --audit-level high
        - echo "Running security scan..."
      only:
        - schedules
      allow_failure: true
  2. Создание расписания В GitLab: Settings → CI/CD → Schedules → New Schedule

    • Description: Nightly Security Scan
    • Cron: 0 2 * * * (каждый день в 2:00)
    • Target branch: main
    • Нажмите “Add pipeline schedule”

Часть 10. Мониторинг и отладка

  1. Просмотр логов пайплайна В GitLab перейдите в CI/CD → Pipelines → выберите пайплайн → Jobs → конкретный job

  2. Использование переменных Добавьте debug информацию:

    debug_info:
      stage: test
      image: alpine:latest
      script:
        - echo "=== Debug Information ==="
        - echo "Commit SHA: $CI_COMMIT_SHA"
        - echo "Branch: $CI_COMMIT_REF_NAME"
        - echo "User: $GITLAB_USER_NAME"
        - echo "Pipeline ID: $CI_PIPELINE_ID"
        - echo "Job ID: $CI_JOB_ID"
        - echo "Environment: $CI_ENVIRONMENT_NAME"
        - echo "========================"
      when: manual
      only:
        - main
  3. Настройка уведомлений В GitLab: Settings → Integrations → настройте Slack, email или другие уведомления

Задания для самостоятельного выполнения

  1. Создание multi-stage Docker build Оптимизируйте Dockerfile для использования multi-stage build и уменьшения размера образа.

  2. Добавление performance тестов Создайте performance тесты и добавьте их в пайплайн с отдельной стадией.

  3. Настройка blue-green deployment Реализуйте стратегию blue-green deployment для production окружения.

  4. Создание API документации Добавьте автоматическую генерацию API документации и включите ее в артефакты.

  5. Настройка мониторинга Интегрируйте мониторинг приложения с Prometheus и добавьте соответствующие проверки в пайплайн.

  6. Создание feature flags Реализуйте систему feature flags и добавьте соответствующие тесты.

  7. Настройка rollback стратегии Создайте автоматический rollback при неудачном деплое.

  8. Добавление code quality метрик Интегрируйте SonarQube или другие инструменты анализа качества кода.

Контрольные вопросы

  1. Что такое GitLab Runner и какие типы раннеров существуют?
  2. В чем разница между stages и jobs в GitLab CI/CD?
  3. Как настроить кэширование зависимостей в пайплайне?
  4. Что такое артефакты и как они используются между job’ами?
  5. Как настроить различные окружения (staging, production)?
  6. В чем преимущество Merge Request пайплайнов?
  7. Как настроить scheduled пайплайны?
  8. Что такое variables в GitLab CI/CD и как их использовать?
  9. Как настроить автоматический rollback при неудачном деплое?
  10. Какие best practices следует соблюдать при создании .gitlab-ci.yml?

Требования к отчету

Отчет по лабораторной работе должен содержать:

  1. Титульный лист
  2. Цель работы
  3. Пошаговое описание выполнения работы с приведением всех вводимых команд и их выводов
  4. Содержимое созданного .gitlab-ci.yml файла с подробными комментариями
  5. Скриншоты выполнения пайплайнов в GitLab
  6. Результаты тестирования всех стадий пайплайна
  7. Описание созданного Merge Request и его обработки
  8. Письменные ответы на контрольные вопросы
  9. Вывод, в котором необходимо кратко описать полученные знания и навыки, а также привести примеры использования GitLab CI/CD в реальных проектах
Наверх
Лаб. работа “Docker Compose: Управление многоконтейнерными приложениями”