# CICD

Информация по непрерывной интеграции (continuous integration) и непрерывному развертыванию (continuous delivery или continuous deployment) программного обеспечения в процессе разработки

# Как реализовать запуск задач в .gitlab-ci.yml с различной периодичностью выполнения

1. Создать 2 планировщика (sheduler) 
    1. Меню: **Build** - **Pipeline Schedules** или **CI/CD** - **Schedules** (в зависимости от версии gitlab)  
        [![image.png](https://lavelin.ru/uploads/images/gallery/2024-04/scaled-1680-/image.png)](https://lavelin.ru/uploads/images/gallery/2024-04/image.png)
    2.  Нажать на кнопку "**New schedule**"  
        [![image.png](https://lavelin.ru/uploads/images/gallery/2024-04/scaled-1680-/Skbimage.png)](https://lavelin.ru/uploads/images/gallery/2024-04/Skbimage.png)
    3. Указать в разделе перменных переменную для одного расписания  
        
        [![image.png](https://lavelin.ru/uploads/images/gallery/2024-04/scaled-1680-/4CIimage.png)](https://lavelin.ru/uploads/images/gallery/2024-04/4CIimage.png)
    4. Аналогично добавить второй планировщик и указать для него свою переменную
2. В файле .gitlab-ci.yml добавить правила выполнения для каждой переменной  
    
    [![image.png](https://lavelin.ru/uploads/images/gallery/2024-04/scaled-1680-/687image.png)](https://lavelin.ru/uploads/images/gallery/2024-04/687image.png)
3. Пример файла .gitlab-ci.yml
    
    ```yaml
    stages:
      - test
    
    .template_short:
      stage: test
      rules:
        - if: '$CI_PIPELINE_SOURCE == "schedule" && $interval == "short"'
      before_script:
        - echo "This is the before_script of the .template_short job"
    
    .template_long:
      stage: test
      rules:
        - if: '$CI_PIPELINE_SOURCE == "schedule" && $interval == "long"'
      before_script:
        - echo "This is the before_script of the .template_long job"
    
    test:daily:
      tags: 
        - my_tag
      extends: .template_short
      script:
        - echo "Run on $interval schedule"
    
    test:weekly:
      tags: 
        - my_tag
      extends: .template_long
      script:
        - echo "Run on $interval schedule"
    
    test:any:
      tags: 
        - my_tag
      script:
        - echo "Run on push and schedule"
    
    ```

# Основные шаблоны для работы с файлами и каталогами GitLab CI/CD

GitLab CI/CD позво043bяет отслеживать изменения файлов и каталогов с помощью **glob patterns**. Они используются в `changes`, `artifacts`, `cache` и других разделах `.gitlab-ci.yml`. Эта статья разберет основные шаблоны и их поведение.

## 🔹 Основные glob patterns

<table id="bkmrk-%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-path"><tbody><tr><th>Шаблон</th><th>Описание</th></tr><tr><td><code>path&#47;&#42;</code></td><td>Отслеживает **только файлы и каталоги первого уровня** в <code>path</code>, **без вложенных файлов**.</td></tr><tr><td><code>path&#47;&#42;&#42;&#47;&#42;</code></td><td>Отслеживает **все файлы и папки** внутри <code>path</code>, включая **вложенные файлы на всех уровнях**.</td></tr><tr><td><code>path&#47;&#42;&#47;&#42;</code></td><td>Отслеживает файлы и папки **только второго уровня** внутри <code>path</code>.</td></tr><tr><td><code>path&#47;&#42;&#47;&#42;&#42;</code></td><td>Отслеживает **файлы на первом уровне** + **все вложенные файлы** во втором уровне и глубже.</td></tr><tr><td><code>path&#47;&#42;&#42;</code></td><td>Аналог <code>path&#47;&#42;&#42;&#47;&#42;</code>, отслеживает всё, включая подпапки и файлы.</td></tr><tr><td><code>path&#47;&#42;&#42;&#47;file&#46;txt</code></td><td>Отслеживает **конкретный файл**, независимо от его глубины.</td></tr></tbody></table>

## 🔹 Вывод

- Используйте `/**/*`, если хотите **отслеживать все файлы и папки**.
- Используйте `/*/*`, если хотите **только второй уровень вложенности**.
- Используйте `path/**/file.txt`, если хотите **отслеживать конкретные файлы на всех уровнях**.

# Рекомендуемый порядок расположения блоков внутри job в .gitlab-ci.yml?

В GitLab CI/CD **есть рекомендованный порядок**, который улучшает **читаемость и поддержку pipeline**.

---

## **📌 Стандартный порядок блоков внутри `job`**

```yaml
job_name:
  extends: .some_template  # 1️⃣ Наследование (если есть)
  stage: build             # 2️⃣ Определение этапа
  tags:                    # 3️⃣ Теги для раннера (если нужны)
    - docker
  needs:                   # 4️⃣ Зависимости от других job'ов
    - previous_job
  variables:               # 5️⃣ Локальные переменные для job
    SOME_VAR: "value"
  before_script:           # 6️⃣ Подготовка окружения перед `script`
    - echo "Setting up environment..."
  script:                  # 7️⃣ Основной код
    - echo "Executing job..."
  after_script:            # 8️⃣ Завершающие действия (если нужны)
    - echo "Cleanup after job"
  artifacts:               # 9️⃣ Артефакты (если нужны)
    paths:
      - my_output/
    expire_in: 1 hour
  rules:                   # 🔟 Условия выполнения job
    - if: '$CI_COMMIT_BRANCH == "main"'
  allow_failure: false      # 1️⃣1️⃣ Позволять ли падение job
  retry: 2                 # 1️⃣2️⃣ Число повторных попыток
  timeout: 30m             # 1️⃣3️⃣ Лимит времени выполнения

```

---

## **📌 Разбор структуры**

<table id="bkmrk-%D0%A1%D0%B5%D0%BA%D1%86%D0%B8%D1%8F-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-exte"><thead><tr><th>**Секция**</th><th>**Описание**</th></tr></thead><tbody><tr><td><code>extends&#58;</code></td><td>Наследование от шаблонного <code>job</code> (если есть).</td></tr><tr><td><code>stage&#58;</code></td><td>Назначение <code>job</code> к определенному этапу.</td></tr><tr><td><code>tags&#58;</code></td><td>Указывает, на каких раннерах будет выполняться <code>job</code>.</td></tr><tr><td><code>needs&#58;</code></td><td>Указывает зависимости от других <code>job</code> (если надо запустить <code>job</code> только после выполнения других).</td></tr><tr><td><code>variables&#58;</code></td><td>Определяет переменные, видимые только внутри <code>job</code>.</td></tr><tr><td><code>before&#95;script&#58;</code></td><td>Выполняется **один раз перед <code>script&#58;</code>** (установка окружения, логирование, авторизация и т. д.).</td></tr><tr><td><code>script&#58;</code></td><td>Основной код <code>job</code>, выполняется **после <code>before&#95;script&#58;</code>**.</td></tr><tr><td><code>after&#95;script&#58;</code></td><td>Выполняется **после <code>script&#58;</code>**, даже если <code>script&#58;</code> упал. Подходит для логов, очистки файлов.</td></tr><tr><td><code>artifacts&#58;</code></td><td>Определяет файлы, которые сохраняются после завершения <code>job</code>.</td></tr><tr><td><code>rules&#58;</code></td><td>Условия выполнения <code>job</code> (например, только в <code>main</code>, только при изменениях в <code>src&#47;</code>).</td></tr><tr><td><code>allow&#95;failure&#58;</code></td><td>Разрешает <code>job</code> завершаться с ошибкой (<code>true</code> → ошибки не остановят pipeline).</td></tr><tr><td><code>retry&#58;</code></td><td>Число повторных попыток при падении <code>job</code>.</td></tr><tr><td><code>timeout&#58;</code></td><td>Лимит времени выполнения <code>job</code> (например, <code>30m</code>).</td></tr></tbody></table>

---

## **📌 Пример 1: Минимальная конфигурация `job`**

Если у вас простой `job`, можно оставить только **ключевые секции**:

```yaml
build_job:
  stage: build
  script:
    - echo "Building the project..."

```

✅ **Минимально необходимый `job`**: `stage:` + `script:`.

---

## **📌 Пример 2: Расширенная конфигурация `job`**

Если `job` сложный, используем **все ключевые блоки**:

```yaml
deploy_job:
  extends: .deploy_template
  stage: deploy
  tags:
    - production-runner
  needs:
    - build_job
  variables:
    DEPLOY_ENV: "production"
  before_script:
    - echo "Подготовка к деплою..."
  script:
    - echo "Выполняем деплой..."
  after_script:
    - echo "Очистка после деплоя..."
  artifacts:
    paths:
      - deploy_logs/
    expire_in: 1 day
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  allow_failure: false
  retry: 2
  timeout: 20m

```

✅ Этот `job` **должен выполниться ТОЛЬКО в `main`**.  
✅ **Если `job` упадет, он попробует перезапуститься дважды** (`retry: 2`).  
✅ **`before_script:` подготавливает окружение, а `after_script:` выполняет очистку.**

---

## **📌 Итог**

### **🚀 Оптимальный порядок блоков в `job`:**

1️⃣ `extends:` (если используется)  
2️⃣ `stage:`  
3️⃣ `tags:` (если есть)  
4️⃣ `needs:` (если job зависит от других job'ов)  
5️⃣ `variables:` (локальные переменные)  
6️⃣ `before_script:` (подготовка окружения)  
7️⃣ `script:` (основная логика job)  
8️⃣ `after_script:` (очистка, логи)  
9️⃣ `artifacts:` (если нужны)  
🔟 `rules:` (условия выполнения)  
1️⃣1️⃣ `allow_failure:` (можно ли игнорировать ошибки)  
1️⃣2️⃣ `retry:` (количество повторных попыток)  
1️⃣3️⃣ `timeout:` (ограничение времени выполнения)