Skip to content

Latest commit

 

History

History
957 lines (839 loc) · 48.2 KB

DOCS.ru.md

File metadata and controls

957 lines (839 loc) · 48.2 KB

Деплойер: документация по версии 1.4.X

Актуальная документация доступна через deployer docs.

Основной формат конфигурации Деплойера - JSON, но он также поддерживает YAML и TOML. Вы можете инициализировать проект с флагом -F и указать предпочтительный формат, либо же отредактировать глобальную конфигурацию (которая пока что останется в виде JSON), указав поле preferred_conf_format (yaml/toml/json или их скрытые варианты), либо же попросить Деплойера сохранить конфигурацию в другом формате через команду deployer edit project. Все примеры в документации ниже написаны на JSON.

Описание принципов работы

Деплойер, по своей сути, - локальный CI/CD. Иными словами, менеджер bash-команд.

Как правило, Деплойер запускается в отдельной папке, чтобы сохранять кэш и при этом держать папку с кодом чистой. Однако вы можете указать как любую папку, так и папку с кодом; если у вас уже есть кэши, вы можете их копировать из исходной папки, делать на них симлинки или полностью их игнорировать и выполнять Пайплайны с нуля.

Описание основных сущностей

1. Действие - Action

Действие - это основная сущность Деплойера. На Действиях в составе Пайплайнов строятся процессы сборки, установки и развёртывания. Однако само по себе Действие быть назначенным проекту не может, для этого и нужны Пайплайны (см. ниже).

В составе Пайплайнов или в Реестре Действий Деплойера действие выглядит как конструкция:

{
  "title": "UPX Compress",
  "desc": "Compress the binary file with UPX.",
  "info": "upx-compress@0.1.0",
  "tags": [
    "upx"
  ],
  "action": {
    "type": "post_build",
    "supported_langs": [
      "any"
    ],
    "commands": [
      {
        "bash_c": "upx <artifact>",
        "placeholders": [
          "<artifact>"
        ],
        "ignore_fails": false,
        "show_success_output": false,
        "show_bash_c": false,
        "only_when_fresh": false
      }
    ]
  },
  "requirements": [
    {
      "type": "exists_any",
      "paths": [
        "/usr/bin/upx",
        "~/.local/bin/upx"
      ]
    }
  ]
}

В составе Реестров каждое Действие и каждый Пайплайн являются значениями в словаре с ключом info (например, "upx-compress@0.1.0": { ... }). Таким образом их можно быстро редактировать, выводить на экран содержимое, добавлять в Пайплайны и проекты.

Для каждого Действия в составе Пайплайна можно назначить список требований requirements. Они будут проверяться перед каждым запуском Пайплайнов, и если хотя бы одно требование не будет удовлетворено, Пайплайн не будет выполнен. Требование можно задать тремя способами:

[
  {
    // если один из этих путей будет найден, требование будет считаться удовлетворённым
    "type": "exists_any",
    "paths": [
      "/usr/bin/upx",
      "~/.local/bin/upx"
    ]
  },
  {
    // если данный путь существует, требование считается удовлетворённым
    "type": "exists",
    "path": "/usr/bin/mold"
  },
  {
    // если данная проверка будет пройдена, требование будет считаться удовлетворённым (подробности см. ниже - Действие `Check`)
    "type": "check_success",
    "command": {
      "bash_c": "/usr/bin/python -V",
      "ignore_fails": true,
      "show_success_output": false,
      "show_bash_c": false,
      "only_when_fresh": false
    },
    "success_when_found": "Python 3."
  },
  {
    // если данный удалённый хост существует в Реестре, доступен, и его версия Деплойера идентична версии запущенного Деплойера,
    // требование будет считаться удовлетворённым
    "type": "remote_accessible_and_ready",
    "remote_host_name": "short-name"
  }
]

Существует 3 категории основных Действий и 9 дополнительных видов Действий:

  1. Действия сборки (pre_build, build, post_build и test)
  2. Действия установки (pack, deliver, install)
  3. Действия развёртывания (configure_deploy, deploy, post_deploy)
  4. Действие наблюдения observe
  5. Действие прерывания interrupt
  6. Действие с кастомной командой custom
  7. Действие проверки вывода кастомной команды check
  8. Действия добавления контента в хранилище Деплойера add_to_storage и использования этого контента use_from_storage
  9. Действие применения патча patch
  10. Действия синхронизации папок сборки - с текущего хоста на удалённый sync_to_remote и наоборот sync_from_remote

Основополагающим является концепт кастомной команды - команды для оболочки терминала. Действия custom, observe и три основные категории Действий содержат внутри одну или больше кастомных команд.

1.1. Кастомная команда

Описание команды для Деплойера выглядит следующим образом:

{
  "bash_c": "upx <artifact>",
  "placeholders": [
    "<artifact>"
  ],
  "ignore_fails": false,
  "show_success_output": false,
  "show_bash_c": false,
  "only_when_fresh": false,
  "remote_exec": []
}
  • bash_c содержит текст команды, которая будет выполняться в терминале
  • placeholders содержит список плейсхолдеров, которые можно будет заменять на переменные и артефакты проекта, чтобы выполнять с ними необходимые действия
  • ignore_fails говорит Деплойеру, нужно ли квалифицировать статус выхода процесса, не равный нулю, как нормальное поведение команды, или нет; если нет, то Деплойер прервёт выполнение Пайплайна и выйдет со статусом 1
  • show_success_output говорит Деплойеру, нужно ли печатать вывод команды всегда (в т.ч. когда статус выхода процесса - 0), или же нужно печатать только при ошибке
  • show_bash_c говорит Деплойеру, нужно ли печатать на экране полный текст команды; это может быть полезным, когда команда содержит уязвимые переменные
  • only_when_fresh говорит Деплойеру, что это действие нужно выполнять только при свежей сборке (либо при первой сборке, либо при явном указании пересобрать с нуля при помощи опции -f)
  • remote_exec содержит список коротких имён хостов, на которых необходимо будет выполнить эту команду

Когда команда специализируется для конкретного проекта, она обрастает дополнительным свойством - replacements:

{
  "bash_c": "upx <artifact>",
  "placeholders": [
    "<artifact>"
  ],
  "replacements": [
    {
      "group": [
        {
          "from": "<artifact>",
          "to": {
            "title": "target/release/deployer",
            "is_secret": false,
            "value": {
              "type": "plain",
              "value": "target/release/deployer"
            }
          }
        }
      ]
    }
  ],
  "ignore_fails": false,
  "show_success_output": false,
  "show_bash_c": false,
  "only_when_fresh": false
}

replacements содержит список замен плейсхолдеров в команде на указанные артефакты или переменные (см. п.3). Следует заметить, что одна и та же команда может выполняться несколько раз для разных наборов переменных, даже если указана в Действии один раз:

{
  "bash_c": "upx <artifact>",
  "placeholders": [
    "<artifact>"
  ],
  "replacements": [
    {
      "group": [
        {
          "from": "<artifact>",
          "to": {
            "title": "target/release/deployer",
            "is_secret": false,
            "value": {
              "type": "plain",
              "value": "target/release/deployer"
            }
          }
        }
      ]
    },
    {
      "group": [
        {
          "from": "<artifact>",
          "to": {
            "title": "target/release/another",
            "is_secret": false,
            "value": {
              "type": "plain",
              "value": "target/release/another"
            }
          }
        }
      ]
    }
  ],
  "ignore_fails": false,
  "show_success_output": false,
  "show_bash_c": false,
  "only_when_fresh": false
}

В указанном примере используется только один плейсхолдер <artifact>, но их может быть несколько, в т.ч. - различные опции для выполнения команды.

Соответственно, если вы хотите просто выполнять команды, которые нельзя отнести к одному из трёх основных видов Действий, следует использовать Действие типа custom:

{
  "title": "List all files and folders",
  "desc": "",
  "info": "ls@0.1.0",
  "tags": [],
  "action": {
    "type": "custom",
    "bash_c": "ls",
    "ignore_fails": false,
    "show_success_output": true,
    "show_bash_c": true,
    "only_when_fresh": false
  }
}

1.2. Действия сборки - pre_build, build и post_build

Для Действий сборки является специфичной специализация на языках программирования: в зависимости от того, соответствует ли набор языков, используемых в проекте, тому набору, который указан в действиях по сборке, Деплойер будет предупреждать вас об использовании несовместимых с проектом Действий.

Note

Специализации работают только при назначении Действий или Пайплайнов из TUI. Если вручную отредактировать конфигурацию, добавив несовместимый Пайплайн, никаких предупреждений Деплойер не выдаст. Это отражает нестрогий и рекомендательный характер таких предупреждений, в отличие от требований requirements.

В вышеуказанном примере мы видим действие, которое должно выполняться после сборки:

{
  "type": "post_build",
  "supported_langs": [
    "any"
  ],
  "commands": [
    {
      "bash_c": "upx <artifact>",
      "placeholders": [
        "<artifact>"
      ],
      "ignore_fails": false,
      "show_success_output": false,
      "show_bash_c": false,
      "only_when_fresh": false
    }
  ]
}

1.3. Действия установки - pack, deliver и install

Для этой группы Действий ключевым фактором специализации является целевой объект установки - таргет (цель). Если характеристики таргета проекта - аппаратная или программная платформа - не соответствуют характеристикам Действия установки, будет выдано предупреждение.

С удовольствием заметим, что UPX скорее относится к Действию упаковки, нежели к Действию после сборки:

{
  "title": "UPX Pack",
  "desc": "Pack the binary by UPX.",
  "info": "upx-pack@0.1.0",
  "tags": [
    "upx"
  ],
  "action": {
    "type": "pack",
    "target": {
      "arch": "x86_64",
      "os": "linux",
      "os_derivative": "any",
      "os_version": {
        "type": "no"
      }
    },
    "commands": [
      {
        "bash_c": "upx <af>",
        "placeholders": [
          "<af>"
        ],
        "ignore_fails": false,
        "show_success_output": false,
        "show_bash_c": false,
        "only_when_fresh": false
      }
    ]
  }
}
  • arch - это строковое обозначение архитектуры аппаратного обеспечения таргета
  • os - это строковое обозначение операционнной системы (android|ios|linux|windows|macos или другое)
  • os_derivative - это дополнительное описание операционной системы или программной платформы
  • os_version - это версия операционной системы или программной платформы

Если os_derivative отсутствует, рекомендуется писать any.

1.4. Действия развёртывания - configure_deploy, deploy, post_deploy

Для этой группы Действий ключевым фактором специализации является тулкит для развёртывания - Docker, Docker Compose, Podman, k8s или иной инструментарий контейнеризации или виртуализации. Если в проекте будет указан не тот тулкит, Деплойер выдаст предупреждение.

Приведём пример с Docker Compose:

{
  "title": "Build Docker Compose Image",
  "desc": "Build Docker image with Docker Compose",
  "info": "docker-compose-build@0.1.0",
  "tags": [
    "docker",
    "compose"
  ],
  "action": {
    "type": "configure_deploy",
    "deploy_toolkit": "docker-compose",
    "commands": [
      {
        "bash_c": "docker compose build",
        "ignore_fails": false,
        "show_success_output": false,
        "show_bash_c": true,
        "only_when_fresh": false
      }
    ]
  }
}

1.5. Действия добавления контента add_to_storage, использования контента use_from_storage и применения патча patch

Часто проекты могут быть достаточно шаблонными, чтобы одни и те же файлы копировались между проектами, но не изменялись и требовались только при сборке или развёртывании. Такие файлы могут быть расположены в специальной папке с сохранением относительных путей и добавлены в хранилище Деплойера:

deployer new content

Тогда для проектов, которые должны использовать эти файлы, можно добавить в Пайплайн сборки новое Действие - use_from_storage:

{
  "title": "Sync content",
  "desc": "",
  "info": "content-sync@0.1.0",
  "tags": [],
  "action": {
    "type": "use_from_storage",
    "content_info": "test-dockerfile-content@0.1.0"
  }
}

В итоге при выполнении Пайплайна в папку сборки будет добавляться нужный вам контент.

Раз за разом вы начнёте замечать, что некоторые проекты переиспользуются в других проектах как зависимости, и их необходимо где-то публиковать. Для этого как нельзя лучше подходят репозитории пакетов, но если вы не хотите публиковать свой проект, то можете добавлять его в хранилище Деплойера в качестве контента. Более того, добавлять его можно автоматически - при помощи Действия add_to_storage:

