Как стать автором
Обновить

Комментарии 14

Если честно, сама я такое не писала, но если чисто в теории, то в том же файле можно написать этап test.

Для GitLab CI (.gitlab-ci.yml):

stages:
  - build
  - test  # ← Новый этап
  - deploy

build:
  stage: build
  script:
    - docker build -t myapp .
    # Сохраняем образ для следующих этапов
    - docker save myapp > myapp.tar
  artifacts:
    paths:
      - myapp.tar

test:  # ← Вот этот новый блок
  stage: test
  script:
    - docker load < myapp.tar
    # Запускаем тесты внутри контейнера
    - docker run --rm myapp npm test  # Для Node.js
    # Или для других языков:
    # - docker run --rm myapp pytest    # Python
    # - docker run --rm myapp mvn test # Java

deploy:
  stage: deploy
  script:
    - ssh user@vm_ip "docker load < myapp.tar"
    - ssh user@vm_ip "docker run -d -p 3000:3000 --name myapp myapp"
  only:
    - master

Для GitHub Actions (.github/workflows/ci.yml):

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Build and test
      run: |
        docker build -t myapp .
        docker run --rm myapp npm test  # Тесты запускаются здесь
        
    - name: Prepare for deploy
      run: docker save myapp > myapp.tar
      
    - name: Upload artifact
      uses: actions/upload-artifact@v2
      with:
        name: app-image
        path: myapp.tar

  deploy:
    needs: build-and-test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/download-artifact@v2
      with:
        name: app-image
        
    - name: Deploy
      run: |
        scp myapp.tar user@vm_ip:/tmp/
        ssh user@vm_ip "docker load < /tmp/myapp.tar"
        ssh user@vm_ip "docker run -d -p 3000:3000 --name myapp myapp"
  1. Сначала собираем образ

  2. Затем тестируем:

    • Загружаем собранный в билде образ из временного файла myapp.tar

    • Запускаем docker run --rm с командой тестов

    • Если тесты упадут - пайплайн остановится

  3. Деплоим только если тесты прошли (все тот же образ myapp.tar)

Если использовать чуть более специализированные тесты, то:

Пишем что-то в docker-compose.test.yml:

version: '3'
services:
  app:
    image: myapp
    command: npm run test:integration  # Ваша команда
    depends_on:
      - postgres
  postgres:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: "test"

В пайплайне будет выглядеть так:

test_integration:
  script:
    - docker-compose -f docker-compose.test.yml up --abort-on-container-exit

Параллельный запуск тестов

stages:
  - build
  - test

unit_test:
  stage: test
  script: docker run --rm myapp npm test

integration_test:
  stage: test
  script: docker-compose -f docker-compose.test.yml up --abort-on-container-exit

e2e_test:
  stage: test
  script: docker run --rm myapp npm run test:e2e

Даю 100%, что вы не сами это написали, а тупо скопировали ответ ИИ.

Я призналась еще в начале, что сама не писала test, но насколько я предполагаю, ответ ии плюс минус верный, учитывая мой небольшой опыт

Описанный флоу выглядит вывернутым наизнанку, потому что в самом пайплайне можно сделать билд, затем тест, а уже работающее потом упаковать в образ и задеплоить. Но если хочется контейнеризовать, а потом тестировать, то в билде собираем образ, пушим в реестр (Github Packages/Gitlab container registry/Dockerhub), потом оттуда забираем образ для стейджа test, указав его явно в файле пайплайна:

test:
  stage: test
  image: dockeraccount/myapp:test_version_tag
  script: |
    pytest #example

Тогда и логи, и репорты прокинуть можно без лишних приседаний, и не нужно писать скриптовую обёртку, чтобы запустить контейнер с нужными параметрами, войти в него, а только потом запускать команды теста. Если контейнер нужен как что-то сбоку для тестов (например, СУБД), то в .gitlab-ci.yml, например, есть секция services, где также можно указать нужный кастомный image из первого шага, а тесты запускать в самом контейнере джоба.

Если машина не ходит сама на гитхаб по какому-то триггеру, а вы всегда подключаетесь к ней чтобы сделать git pull, то сделайте ssg agent и ssh forwarding. Будет безопаснее, ключ не будет храниться на машине. Если ещё добавите интеграцию на какой-нибудь 1password для использования его в качестве агента, то вообще нигде не будете хранить ключи, а авторизовывать открытие туннеля будете отпечатком пальца (или пин-кодом, если нет ридера). Дофига секьюрнее и удобнее.

Скорее всего вы правы, я в этом деле еще профан. А можете чуть более конкретно описать, как это сделать? Или может знаете пару хороших статей на этот счет?

как вариант

Для каждого repo свой воркер, а VPS с докером одна. Нужно разные репо деплоить как отдельные контейнеры на одном VPS. В этом случае нужен общий воркер для всех repo, а это делается только для "организации" в GitHub.

Нет просто разворачиваете воркер на своём VPS, изучите статью ссылку я приложил

Вы не сможете добавить один и то же раннер (VPS) для разных проектов. Нужно будет два ранера ставить для двух проектов.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации