Обзор
После того как ваше приложение собрано и протестировано локально, у вас есть два пути для его распространения:- Разверните tar-архив — загрузите своё приложение напрямую на конкретный сервер Twenty для внутреннего или частного использования.
- Публикация в npm — опубликуйте свой пакет, заявите права на него в Twenty и завершите его настройку, чтобы другие рабочие пространства могли находить и устанавливать его.
Владение регистрацией
Публикация приложения создаёт регистрацию приложения: идентификатор приложения в инстансе, общий для всех рабочих пространств, которые его устанавливают. Она содержит запись приложения в маркетплейсе, его клиент OAuth и его серверное состояние —serverVariables, настраиваемые оператором, и записи с областью действия server в хранилище ключей и значений.
universalIdentifier уникален во всём инстансе, а регистрация принадлежит не более чем одному рабочему пространству (её владельцу) — либо никому, пока не будет заявлена, — поэтому установка приложения и разработка приложения — это два разных права:
Синхронизация кода и манифеста с идентификатором является заявлением об авторстве, поэтому возможность установить приложение никогда не даёт права публиковать код под его идентификатором. Рабочему пространству, не являющемуся владельцем, будет отказано независимо от того, размещено ли приложение, предустановлено или является приватным.
К такому отказу приводят две ситуации:
- Идентификатор принадлежит другому рабочему пространству. Измените
universalIdentifierв конфигурации приложения — это обычное решение, если вы создали форк чужого приложения. Если вам нужно сохранить идентификатор, рабочее пространство-владелец должно передать регистрацию вашему рабочему пространству. - Идентификатор не принадлежит ни одному рабочему пространству. Приложения, импортированные синхронизацией каталога маркетплейса, изначально не имеют владельца. Заявите права на своё приложение с помощью GitHub, прежде чем разрабатывать его. Публикация с подтверждением происхождения npm предоставляет доказательство авторства; она не назначает автоматически рабочее пространство владельца в Twenty.
Сборка вашего приложения
Выполните команду сборки, чтобы проверить типы и собрать приложение:--json для проверки манифеста и метаданных артефакта. twenty app publish создаёт сам пакет; отдельная сборка tarball-архива не требуется.
Развертывание на сервер (tarball)
Для приложений, которые вы не хотите делать общедоступными — собственные инструменты, интеграции только для предприятий или экспериментальные сборки — вы можете развернуть tarball напрямую на сервер Twenty.Требования
Перед развертыванием вам нужен настроенный remote, указывающий на целевой сервер. Remotes локально хранят URL сервера и учётные данные аутентификации в~/.twenty/config.json.
Добавьте remote:
Развертывание
Соберите и загрузите ваше приложение на сервер в одном шаге:Общий доступ к развернутому приложению
Приложения в формате tarball не отображаются в публичном маркетплейсе, поэтому другие рабочие пространства на том же сервере не найдут их при просмотре. Чтобы поделиться развернутым приложением:- Перейдите в Настройки > Разработчики > Приложения и откройте своё приложение в разделе Мои приложения
- На вкладке Распространение нажмите Копировать ссылку для общего доступа
- Поделитесь этой ссылкой с пользователями в других рабочих пространствах — она ведёт их прямо на страницу установки приложения
Управление версиями
При обновлении уже развернутого tarball-приложения сервер требует, чтобы значениеversion в package.json было строго выше (согласно упорядочиванию по semver), чем текущая развернутая версия. Повторное развертывание той же версии или отправка более ранней версии отклоняется, когда сервер регистрирует загруженный tarball, который затем снова удаляется. Вы увидите ошибку VERSION_ALREADY_EXISTS от CLI.
Чтобы выпустить обновление:
- Увеличьте значение поля
versionв вашемpackage.json(например:1.2.3→1.2.4,1.3.0или2.0.0). - Выполните
twenty app publish --private(илиtwenty app publish --private --remote production) - Рабочие пространства, в которых приложение установлено и для него включено автообновление (на вкладке «Общие» приложения), обновляются автоматически в фоновом режиме; в остальных рабочих пространствах пользователи увидят доступное обновление в своих настройках
Пререлизные теги работают как ожидается: повышение версии
1.0.0-rc.1 → 1.0.0-rc.2
допускается, а финальный релиз вроде 1.0.0 корректно распознаётся как более высокий
чем 1.0.0-rc.5. Версия в package.json должна сама по себе быть корректной строкой semver
.Совместимость версий сервера
Если ваше приложение использует функцию, появившуюся в конкретной версии сервера Twenty (например, провайдеры OAuth, добавленные в v2.3.0), следует объявить минимальную требуемую версию сервера с помощью поляengines.twenty в package.json:
Что происходит при развёртывании и установке:
- Если
engines.twentyзадано и версия целевого сервера не удовлетворяет диапазону, развёртывание (загрузка tarball-архива) или установка отклоняются с ошибкойSERVER_VERSION_INCOMPATIBLEи сообщением, указывающим как требуемый диапазон, так и фактическую версию сервера. - Если
engines.twentyне задано, проверка версии не выполняется, и приложение принимается на сервере любой версии (обратная совместимость с существующими приложениями). Пустое значение отклоняется как недопустимый диапазон. - Маркетплейс не отображает приложение, последняя версия которого объявляет диапазон
engines.twenty, которому сервер не соответствует, или недопустимый диапазон. Приложение остаётся зарегистрированным и видимым в панели администратора. - Если на сервере
APP_VERSIONне задано, проверка пропускается.
Сервер выполняет окончательную проверку — он проверяет
engines.twenty как при
загрузке tarball-архива, так и при установке в рабочем пространстве. Если вы развёртываете tarball вне стандартного процесса или
устанавливаете из маркетплейса, сервер всё равно принудительно проверяет совместимость.Автоматизированный CI/CD (рабочие процессы, сгенерированные шаблоном)
Приложения, созданные с помощьюtwenty app init, «из коробки» включают три рабочих процесса GitHub Actions в каталоге .github/workflows/. CI запускается без какой-либо настройки, для CD требуется один секрет, а публикация в npm требует однократной настройки доверенного издателя npm (trusted-publisher).
CI — ci.yml
Автоматически запускает интеграционные тесты при каждом пуше в main и для каждого pull request.
Что делает:
- Извлекает исходный код вашего приложения.
- Запускает изолированный тестовый экземпляр Twenty с помощью составного действия
twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main. - Включает Corepack и настраивает Node.js на основе вашего
.nvmrc. - Устанавливает закреплённую автономную CLI на этапе Установка CLI Twenty.
- Устанавливает зависимости с помощью
yarn install --immutable, затем запускает lint, проверку типов и модульные тесты. - Запускает
yarn test, передаваяTWENTY_API_URLиTWENTY_API_KEYиз запущенного экземпляра, чтобы ваши тесты могли взаимодействовать с реальным сервером.
TWENTY_VERSION(переменная окружения, по умолчаниюlatest) — зафиксируйте версию сервера Twenty, используемую в CI, отредактировав это значение вci.yml.- Параллельные запуски группируются по
github.refи отменяют выполняющиеся прогоны при новых пушах.
CD — cd.yml
Разворачивает ваше приложение на настроенном сервере Twenty при каждом пуше в main и, при необходимости, из pull request при наличии метки deploy.
Что делает:
- Извлекает head-коммит PR (для PR с меткой) или запушенный коммит.
- Запускает
twentyhq/twenty/.github/actions/deploy-twenty-app@main— эквивалент для CItwenty app publish --private. - Запускает
twentyhq/twenty/.github/actions/install-twenty-app@main, чтобы новая развернутая версия была установлена в целевое рабочее пространство.
Значение
TWENTY_DEPLOY_URL по умолчанию — http://localhost:2020 — это заглушка —
с хостируемого GitHub раннера к ней не будет доступа. Перед включением CD замените его на публичный URL вашего
сервера (или используйте self-hosted раннер с сетевым доступом).deploy. Условие if: в cd.yml запустит задачу для этого PR, используя его head-коммит, что позволит проверить изменение на целевом сервере до слияния.
Публикация — publish.yml
Публикует ваше приложение в npm с указанием происхождения (provenance), когда вы отправляете тег версии (например, v1.0.0), или когда вы запускаете рабочий процесс вручную на вкладке Actions.
Что делает:
- Клонирует ваше приложение, настраивает Node.js и обновляет npm (для доверенной публикации требуется npm версии 11.5.1 или новее).
- Устанавливает закреплённую автономную CLI на этапе Установка CLI Twenty, затем устанавливает зависимости приложения с помощью
yarn install --immutable. - Запускает
twenty app publish, который собирает и упаковывает изолированный снимок приложения, а затем публикует его в npm. В CI он автоматически добавляет--provenanceи--access public, поэтому в рабочем процессе флаги не требуются.
publish.yml (см. документацию по доверенной публикации в npm). Публикация с подтверждением происхождения удостоверяет, какой репозиторий GitHub собрал пакет. После публикации заявите права собственности в Twenty.
npm принимает подтверждение происхождения только из публичных репозиториев с исходным кодом. Если вы публикуете из приватного репозитория, npm отклоняет пакет подтверждения происхождения OIDC с ошибкой Без подтверждения происхождения GitHub права на пакет нельзя заявить через Заявить права с помощью GitHub. Если вам нужен этот процесс назначения владельца, используйте общедоступный репозиторий с подтверждением происхождения.
E422 ... Ошибка Unsupported GitHub Actions source repository visibility: “private”. Чтобы публиковать из приватного репозитория, отключите подтверждение происхождения, установив TWENTY_APP_PUBLISH_DISABLE_PROVENANCE: ‘true’вenvшага публикации (закомментированная подсказка включена в сгенерированныйpublish.yml`):Закрепление версии CLI
Все три сгенерированных рабочих процесса закрепляют автономную CLI на версииtwenty, которая запустила twenty app init. Этапы Установка CLI Twenty в ci.yml и publish.yml используют npm install -g twenty@\<version>. В cd.yml и действие развёртывания, и действие установки получают одну и ту же версию через свой входной параметр cli-version.
Для обновления одновременно обновите две команды установки и оба входных параметра cli-version. Эти закрепления не зависят от версии сервера TWENTY_VERSION, используемой в CI, и ссылок на повторно используемые действия ниже.
Закрепление версий повторно используемых действий
Рабочие процессыci.yml и cd.yml ссылаются на повторно используемые действия с указанием @main, поэтому обновления действий в репозитории twentyhq/twenty подхватываются автоматически. Если вам нужны детерминированные сборки, замените @main на SHA коммита или тег релиза в каждой строке uses:.
Публикация в npm
Публикация в npm позволяет разместить ваше приложение на маркетплейсе Twenty. После синхронизации каталога и любой необходимой настройки серверных маршрутов рабочие пространства смогут просматривать, устанавливать и обновлять его через интерфейс после прохождения проверки Marketplace.Требования
- Учётная запись npm
- Ключевое слово
twenty-appв массивеkeywordsвашегоpackage.json(добавьте его вручную — по умолчанию оно не включено в шаблонtwenty app init)
Метаданные маркетплейса
КонфигурацияdefineApplication() поддерживает необязательные поля, которые определяют, как ваше приложение отображается в маркетплейсе. Используйте logo и galleryImages, чтобы ссылаться на изображения из папки public/:
src/application-config.ts
author, category, aboutDescription, websiteUrl, termsUrl и т. д.).
Рекомендуемые размеры изображений галереи
Маркетплейс отображаетgalleryImages в контейнере с фиксированным соотношением сторон 8:5 (например, 1600×1000 px).
Изображения галереи с любым соотношением сторон отображаются полностью и никогда не
обрезаются, но всё, что значительно выше или уже, чем
8:5, будет иметь
пустые поля по бокам.Ограничение размера изображения
Файлlogo и каждый файл из galleryImages не должны превышать 10 MB. Более крупные файлы пропускаются при повторном размещении ваших опубликованных ресурсов на маркетплейсе, поэтому они не будут отображаться.
Публикация
beta или next):
Как работает обнаружение приложений в маркетплейсе
Сервер Twenty синхронизирует каталог маркетплейса из реестра npm каждый час. Автономная CLI не имеет команды синхронизации каталога. Дождитесь синхронизации каталога сервером или используйте инструменты администрирования сервера. Метаданные, отображаемые в маркетплейсе, берутся из вашей конфигурацииdefineApplication() — см. раздел Метаданные маркетплейса выше.
Если ваше приложение не определяет
aboutDescription в defineApplication(), маркетплейс автоматически использует README.md вашего пакета из npm в качестве содержимого страницы «О приложении». Это означает, что вы можете поддерживать единый README как для npm, так и для маркетплейса Twenty. Если вы хотите другое описание в маркетплейсе, явно задайте aboutDescription.Вкладка About отображает только текст Markdown. Изображения не отображаются, независимо от того, используется ли синтаксис Markdown или теги <img>, а необработанный HTML, например бейджи или блоки \<div align="center">, отображается как обычный текст.Публикация через CI
Сгенерированный выше рабочий процессpublish.yml автоматически публикует в npm по тегам версий, с provenance. Поскольку twenty app publish при запуске в CI добавляет за вас --provenance и --access public, в рабочем процессе не нужны флаги npm — требуется только однократная настройка доверенного издателя.
Для других систем CI (GitLab CI, CircleCI и т. д.) запустите yarn install, затем twenty app publish. Provenance создается, когда среда может выпустить токен OIDC, и в противном случае автоматически пропускается.
npm provenance добавляет значок доверия к вашему пакету в npm, позволяя пользователям
проверить, что пакет был собран из конкретного коммита в общедоступном конвейере CI.
Это также то, что позволяет вам заявить права на ваше приложение в маркетплейсе Twenty.
Подробности см. в документации по npm provenance
.
Заявление прав на приложение
При заявлении прав регистрация вашего приложения назначается рабочему пространству Twenty, которое будет им управлять. Заявление прав на приложение доступно всем рабочим пространствам. Для получения прав через вкладку Apps в Settings > Developers вашей роли необходимы разрешения Workspace Apps и Developers. Право собственности определяется для каждого экземпляра Twenty: заявление прав в Twenty Cloud не заявляет права на приложение на отдельном самостоятельно размещённом сервере. Другие рабочие пространства в том же экземпляре устанавливают ваше приложение, не заявляя права на него самостоятельно.Перед заявлением прав
- Опубликуйте пакет из общедоступного репозитория GitHub, используя GitHub Actions и доверенную публикацию npm с подтверждением происхождения. Версия, импортированная в каталог Twenty, должна содержать аттестацию происхождения.
- Добавьте ключевое слово
twenty-appвpackage.jsonи дождитесь синхронизации каталога. - Выберите рабочее пространство, которому будет принадлежать приложение. Для приложений с серверными маршрутами это рабочее пространство также запускает и оплачивает общий резолвер.
- Войдите в GitHub под личной учётной записью, которой принадлежит исходный репозиторий, или как владелец организации, которой он принадлежит. Одного доступа соавтора репозитория или доступа сопровождающего пакета npm недостаточно.
Закрепить через GitHub
- В рабочей области предполагаемого владельца перейдите в Настройки > Разработчики > Приложения (
/settings/developers#apps). - В разделе Заявить права на приложение введите точное имя пакета npm, включая его область видимости (например,
@your-org/twenty-app), илиuniversalIdentifierприложения. - Нажмите Найти и убедитесь, что результатом является ваше приложение. Если оно не найдено, нажмите Синхронизировать каталог, если эта кнопка доступна, дождитесь завершения синхронизации, а затем выполните поиск снова.
- Нажмите Заявить права с помощью GitHub и авторизуйте Twenty. Для репозитория, принадлежащего организации, предоставьте доступ к этой организации в разделе GitHub Доступ к организации. Для личных репозиториев не требуется предоставлять доступ организации.
- Вернувшись в Twenty, убедитесь, что приложение отображается в разделе Мои приложения с типом NPM. Откройте его и убедитесь, что в разделе Распространение > Владение указано Заявлено этим рабочим пространством.
Настройка серверных маршрутов
Серверный маршрут получает события для нескольких рабочих пространств по одному URL-адресу. Его резолвер запускается в рабочем пространстве владельца регистрации, а затем распределяет работу в соответствующее рабочее пространство, где установлено приложение.- Откройте приложение в разделе Мои приложения и заполните все обязательные Переменные сервера на вкладке Конфигурация.
- В разделе Распространение нажмите Посмотреть на маркетплейсе, чтобы открыть страницу приложения и установить его в рабочем пространстве владельца. Вы можете открыть эту страницу ещё до появления приложения в поиске маркетплейса.
- Зарегистрируйте URL-адрес серверного вебхука у своего провайдера и протестируйте событие из второго рабочего пространства, в котором установлено приложение. Проверьте журналы как резолвера, так и целевой функции.
Стоимость и доступность рабочего пространства владельца
Сведения о потреблении кредитов, ценах и выставлении счетов рабочему пространству см. в разделе Как учитываются запуски логических функций. Удаление приложения из рабочего пространства владельца или удаление этого рабочего пространства удаляет общий резолвер и прерывает серверные вебхуки для всех установок в этом экземпляре.Владение после переноса репозитория
Перенос репозитория GitHub в другую личную учётную запись или организацию не передаёт и не удаляет существующее заявление прав в Twenty. Регистрация остаётся привязанной к рабочему пространству владельца. Сохраните тот же пакет npm иuniversalIdentifier приложения; смена рабочего пространства владельца Twenty требует отдельной передачи прав собственности.
Устранение неполадок при заявлении прав
Если у вас возникли проблемы с заявлением прав на приложение, свяжитесь с нами в Discord или создайте задачу в GitHub.Конфигурация заявления прав GitHub для самостоятельного хостинга
Конфигурация заявления прав GitHub для самостоятельного хостинга
Администратор сервера настраивает
APP_CLAIM_GITHUB_CLIENT_ID и
APP_CLAIM_GITHUB_CLIENT_SECRET с помощью OAuth-приложения GitHub. Установите для его URL обратного вызова авторизации
значение вашего SERVER_URL с добавлением
/application-registration-claim/github/callback, например
https://twenty.example.com/application-registration-claim/github/callback.
В Twenty Cloud эта конфигурация уже управляется для вас.Видимость и проверка в Marketplace
Все приложения, представленные в Marketplace, прошли проверку безопасности и качества Twenty. Недавно опубликованное приложение остаётся скрытым, пока не пройдёт проверку Marketplace; подтверждение прав устанавливает владение, но не делает его доступным в списке. Скрытое приложение всё ещё можно установить. В разделе Настройки > Приложения > Marketplace откройте фильтр и включите Показывать скрытые приложения или поделитесь страницей прямой установки приложения через Мои приложения > ваше приложение > Распространение > Копировать ссылку для общего доступа. Рабочие пространства увидят предупреждение о том, что приложение не прошло проверку Twenty. Если ваше приложение представлено в списке, но всё ещё отсутствует в Marketplace, убедитесь, что синхронизация каталога завершена, все обязательные переменные сервера заполнены и любая настройка серверных маршрутов завершена.Установка приложений
После публикации приложения (npm) или его развертывания (tarball) рабочие пространства могут установить его через интерфейс. Перейдите на страницу Настройки > Приложения в Twenty, где можно просматривать и устанавливать как приложения из маркетплейса, так и развернутые через tarball. Вы также можете устанавливать приложения из командной строки:Сервер при установке применяет версионирование semver, аналогичное правилам при развёртывании:
- Установка той же версии, которая уже установлена в вашем рабочем пространстве, отклоняется с ошибкой
APP_ALREADY_INSTALLED. - Установка версии ниже текущей отклоняется с ошибкой
CANNOT_DOWNGRADE_APPLICATION.
twenty app install.