---
title: 发布
description: 将你的 Twenty 应用分发到应用市场，或进行内部部署。
---

<Warning>
应用目前处于 Alpha 测试阶段。 该功能可用，但仍在演进中。
</Warning>

## 概览

一旦你的应用已[在本地构建并完成测试](/l/zh/developers/extend/apps/building)，你可以通过两种方式进行分发：

* **发布到 npm** — 将你的应用在 Twenty 应用市场上架，供任何工作区发现并安装。
* **部署 tar 包** — 直接将你的应用上传到特定的 Twenty 服务器，以供内部或私有使用。

两种路径都从同一个**构建**步骤开始。

## 构建你的应用

`build` 命令会编译你的 TypeScript 源码，转译逻辑函数和前端组件，并生成一个描述你应用内容的 `manifest.json`：

```bash filename="Terminal"
yarn twenty build
```

输出将写入 `.twenty/output/`。 此目录包含分发所需的一切：已编译的代码、资源、清单，以及你的 `package.json` 副本。

要同时创建一个 `.tgz` 压缩包（由部署命令在内部使用，或用于手动分发）：

```bash filename="Terminal"
yarn twenty build --tarball
```

## 发布到 npm

发布到 npm 可让你的应用在 Twenty 应用市场中被发现。 任何 Twenty 工作区都可以直接通过 UI 浏览、安装和升级应用市场中的应用。

### 要求