{
  "title": "Add content",
  "desc": "",
  "info": "content-add@0.1.0",
  "tags": [],
  "action": {
    "type": "add_to_storage",
    "short_name": "my-project",
    "auto_version_rule": {
      "plain_file": "file-with-current-version.txt"
    }
  }
}
  • short_name - строковое обозначение контента, которое будет использовано для размещения в хранилище и каждый раз при использовании
  • auto_version_rule - способ автоматического определения версии контента (либо plain_file - файл, в котором будет указана только версия и больше ничего, либо cmd_stdout - команда, которая выведет на экран только версию и больше ничего)

Однако иногда файл нужно каким-то образом редактировать - и не столько даже добавляемый контент из хранилища Деплойера, сколько, например, различные файлы в зависимостях сборки, например, вручную делать форки библиотек Python для добавления нужной функциональности и т.д. и т.п. Причём, как правило, хочется делать это без создания форков и синхронизации изменений с main-репозиторием! Одними патчами git'а не обойтись.

Для этого Деплойер использует для патчей библиотеку smart-patcher. Такие патчи позволяют изменять исходные тексты, сложные документы и даже бинарные файлы, позволяя искать необходимые включения в содержимом на базе отсеивающих правил и даже используя скрипты на таких языках, как Python, Lua и Rhai. Например, в репозитории smart-patcher есть пример с патчем для документа Microsoft Word - и много других примеров.

Для использования умных патчей вам необходимо сперва написать файл патча. Пример:

{
  "patches": [
    {
      "files": [
        {
          "just": "test_v5.docx"
        }
      ],
      "decoder": {
        "python": "../tests/test_v5.py"
      },
      "encoder": {
        "python": "../tests/test_v5.py"
      },
      "path_find_graph": [],
      "replace": {
        "from_to": [
          "game",
          "rock"
        ]
      }
    }
  ]
}

Действие патча же выглядит так:

{
  "title": "Apply patch",
  "desc": "",
  "info": "my-patch@0.1.0",
  "tags": [],
  "action": {
    "type": "patch",
    "patch": "my_path.json"
  }
}

Патч должен располагаться в папке сборки при выполнении Пайплайна. Очень хорошей практикой является написание патчей и размещение их в качестве контента в хранилище Деплойера. Тогда и файл патча, и скрипты будут расположены рядом и будут добавляться в процессе сборки.

При применении патча Деплойер выводит количество его применений в проекте. Если патч не был применён ни разу в процессе выполнения Пайплайна, Деплойер выдаст ошибку.

Note

По умолчанию Деплойер не поддерживает скрипты патчей, написанные на Python. Если такая поддержка необходима, соберите Деплойер командой deployer run ru-full.

1.6. Действия синхронизации папок сборки - с текущего хоста на удалённый sync_to_remote и наоборот sync_from_remote

Иногда нужно синхронизировать файлы сборки между удалёнными хостами и текущим хостом. Например, когда часть действий нужно обязательно выполнить на одном хосте, а часть - на другом. Для этого можно использовать встроенные Действия sync_to_remote и sync_from_remote:

{
  "title": "Send build folder to remote",
  "desc": "",
  "info": "send-to-remote@0.1.0",
  "tags": [],
  "action": {
    "type": "sync_to_remote",
    "remote_host_name": "remote-pc"
  }
}

1.7. Другие действия - interrupt, observe и test

Note

Нет нужного примера конфигурации? Создайте действие самостоятельно при помощи команды deployer new action и выведите его на экран при помощи deployer cat action my-action@x.y.z.

interrupt используется для ручного прерывания сборки/развёртывания проекта. Когда Деплойер доходит до этого действия, он ожидает пользовательского ввода, чтобы продолжить, когда вы выполните необходимые действия вручную.

observe - Действие, которое практически идентично custom. Оно используется, например, чтобы запустить Prometheus, Jaeger или что угодно ещё. Отличительной особенностью является то, что оно запускается без перенаправления ввода-вывода, т.е. в нём можно взаимодействовать с программами.

А вот test - особенное действие, позволяющее проверять, что вывела команда в stdout/stderr:

{
  "type": "test",
  "command": {
    "bash_c": "<af>",
    "placeholders": [
      "<af>"
    ],
    "ignore_fails": true,
    "show_success_output": false,
    "show_bash_c": false,
    "only_when_fresh": false
  },
  "success_when_found": "some rust regex"
}
  • success_when_found сообщает Деплойеру, что если он найдёт указанное регулярное выражение, то выполнение команды будет считаться успешным
  • success_when_not_found сообщает Деплойеру, что если он не найдёт указанное регулярное выражение, то выполнение команды будет считаться успешным

Причём, если оба поля указаны, то успешным запуск будет считаться в случае, если оба варианта были успешны (первое регулярное выражение должен найти, второе - должен не найти).

1.8. Субпайплайны

Субпайплайны позволяют группировать Действия по описанию и назначению, чтобы затем использовать их совместно в Пайплайнах проектов. Пример:

{
  "type": "sub_pipeline",
  "title": "Sub-pipeline running Action",
  "desc": "This is actual Pipeline inside your described Action.",
  "info": "test-subpipeline@0.2.0",
  "tags": [],
  "actions": [
    {
      "title": "List files",
      "desc": "Got from `List files and folders`.",
      "info": "ls@0.1.0",
      "tags": [],
      "action": {
        "type": "custom",
        "bash_c": "ls",
        "ignore_fails": false,
        "show_success_output": true,
        "show_bash_c": true,
        "only_when_fresh": false
      },
      "exec_in_project_dir": false
    }
  ]
}

Note

Вне зависимости от наличия экслюзивной метки сборки, Субпайплайн будет выполнен в той же папке, что и родительский Пайплайн.

На этом описание Действий заканчивается, и мы переходим к Пайплайнам.

2. Пайплайн - Pipeline

Пайплайн - это упорядоченный набор Действий, который необходим для достижения определённой цели. Например, когда нужно проверить качество кода, проверить код с помощью статического анализатора, затем собрать, сжать, упаковать в пакет для определённого дистрибутива и загрузить на хостинг. Или когда нужно собрать Android-приложение, подписать и установить на устройство, подключённое по ADB. Композиция Пайплайна может быть любой, главный же пример приведён в файле deploy-config.json этого репозитория:

{
  "title": "Deployer Pipeline",
  "desc": "Default Deployer Pipeline for itself.",
  "info": "deployer-default@0.1.0",
  "tags": [
    "cargo",
    "clippy",
    "build",
    "upx"
  ],
  "actions": [
    {
      "title": "Lint",
      "desc": "Got from `Cargo Clippy`.",
      "info": "cargo-clippy@0.1.0",
      "tags": [
        "cargo",
        "clippy"
      ],
      "action": {
        "type": "pre_build",
        "supported_langs": [
          "rust"
        ],
        "commands": [
          {
            "bash_c": "cargo clippy",
            "ignore_fails": false,
            "show_success_output": true,
            "show_bash_c": true
          }
        ]
      }
    },
    {
      "title": "Build",
      "desc": "Got from `Cargo Build (Release)`. Build the Rust project with Cargo default settings in release mode",
      "info": "cargo-rel@0.1",
      "tags": [
        "rust",
        "cargo"
      ],
      "action": {
        "type": "build",
        "supported_langs": [
          "rust"
        ],
        "commands": [
          {
            "bash_c": "cargo build --release",
            "ignore_fails": false,
            "show_success_output": false,
            "show_bash_c": true
          }
        ]
      }
    },
    {
      "title": "Compress",
      "desc": "Got from `UPX Compress`.",
      "info": "upx@0.1.0",
      "tags": [
        "upx"
      ],
      "action": {
        "type": "post_build",
        "supported_langs": [
          "any"
        ],
        "commands": [
          {
            "bash_c": "upx <artifact>",
            "placeholders": [
              "<artifact>"
            ],
            "replacements": [
              {
                "group": [
                  {
                    "from": "<artifact>",
                    "to": {
                      "title": "target/release/deployer",
                      "is_secret": false,
                      "value": {
                        "type": "plain",
                        "value": "target/release/deployer"
                      }
                    }
                  }
                ]
              }
            ],
            "ignore_fails": false,
            "show_success_output": false,
            "show_bash_c": false
          }
        ]
      }
    },
    {
      "title": "Install to ~/.cargo/bin",
      "desc": "",
      "info": "install-to-cargo-bin@0.1.1",
      "tags": [
        "cargo"
      ],
      "action": {
        "type": "install",
        "target": {
          "arch": "x86_64",
          "os": "linux",
          "os_derivative": "any",
          "os_version": {
            "type": "no"
          }
        },
        "commands": [
          {
            "bash_c": "cp -f <artifact> ~/.cargo/bin",
            "placeholders": [
              "<artifact>"
            ],
            "replacements": [
              {
                "group": [
                  {
                    "from": "<artifact>",
                    "to": {
                      "title": "target/release/deployer",
                      "is_secret": false,
                      "value": {
                        "type": "plain",
                        "value": "target/release/deployer"
                      }
                    }
                  }
                ]
              }
            ],
            "ignore_fails": false,
            "show_success_output": false,
            "show_bash_c": false
          }
        ]
      }
    }
  ],
  "default": true
}

