К концу этого туториала у вас будет полностью функциональная настройка Bitbucket Pipelines, которая автоматически запускает тесты при каждом коммите. Всего за 45 минут вы настроите CI/CD пайплайн, который обнаруживает баги до попадания в продакшн, с параллельным тестированием, кешированием и стратегиями деплоя.

Что вы построите

Вы создадите production-ready пайплайн для тестирования, который:

  • Автоматически запускает юнит, интеграционные и E2E тесты при каждом пуше
  • Выполняет тесты параллельно, сокращая время сборки на 60%
  • Кеширует зависимости для ускорения сборок
  • Генерирует отчеты о покрытии тестами
  • Автоматически деплоит, когда все тесты проходят

Эта настройка используется такими компаниями, как Atlassian, Docker и тысячами команд разработки для поддержания качества кода и ускорения релизов.

Цели обучения

В этом туториале вы узнаете:

  • Как настроить bitbucket-pipelines.yml для автоматизированного тестирования
  • Как настроить параллельное выполнение тестов для более быстрой обратной связи
  • Как реализовать стратегии кеширования для оптимизации времени сборки
  • Как интегрировать отчеты о покрытии и quality gates
  • Как работать с разными окружениями (staging, production)
  • Как решать распространенные проблемы пайплайна

Расчетное время: 45-60 минут

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

Необходимое ПО

Перед началом установите:

ИнструментВерсияНазначение
Git2.0+Система контроля версий
Node.js18+Runtime для примера проекта
npm9+Управление пакетами
Docker20+Container runtime (опционально)

Установка:

# macOS
brew install git node

# Linux (Ubuntu/Debian)
apt-get install git nodejs npm

# Windows
choco install git nodejs

Требуемые знания

Вы должны быть знакомы с:

  • ✅ Базовыми рабочими процессами Git (commit, push, pull)
  • ✅ Основами командной строки
  • ✅ Базовым пониманием концепций CI/CD
  • ❌ Не требуется: Продвинутые знания Docker или Kubernetes

Требуемые ресурсы

  • Аккаунт Bitbucket (бесплатный tier подходит)
  • Репозиторий с тестами (или используйте наш пример проекта)
  • Права на запись в настройки репозитория
  • 15 минут для первого запуска пайплайна

Шаг 1: Настройка проекта и конфигурации

На этом шаге мы создадим базовый файл конфигурации пайплайна и разберем его структуру.

Создание конфигурации пайплайна

Перейдите в корень вашего репозитория и создайте файл конфигурации:

cd ваш-проект
touch bitbucket-pipelines.yml

Добавьте базовую структуру пайплайна:

# bitbucket-pipelines.yml
image: node:18

pipelines:
  default:
    - step:
        name: Build and Test
        caches:
          - node
        script:
          - npm install
          - npm test

Что это делает:

  • image: node:18 - Указывает Docker образ для среды сборки
  • caches: - node - Кеширует node_modules для ускорения последующих сборок
  • script - Команды, выполняемые последовательно

Коммит и пуш

git add bitbucket-pipelines.yml
git commit -m "Add Bitbucket Pipelines configuration"
git push origin main

Вы должны увидеть:

  • Bitbucket автоматически обнаруживает конфигурацию
  • Первый запуск пайплайна начинается в течение 30 секунд
  • Пайплайн появляется в UI Bitbucket во вкладке “Pipelines”

💡 Профессиональный совет: Включите Pipelines в Настройках репозитория → Pipelines → Настройки, если еще не включено.

Проверка настройки

Перейдите к вашему репозиторию в Bitbucket и кликните на вкладку “Pipelines”.

Ожидаемый результат:

✅ Pipeline #1 (в процессе)
   └── Build and Test (выполняется)

Контрольная точка: У вас должен быть запущен базовый пайплайн. Даже если тесты не проходят, пайплайн должен выполняться.

Шаг 2: Настройка нескольких типов тестов