* 一个 [npm](https://www.npmjs.com) 账户
* 在你的 `package.json` 的 `keywords` 数组中**必须**包含 `twenty-app` 关键字

### 添加所需关键字

Twenty 市场通过在 npm 注册表中搜索带有 `twenty-app` 关键字的包来发现应用。 将其添加到你的 `package.json`：

```json filename="package.json"
{
  "name": "twenty-app-postcard-sender",
  "version": "1.0.0",
  "keywords": ["twenty-app"],
  ...
}
```

<Note>
该市场会在 npm 注册表中搜索 `keywords:twenty-app`。 没有此关键字，即使包名带有 `twenty-app-` 前缀，你的包也不会出现在市场中。
</Note>

### 步骤

1. **构建你的应用：**

```bash filename="Terminal"
yarn twenty build
```

2. **发布到 npm：**

```bash filename="Terminal"
yarn twenty publish
```

这会在 `.twenty/output/` 目录下运行 `npm publish`。

要在特定的 dist-tag（例如 `beta` 或 `next`）下发布：

```bash filename="Terminal"
yarn twenty publish --tag beta
```

### 应用市场的发现机制如何运作

Twenty 服务器会**每小时**从 npm 注册表同步其市场目录：

1. 它会搜索所有带有 `keywords:twenty-app` 关键字的 npm 包
2. 对于每个包，它会从 npm CDN 获取 `manifest.json`
3. 应用的元数据（名称、描述、作者、徽标、屏幕截图、类别）将从清单中提取，并显示在市场中

发布后，你的应用最多可能需要一小时才会出现在市场中。 要立即触发同步，而无需等待下一次每小时同步：

```bash filename="Terminal"
yarn twenty catalog-sync
```

要指定特定的远程：

```bash filename="Terminal"
yarn twenty catalog-sync -r production
```

市场中显示的元数据来自你在应用源代码中调用的 `defineApplication()` —— 诸如 `displayName`、`description`、`author`、`category`、`logoUrl`、`screenshots`、`aboutDescription`、`websiteUrl` 和 `termsUrl` 等字段。

### CI 发布

脚手架项目包含一个 GitHub Actions 工作流，会在每次发版时自动发布：

```yaml filename=".github/workflows/publish.yml"
name: Publish
on:
  release:
    types: [published]

permissions:
  contents: read
  id-token: write

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "24"
          registry-url: https://registry.npmjs.org
      - run: yarn install --immutable
      - run: npx twenty build
      - run: npm publish --provenance --access public
        working-directory: .twenty/output
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```

对于其他 CI 系统（GitLab CI、CircleCI 等），同样适用以下三条命令：`yarn install`、`yarn twenty build`，然后在 `.twenty/output` 目录下执行 `npm publish`。

<Tip>
**npm provenance** 可选，但建议启用。 使用 `--provenance` 发布会在你的 npm 列表中添加可信徽章，使用户可以验证该包是由公共 CI 流水线中的特定提交构建的。 有关设置说明，请参见 [npm provenance 文档](https://docs.npmjs.com/generating-provenance-statements)。
</Tip>

## 部署到服务器（tar 包）

对于你不希望公开的应用（专有工具、仅供企业使用的集成或实验性构建），你可以将 tar 包直接部署到某台 Twenty 服务器。

### 先决条件

在部署之前，你需要配置一个指向目标服务器的远程。 远程会将服务器 URL 和身份验证凭据本地存储在 `~/.twenty/config.json` 中。

添加远程：

```bash filename="Terminal"
yarn twenty remote add --url https://your-twenty-server.com --as production
```

对于本地开发服务器：

```bash filename="Terminal"
yarn twenty remote add --local --as local
```

对于非交互式环境，你也可以使用 API 密钥进行身份验证：

```bash filename="Terminal"
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
```

管理你的远程：

```bash filename="Terminal"
yarn twenty remote list       # List all configured remotes
yarn twenty remote switch prod # Set the default remote
yarn twenty remote status     # Show active remote and auth status
yarn twenty remote remove old # Remove a remote
```

### 部署

一步构建并将你的应用上传到服务器：

```bash filename="Terminal"
yarn twenty deploy
```

这会使用 `--tarball` 构建应用，然后通过 GraphQL 多部分上传将该 tar 包上传到默认远程。

部署到特定远程：

```bash filename="Terminal"
yarn twenty deploy -r production
```

### 共享已部署的应用

通过 tar 包分发的应用不会出现在公共市场中，因此同一服务器上的其他工作区无法通过浏览发现它们。 要共享已部署的应用：

1. 前往 **Settings > Applications > Registrations** 并打开你的应用
2. 在 **Distribution** 选项卡中，点击 **Copy share link**
3. 将此链接分享给其他工作区的用户 — 它会将他们直接带到该应用的安装页面

该分享链接使用服务器的基础 URL（不包含任何工作区子域），因此适用于该服务器上的任意工作区。

### 版本管理

要发布更新：

1. 更新 `package.json` 中的 `version` 字段
2. 运行 `yarn twenty deploy`（或 `yarn twenty deploy -r production`）
3. 已安装该应用的工作区会在其设置中看到可用的升级

## 安装应用

一旦应用已发布（npm）或已部署（tar 包），各工作区即可通过 UI 进行安装：

```bash filename="Terminal"
yarn twenty install
```

或者在 Twenty UI 的 **Settings > Applications** 页面中浏览并安装来自市场或通过 tar 包部署的应用。

## 应用分发类别

Twenty 会根据分发方式将应用归为三类：

| 类别            | 工作原理                                               | 在应用市场中可见？ |
| ------------- | -------------------------------------------------- | --------- |
| **开发**        | 通过 `yarn twenty dev` 运行的本地开发模式应用。 用于构建和测试。         | 否         |
| **已发布（npm）**  | 发布到 npm 且包含 `twenty-app` 关键字的应用。 在应用市场上架，供任何工作区安装。 | 是         |
| **内部（tar 包）** | 通过 tar 包部署到特定服务器的应用。 仅通过分享链接对该服务器上的工作区可用。          | 否         |

<Tip>
在构建你的应用时，从**开发**模式开始。 准备就绪后，选择用于广泛分发的**已发布**（npm），或用于私有部署的**内部**（tar 包）。
</Tip>

## CLI 参考

| 命令                          | 描述               | 关键选项                                        |
| --------------------------- | ---------------- | ------------------------------------------- |
| `yarn twenty build`         | 编译应用并生成清单        | `--tarball` — 同时创建一个 `.tgz` 包               |
| `yarn twenty publish`       | 构建并发布到 npm       | `--tag <tag>` — npm 分发标签（例如 `beta`、`next`）  |
| `yarn twenty deploy`        | 构建并将 tar 包上传到服务器 | `-r, --remote <name>` — 目标远程                |
| `yarn twenty catalog-sync`  | 在服务器上触发市场目录同步    | `-r, --remote <name>` — 目标远程                |
| `yarn twenty install`       | 在某个工作区安装已部署的应用   | `-r, --remote <name>` — 目标远程                |
| `yarn twenty dev`           | 监听并同步本地更改        | 使用默认远程                                      |
| `yarn twenty remote add`    | 添加服务器连接          | `--url`，`--token`，`--as`，`--local`，`--port` |
| `yarn twenty remote list`   | 列出已配置的远程         | —                                           |
| `yarn twenty remote switch` | 设置默认远程           | —                                           |
| `yarn twenty remote status` | 显示连接状态           | —                                           |
| `yarn twenty remote remove` | 移除远程             | —                                           |