В общем, Пайплайн содержит список Действий в поле actions.

Помимо этого, если ваши Пайплайны должны управлять конфликтующими версиями кэша (например, при сборке проекта под разные целевые архитектуры), то вы можете указать эксклюзивную метку сборки в поле exclusive_exec_tag. Например, укажите x86_64 при добавлении Пайплайна сборки для одной архитектуры, а aarch64 - для другой. Тогда Пайплайны будут собираться в разных папках, и информация о кэше будет сохранена в обоих случаях.

2.1. Контейнеризированная сборка и выполнение, а также стратегии

Поскольку Деплойер может выполнять любые команды, он также может автоматизировать выполнение развёртывания в контейнерах и кластерах при помощи Docker- и Kubernetes-подобных платформ. Но, что самое интересное, Деплойер предоставляет автоматизацию сборки и запуска ваших Пайплайнов в контейнерах Docker и Podman с автоматической генерацией Dockerfile. Артефакты также будут извлечены автоматически и помещены в папку проекта. Контейнеризированная сборка может быть полезной в тех случаях, когда требуется сборка под другие платформы или в другом окружении.

В этом плане Деплойер позволяет дополнительные функции (см. ниже).

Сборка и выполнение происходят следующим образом:

  1. Формируется образ для сборки Деплойера под нужную платформу (для выполнения Пайплайнов на базе образа).
  2. Собирается Деплойер.
  3. Формируется образ для сборки проекта под нужную платформу - с необходимыми зависимостями и прочими командами, которые можно указать самостоятельно.
  4. Если указаны стратегии кэширования сборки, Деплойер производит сборку и сохраняет кэши.
  5. Деплойер на машине-хосте запускает Деплойер в контейнере и производит полное выполнение Пайплайна.

Note

При сборке в контейнерах Деплойер не поддерживает Действия interrupt, observe, add_to_storage и use_from_storage, а при запуске - Действия add_to_storage и use_from_storage.

Для решения проблем синхронизации каких-то файлов или выполнения операций ввода-вывода вы можете использовать Пайплайн с опциями контейнеризированной сборки внутри другого Пайплайна, который уже сможет использовать нужные вам Действия.

Посмотрим на пример контейнеризированного Пайплайна:

{
  "title": "containered",
  "desc": "Got from `Deployer Pipeline`.",
  "info": "deployer-default@0.1.2",
  "tags": [
    "cargo",
    "clippy",
    "build"
  ],
  "actions": [
    {
      "title": "Lint",
      "desc": "Got from `Cargo Clippy`.",
      "info": "cargo-clippy@0.1.0",
      "tags": [
        "cargo",
        "clippy"
      ],
      "action": {
        "type": "pre_build",
        "supported_langs": [
          "rust"
        ],
        "commands": [
          {
            "bash_c": "cargo clippy --no-default-features --features=lua,rhai,tui,containered",
            "ignore_fails": false,
            "show_success_output": true,
            "show_bash_c": true
          }
        ]
      },
      "requirements": [
        {
          "type": "exists_any",
          "paths": [
            "/bin/cargo",
            "~/.cargo/bin/cargo"
          ]
        }
      ]
    },
    {
      "title": "Build",
      "desc": "Got from `Cargo Build (Release)`. Build the Rust project with Cargo default settings in release mode",
      "info": "cargo-rel@0.1",
      "tags": [
        "rust",
        "cargo"
      ],
      "action": {
        "type": "build",
        "supported_langs": [
          "rust"
        ],
        "commands": [
          {
            "bash_c": "RUSTFLAGS='-Zthreads=16' cargo build --release --no-default-features --features=lua,rhai,tui,containered",
            "ignore_fails": false,
            "show_success_output": false,
            "show_bash_c": true
          }
        ]
      },
      "requirements": [
        {
          "type": "exists_any",
          "paths": [
            "/bin/cargo",
            "~/.cargo/bin/cargo"
          ]
        }
      ]
    }
  ],
  "default": false,
  "containered_opts": {
    "preflight_cmds": [
      "RUN apt-get update && apt-get install -y build-essential curl git && rm -rf /var/lib/apt/lists/*",
      "RUN curl https://sh.rustup.rs -sSf | bash -s -- -y --profile minimal --default-toolchain nightly",
      "ENV PATH=\"/root/.cargo/bin:${PATH}\"",
      "RUN rustup component add clippy"
    ],
    "cache_strategies": [
      {
        "fake_content": "docker-fake-files@0.1.0",
        "copy_cmds": [
          "COPY rust-toolchain.toml .",
          "COPY .docker-fake-files/rust/lib.rs src/lib.rs",
          "COPY .docker-fake-files/rust/main.rs src/main.rs",
          "COPY Cargo.toml .",
        ],
        "pre_cache_cmds": [
          "DEPL"
        ]
      },
      {
        "copy_cmds": [
          "COPY src/ src/",
          "COPY DOCS.en.md .",
          "COPY DOCS.ru.md ."
        ],
        "pre_cache_cmds": [
          "RUN touch src/main.rs",
          "RUN touch src/lib.rs",
          "DEPL"
        ]
      }
    ]
  },
  "exclusive_exec_tag": "containered"
}

Всё отличие заключается в добавлении поля containered_opts, которое автоматически заставляет Деплойер выполнять этот Пайплайн в контейнеризированном окружении.

  • base_image - вы можете указать базовый образ для сборки проекта (по умолчанию - ubuntu:latest)
  • preflight_cmds - список команд для правильной установки окружения
  • build_deployer_base_image, preflight_deployer_build_deps и deployer_build_cmds - базовый образ, команды для настройки и команды для сборки самого Деплойера
  • cache_strategies - стратегии кэширования при сборке
  • use_containerd_local_storage_cache - при сборке в Docker и включенной фиче containerd в /etc/docker/daemon.json позволяет сохранять кэш образов в папке выполнения Пайплайна, что упрощает очистку кэша
  • prevent_metadata_loading - предотвращает повторное подключение к регистрам и поиск нового образа, когда доступен старый (позволяет осуществлять сборку и запуск Пайплайнов в контейнерах без доступа к Интернету)
  • executor - позволяет указать исполнителя сборки и запуска (по умолчанию - Docker, для использования Podman укажите podman)

Поскольку Деплойер нужен в контейнеризированном окружении, проверяйте совместимость Деплойера и окружения путём запуска Пайплайна. Если Деплойер собран с поддержкой Python, лучше всего использовать идентичные базовые образы.

Чтобы сохранять кэш сборок, а не пересобирать Пайплайн постоянно с нуля, рекомендуется указать стратегии кэширования. Они выполняются при сборке контейнеризированного окружения. Доступные поля:

  • fake_content - поле для синхронизации контента для подмены существующих файлов (работает также, как и use_from_storage, но не поддерживает latest-теги)
  • copy_cmds - команды для копирования исходного кода в образ
  • pre_cache_cmds - команды для предварительного кэширования

Если в качестве команды предварительного кэширования нужно выполнить Пайплайн, укажите команду "DEPL". Конфигурация контейнеризированного Пайплайна будет добавлена в контейнер автоматически.

Стратегии кэширования подходят для реализации многостадийных сборок. В указанном выше примере происходит двухстадийная сборка для Rust-проекта, которая сначала требует копирования реального Cargo.toml и фейковых lib.rs и main.rs, чтобы сначала скомпилировать все зависимости проекта, а потом уже копирует реальный исходный код src/ и обновляет штампы времени RUN touch src/main.rs & touch src/lib.rs, чтобы затем собрать проект без необходимости пересборки зависимостей. В этом случае будет использоваться кэш зависимостей до тех пор, пока Cargo.toml не будет отредактирован.