Реальные проекты требуют разных типов тестов. Давайте настроим юнит-тесты, интеграционные тесты и линтинг параллельно.

Обновление конфигурации пайплайна

Измените ваш bitbucket-pipelines.yml:

image: node:18

definitions:
  caches:
    npm: ~/.npm

pipelines:
  default:
    - parallel:
      - step:
          name: Unit Tests
          caches:
            - node
            - npm
          script:
            - npm ci
            - npm run test:unit
          artifacts:
            - coverage/**

      - step:
          name: Linting
          caches:
            - node
          script:
            - npm ci
            - npm run lint

      - step:
          name: Integration Tests
          caches:
            - node
          services:
            - docker
          script:
            - npm ci
            - npm run test:integration

Что изменилось:

  • parallel: - Запускает несколько шагов одновременно (на 60% быстрее)
  • npm ci - Чистая установка, быстрее и надежнее чем npm install
  • artifacts - Сохраняет отчеты о покрытии для последующих шагов
  • services: - docker - Запускает Docker daemon для интеграционных тестов

Обновление скриптов в package.json

Убедитесь, что ваш package.json содержит тестовые скрипты:

{
  "scripts": {
    "test:unit": "jest --coverage --testPathPattern=unit",
    "test:integration": "jest --testPathPattern=integration",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  }
}

Распространенные проблемы ⚠️

Проблема: “npm run test:unit not found”

Решение: Добавьте отсутствующий скрипт в package.json или обновите команду пайплайна в соответствии с вашей реальной командой для тестов:

script:
  - npm ci
  - npm test  # Используйте вашу реальную команду для тестов

Проблема: Ошибки нехватки памяти во время тестов

Решение: Увеличьте выделение памяти:

- step:
    name: Unit Tests
    size: 2x  # Удваивает память (4GB вместо 2GB)

Проверка этого шага

Запушьте изменения и следите за пайплайном:

git add bitbucket-pipelines.yml package.json
git commit -m "Add parallel test execution"
git push

Ожидаемый результат:

✅ Pipeline #2 (в процессе)
   ├── Unit Tests (выполняется) [30s]
   ├── Linting (выполняется) [15s]
   └── Integration Tests (выполняется) [45s]

Контрольная точка: Все три тестовых шага должны выполняться одновременно, сокращая общее время выполнения.

Шаг 3: Реализация продвинутого кеширования

Кеширование значительно сокращает время сборки. Давайте реализуем многоуровневое кеширование.

Улучшенная стратегия кеширования

Обновите пайплайн с продвинутым кешированием:

image: node:18

definitions:
  caches:
    npm: ~/.npm
    cypress: ~/.cache/Cypress
    jest: .jest-cache

pipelines:
  default:
    - parallel:
      - step:
          name: Unit Tests
          caches:
            - node
            - npm
            - jest
          script:
            - npm ci --cache ~/.npm --prefer-offline
            - npm run test:unit -- --cache --cacheDirectory=.jest-cache
          artifacts:
            - coverage/**
            - test-results/**

Преимущества кеширования:

  • Первая сборка: ~120 секунд (без кеша)
  • Последующие сборки: ~35 секунд (с кешем)
  • Экономия: сборки на 70% быстрее

💡 Профессиональный совет: Кешируйте слои Docker для еще более быстрых сборок:

- step:
    name: Build Docker Image
    caches:
      - docker
    script:
      - docker build -t myapp:$BITBUCKET_COMMIT .

Проверка работы кеша

Проверьте логи пайплайна на индикаторы кеша:

Restoring caches...
✓ node: Restored successfully (142.3 MB)
✓ npm: Restored successfully (89.1 MB)

Контрольная точка: Вторая сборка должна быть на 50-70% быстрее первой.

Шаг 4: Добавление покрытия тестами и quality gates

Обеспечьте качество кода, добавив пороговые значения покрытия.

Настройка отчетов о покрытии

Добавьте конфигурацию покрытия в jest.config.js:

// jest.config.js
module.exports = {
  collectCoverage: true,
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov', 'html'],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  }
};

Обновление пайплайна с quality gates

- step:
    name: Unit Tests with Coverage
    caches:
      - node
    script:
      - npm ci
      - npm run test:unit
      - |
        if [ -f coverage/lcov.info ]; then
          echo "✅ Coverage report generated"
        else
          echo "❌ Coverage report missing"
          exit 1
        fi
    artifacts:
      - coverage/**

Что это делает:

  • Генерирует отчеты о покрытии в нескольких форматах
  • Прерывает сборку, если покрытие падает ниже 80%
  • Сохраняет артефакты покрытия для последующего просмотра

Интеграция с инструментами покрытия кода

Добавьте интеграцию с Codecov:

- step:
    name: Upload Coverage
    script:
      - pipe: codecov/codecov-upload:1.3.2
        variables:
          CODECOV_TOKEN: $CODECOV_TOKEN

Ожидаемый вывод:

✅ Coverage: 87.3% (+2.1%)
✅ All thresholds passed
✅ Uploaded to Codecov

Контрольная точка: Сборка должна прерываться, если покрытие падает ниже 80%.

Шаг 5: Пайплайны для разных окружений

Настройте различное поведение для веток и окружений.

Пайплайны для конкретных веток

pipelines:
  default:
    - step:
        name: Quick Tests
        script:
          - npm ci
          - npm run test:unit

  branches:
    main:
      - step:
          name: Full Test Suite
          script:
            - npm ci
            - npm run test:unit
            - npm run test:integration
            - npm run test:e2e
      - step:
          name: Deploy to Staging
          deployment: staging
          script:
            - npm run deploy:staging

    develop:
      - step:
          name: Development Tests
          script:
            - npm ci
            - npm run test:unit
            - npm run lint

  pull-requests:
    '**':
      - step:
          name: PR Validation
          script:
            - npm ci
            - npm run test:unit
            - npm run lint

Поведение пайплайна:

  • Feature ветки: Только быстрые юнит-тесты (2 минуты)
  • Pull requests: Юнит-тесты + линтинг (3 минуты)
  • Ветка develop: Тесты для разработки (4 минуты)
  • Ветка main: Полный набор + деплой (8 минут)

Переменные окружения

Добавьте секреты в Настройках репозитория → Pipelines → Переменные репозитория:

- step:
    name: Integration Tests
    script:
      - export DATABASE_URL=$DATABASE_URL_TEST
      - export API_KEY=$API_KEY_TEST
      - npm run test:integration

💡 Профессиональный совет: Используйте переменные деплоймента для конфигураций конкретных окружений:

- step:
    name: Deploy to Production
    deployment: production
    script:
      - echo "Deploying with API_KEY: ${API_KEY}"
      - npm run deploy

Контрольная точка: Разные ветки должны запускать разные конфигурации пайплайна.

Шаг 6: Управление деплоем

Автоматический деплой, когда тесты проходят.

Условный деплой

- step:
    name: Deploy to Production
    deployment: production
    trigger: manual
    script:
      - pipe: atlassian/aws-s3-deploy:1.1.0
        variables:
          AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
          AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
          AWS_DEFAULT_REGION: 'us-east-1'
          S3_BUCKET: 'my-production-bucket'
          LOCAL_PATH: 'dist'

Опции деплоя:

  • trigger: manual - Требует ручного подтверждения
  • trigger: automatic - Деплоит автоматически, когда тесты проходят

Деплой с откатом

- step:
    name: Deploy with Rollback
    script:
      - export PREVIOUS_VERSION=$(git describe --tags --abbrev=0)
      - npm run deploy
      - npm run healthcheck || (echo "Health check failed, rolling back..." && git checkout $PREVIOUS_VERSION && npm run deploy && exit 1)

Контрольная точка: Деплой должен происходить только после прохождения всех тестов.

Тестирование вашей реализации

Теперь давайте убедимся, что все работает корректно.

Ручное тестирование

  1. Тест-кейс 1: Пуш в feature ветку

    Создайте и запушьте feature ветку:

    git checkout -b feature/test-pipeline
    git push origin feature/test-pipeline
    

    Ожидаемый результат:

    ✅ Quick Tests passed (2m 15s)
    
  2. Тест-кейс 2: Pull Request

    Создайте PR в UI Bitbucket.

    Ожидаемый результат:

    ✅ PR Validation passed (3m 30s)
    ├── Unit Tests ✅
    └── Linting ✅
    
  3. Тест-кейс 3: Деплой в main ветку

    Мердж в main:

    git checkout main
    git merge feature/test-pipeline
    git push origin main
    

    Ожидаемый результат:

    ✅ Full Test Suite passed (7m 45s)
    ⏸️  Deploy to Staging (доступен ручной триггер)
    

Автоматизированный скрипт проверки работоспособности

Создайте скрипт валидации:

#!/bin/bash
# validate-pipeline.sh

echo "🔍 Валидация конфигурации Bitbucket Pipeline..."

# Проверка существования файла пайплайна
if [ ! -f "bitbucket-pipelines.yml" ]; then
    echo "❌ bitbucket-pipelines.yml не найден"
    exit 1
fi
echo "✅ Конфигурация пайплайна существует"

# Валидация синтаксиса YAML
if command -v yamllint &> /dev/null; then
    yamllint bitbucket-pipelines.yml || exit 1
    echo "✅ Синтаксис YAML валиден"
fi

# Проверка необходимых скриптов в package.json
required_scripts=("test:unit" "lint")
for script in "${required_scripts[@]}"; do
    if grep -q "\"$script\"" package.json; then
        echo "✅ Скрипт '$script' найден"
    else
        echo "❌ Скрипт '$script' отсутствует"
        exit 1
    fi
done

echo "✅ Все валидации пройдены! 🎉"

Запустите его:

chmod +x validate-pipeline.sh
./validate-pipeline.sh

Чеклист валидации

  • Пайплайн запускается при каждом пуше
  • Параллельные шаги выполняются одновременно
  • Кеширование сокращает время последующих сборок
  • Отчеты о покрытии генерируются
  • Поведение для конкретных веток работает
  • Ручной деплой требует подтверждения
  • Неуспешные тесты блокируют деплой

Решение проблем

Проблема 1: Пайплайн не запускается

Симптомы:

  • Пайплайн не выполняется после пуша
  • Вкладка “Pipelines” не показывает историю

Возможные причины:

  1. Pipelines не включены в настройках репозитория
  2. Неверный синтаксис YAML в файле конфигурации

Решение:

# Валидация синтаксиса YAML локально
docker run --rm -v $(pwd):/work mikefarah/yq eval bitbucket-pipelines.yml

# Включите pipelines в настройках репозитория
# Перейдите: Настройки репозитория → Pipelines → Настройки
# Включите "Enable Pipelines"

Как проверить, что исправлено:

git commit --allow-empty -m "Trigger pipeline"
git push
# Проверьте вкладку Pipelines в течение 30 секунд

Проблема 2: Ошибки нехватки памяти

Сообщение об ошибке:

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

Что это значит: Ваши тесты потребляют больше, чем стандартный лимит памяти в 2GB.

Быстрое решение:

- step:
    name: Memory-Intensive Tests
    size: 2x  # Увеличивает до 4GB RAM
    script:
      - npm ci
      - NODE_OPTIONS="--max-old-space-size=3072" npm test

Детальное решение:

  1. Профилируйте ваши тесты для поиска утечек памяти:

    node --inspect-brk node_modules/.bin/jest --runInBand
    
  2. Оптимизируйте настройку тестов:

    // jest.config.js
    module.exports = {
      maxWorkers: 2,  // Ограничить параллельные воркеры
      clearMocks: true,
      resetMocks: true,
    };
    

Проблема 3: Медленное время сборки

Если сборки занимают более 5 минут:

  1. Включите параллельное выполнение:

    - parallel:
      - step:
          name: Fast Tests
      - step:
          name: More Tests
    
  2. Оптимизируйте кеширование:

    definitions:
      caches:
        custom-cache: path/to/cache
    
  3. Используйте npm ci вместо npm install:

    npm ci  # На 40% быстрее чем npm install
    
  4. Мониторьте метрики сборки:

    # Добавьте в пайплайн
    - time npm ci
    - time npm test
    

Проблема 4: Сбои подключения к Docker сервису

Симптомы:

  • Интеграционные тесты падают с “Cannot connect to Docker daemon”

Решение:

- step:
    name: Integration Tests
    services:
      - docker
    script:
      - sleep 10  # Дождаться запуска Docker
      - docker ps  # Проверить, что Docker запущен
      - npm run test:integration

Все еще есть проблемы?

Следующие шаги

Поздравляем! Вы успешно настроили автоматизированное тестирование в Bitbucket Pipelines. 🎉

Что вы построили

Теперь у вас есть:

  • ✅ Автоматизированное тестирование при каждом коммите
  • ✅ Параллельное выполнение тестов (сборки на 60% быстрее)
  • ✅ Многоуровневая стратегия кеширования
  • ✅ Отчеты о покрытии с quality gates
  • ✅ Поведение пайплайна для конкретных веток
  • ✅ Контроль ручного деплоя
  • ✅ Production-ready CI/CD пайплайн

Повысьте свои навыки

Готовы к большему? Попробуйте эти улучшения:

Простые улучшения (30 мин каждое)

  1. Добавить уведомления в Slack

    - step:
        name: Notify on Failure
        script:
          - pipe: atlassian/slack-notify:2.1.0
            variables:
              WEBHOOK_URL: $SLACK_WEBHOOK
    
  2. Добавить сканирование безопасности

    - step:
        name: Security Audit
        script:
          - npm audit --audit-level=moderate
    

Промежуточные улучшения (1-2 часа каждое)

  1. Добавить тестирование производительности

    • Интегрировать Lighthouse CI
    • Установить бюджеты производительности
    • Прерывать сборки при регрессии
  2. Реализовать Blue-Green деплой

    • Деплой в staging окружение
    • Запуск smoke tests
    • Переключение на production

Продвинутые улучшения (3+ часа)

  1. Мультиоблачный деплой
    • Деплой в AWS, Azure, GCP одновременно
    • Географическая маршрутизация
    • Стратегии failover

Связанные туториалы

Продолжайте обучение:

Поделитесь результатами

Построили впечатляющий пайплайн? Поделитесь им:

  • Твитните вашу настройку с #BitbucketPipelines
  • Напишите о вашем опыте в блоге
  • Внесите улучшения в open-source проекты

Заключение

Что вы достигли

В этом туториале вы:

  1. ✅ Создали полную конфигурацию Bitbucket Pipelines
  2. ✅ Реализовали параллельное выполнение тестов для более быстрой обратной связи
  3. ✅ Настроили многоуровневое кеширование для оптимизации времени сборки
  4. ✅ Добавили отчеты о покрытии и quality gates
  5. ✅ Настроили поведение пайплайна для конкретных веток
  6. ✅ Настроили условный деплой с ручным контролем

Ключевые выводы

  • Параллельное выполнение может сократить время сборки на 50-70%
  • Стратегии кеширования критически важны для быстрых циклов обратной связи
  • Quality gates предотвращают попадание низкокачественного кода в продакшн
  • Конфигурации для конкретных веток балансируют между скоростью и тщательностью
  • Ручные триггеры деплоя обеспечивают безопасность для production релизов

Продолжайте обучение

Это только начало! Изучите:


Вопросы или отзывы? Поделитесь вашей настройкой пайплайна в комментариях ниже!

Это было полезно? Поделитесь с вашей командой для улучшения рабочего процесса CI/CD!