# Рекомендуемый порядок расположения блоков внутри 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>`extends:`</td><td>Наследование от шаблонного `job` (если есть).</td></tr><tr><td>`stage:`</td><td>Назначение `job` к определенному этапу.</td></tr><tr><td>`tags:`</td><td>Указывает, на каких раннерах будет выполняться `job`.</td></tr><tr><td>`needs:`</td><td>Указывает зависимости от других `job` (если надо запустить `job` только после выполнения других).</td></tr><tr><td>`variables:`</td><td>Определяет переменные, видимые только внутри `job`.</td></tr><tr><td>`before_script:`</td><td>Выполняется **один раз перед `script:`** (установка окружения, логирование, авторизация и т. д.).</td></tr><tr><td>`script:`</td><td>Основной код `job`, выполняется **после `before_script:`**.</td></tr><tr><td>`after_script:`</td><td>Выполняется **после `script:`**, даже если `script:` упал. Подходит для логов, очистки файлов.</td></tr><tr><td>`artifacts:`</td><td>Определяет файлы, которые сохраняются после завершения `job`.</td></tr><tr><td>`rules:`</td><td>Условия выполнения `job` (например, только в `main`, только при изменениях в `src/`).</td></tr><tr><td>`allow_failure:`</td><td>Разрешает `job` завершаться с ошибкой (`true` → ошибки не остановят pipeline).</td></tr><tr><td>`retry:`</td><td>Число повторных попыток при падении `job`.</td></tr><tr><td>`timeout:`</td><td>Лимит времени выполнения `job` (например, `30m`).</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:` (ограничение времени выполнения)