Для пересборки окружения с нуля запустите Деплойер с флагом -f/--fresh.

Одной из самых важных сущностей являются переменные. Они одновременно являются и хранителями ваших секретов, и теми самыми динамическими сущностями, которые могут поменять исход выполнения Пайплайна. Пример простой переменной:

{
  "title": "deployer artifact location",
  "is_secret": false,
  "value": {
    "type": "plain",
    "value": "target/release/deployer"
  }
}
  • title - название переменной (то, как она будет отображаться в TUI)
  • is_secret - является ли переменная секретом (если является, то команда, которая её содержит, не будет показана на экране)
  • value - само значение переменной или же информация о том, откуда и как это значение брать

Есть три поддерживаемых сейчас типа переменных:

  1. plain - содержимое строки и есть переменная
  2. from_env_var - переменная будет взята из окружения оболочки Деплойера
  3. from_env_file - переменная будет взята из указанного env-файла с указанным ключом
  4. from_hc_vault_kv2 - переменная будет взята из HashiCorp Vault KV2-хранилища с указанными mount_path и secret_path

Примеры:

{
  "title": "Grafana token",
  "is_secret": true,
  "value": {
    "type": "from_env_file",
    "env_file_path": ".env",
    "key": "GRAFANA_TOKEN"
  }
}
{
  "title": "Simple env var",
  "is_secret": false,
  "value": {
    "type": "from_env_var",
    "var_name": "variable-key"
  }
}
{
  "title": "Secret!",
  "is_secret": true,
  "value": {
    "type": "from_hc_vault_kv2",
    "mount_path": "The mount path where your KV2 secrets engine is mounted",
    "secret_path": "Path to your secret"
  }
}

Заметьте, что вы должны перед использованием from_hc_vault_kv2-переменных указать две переменные окружения: DEPLOYER_VAULT_ADDR (URL-адрес Vault) и DEPLOYER_VAULT_TOKEN (токен Vault).

Ещё одной важной сущностью является удалённый хост. Деплойер хранит все хосты в Реестре (глобальный файл конфигурации - список remote_hosts). Структура хоста выглядит так:

{
  "short_name": "localhost",
  "ip": "127.0.0.1",
  "port": 22,
  "username": "username",
  "ssh_private_key_file": "/path/to/id_rsa"
}

Чтобы иметь возможность использовать хост, перед его добавлением необходимо создать ключ и разрешить авторизацию на удалённом хосте по ключу.

Описание утилиты CLI

Деплойер, в первую очередь, - CLI-утилита. По любой команде Деплойера можно посмотреть справку, указав опцию -h. Приведём примеры самых распространённых команд:

deployer new action                            # создать Действие и поместить в Реестр
deployer new pipeline                          # создать Пайплайн и поместить в Реестр
deployer new remote                            # добавить в Реестр новый удалённый хост
deployer init                                  # инициализировать проект, указать все свойства
deployer with                                  # проверить совместимость и назначить Пайплайн для проекта,
                                               # а также указать необходимые переменные и артефакты вместо плейсхолдеров
deployer run                                   # запустить Пайплайн, назначенный по умолчанию
deployer run my-pipe                           # запустить Пайплайн по короткому имени
deployer run configure,build -o build-folder   # запустить Пайплайны `configure` и `build` в папке `build-folder`
deployer run -R my-remote my-pipe              # запустить Пайплайн `my-pipe` на удалённом хосте `my-remote`

Интерфейс консоли (TUI)

Деплойер обладает поддержкой высококлассного настройщика через терминал, что позволяет вам вообще забыть про ручное написание Действий и Пайплайнов для ваших проектов. Просто попробуйте создать Действие или Пайплайн, и Деплойер сам вас обо всём спросит.

Логи

В папке с кэшами сборки Деплойера есть папка logs, в которой расположены файлы логов проектов с указанием даты и времени сборки. Информация в них повторяет информацию с экрана терминала и на данный момент не хранит весь лог выполнения каждой команды в оболочке.