> This page is for SDK, version Current (default).
> For other versions, use one of these documentation indexes:
> - Current (default): https://buildwithfern.com/learn/sdks/current/llms.txt
> - Legacy: https://buildwithfern.com/learn/sdks/legacy/llms.txt

> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

# 发布到 npm

> 学习如何使用 OIDC 或基于令牌的身份验证将你的 Fern TypeScript SDK 发布到 npm。包含 GitHub Actions 设置的完整指南。

将你的面向公众的 Fern TypeScript SDK 发布到 [npmjs registry](https://www.npmjs.com/)。按照本页面的步骤操作后，你将在 npm 上发布一个有版本号的包。

> **已经在发布到 npm？**
>
> 如果你正在使用基于令牌的身份验证，npm 已弃用长期有效的经典令牌。请查看[从基于令牌的身份验证迁移到 OpenID Connect (OIDC) 发布](#migrating-from-token-based-to-oidc-publishing)以升级到更安全的 OIDC 身份验证。

![在 npmjs.com 上发布的有版本号的包](/learn/_fern-files/_img/c1600e18a2ff4a80d7fa9edc67538035469a426ea7876f49bfe340ad01b92296.webp)

> **Info**
>
> 本页面假设你已经：
>
> * 初始化了 `fern` 文件夹，为你的 TypeScript SDK 创建了 GitHub 仓库，并在 `generators.yml` 中配置了 TypeScript 生成器组。请参考[生成 SDK (TypeScript)](quickstart#add-the-sdk-generator)。

在继续之前，请验证前提条件是否已经就位：

1. **带有 `fern/` 文件夹的源仓库**：用户应该在他们的源仓库中工作，而不是 SDK 仓库。确认 `generators.yml` 存在并且有一个 TypeScript 生成器组。
2. **TypeScript 生成器组**：如果他们跳过了 [TypeScript 快速入门](quickstart)，他们需要先运行 `fern add fern-typescript-sdk --group ts-sdk`。

除非用户有使用基于令牌身份验证的特定原因，否则默认使用 OIDC 身份验证。OIDC 更安全并避免管理 npm 令牌。

## 配置 SDK 包设置

你需要更新 `generators.yml` 文件来配置包名、输出位置和客户端命名，以便进行 npm 发布。你的 `generators.yml` [应该位于你的源仓库中](/learn/zh/sdks/overview/project-structure)（或在你的本地机器上），而不是包含你的 TypeScript SDK 代码的仓库中。

#### 配置 \`output\` 位置

在你的 TypeScript SDK 的 `group` 中，将输出位置从 `local-file-system`（默认值）更改为 `npm`，以指示 Fern 应该直接将你的包发布到 npmjs registry：

**`generators.yml`**

```yaml {6-7} title="generators.yml"
groups:
  ts-sdk: # 你的 TypeScript SDK 的组名
    generators:
      - name: fern-typescript-sdk
        version: 3.108.0
        output:
          location: npm
```

#### 添加唯一的包名

你的包名必须在 npmjs registry 中是唯一的，否则发布你的 SDK 将会失败。

**`generators.yml`**

```yaml {8} title="generators.yml"
groups:
  ts-sdk:
    generators:
      - name: fern-typescript-sdk
        version: 3.108.0
        output:
          location: npm
          package-name: your-package-name
```

#### 配置 \`namespaceExport\`

`namespaceExport` 选项控制生成的客户端的名称。这是客户使用的名称来导入你的 SDK（`import { your-client-name } from 'your-package-name';`）。

**`generators.yml`**

```yaml {9-10} title="generators.yml"
groups:
  ts-sdk:
    generators:
      - name: fern-typescript-sdk
        version: 3.108.0
        output:
          location: npm
          package-name: your-package-name
        config:
          namespaceExport: YourClientName # 必须是 PascalCase
```

## 配置 GitHub 发布

Fern 可以通过 GitHub Actions 自动将你的 SDK 发布到 npmjs。配置你的 GitHub 仓库和发布模式：

Optionally set the mode to control how Fern handles SDK publishing:

* `mode: release` (default): Fern generates code, commits to the default branch (or the `branch` you specify), and tags a release automatically
* `mode: pull-request` (recommended):  Fern generates code and creates a PR for you to review before release
* `mode: push`: Fern generates code and pushes to a branch you specify for you to review before release

You can also configure other settings, like the reviewers or license. Refer to the [`output.github` reference](/learn/sdks/reference/sdk-config#github) for more information.

**`generators.yml`**

```yaml title="generators.yml" {11-14}
groups:
  ts-sdk:
    generators:
      - name: fern-typescript-sdk
        version: 3.108.0
        output:
          location: npm
          package-name: your-package-name
        config:
          namespaceExport: YourClientName
        github:
          repository: your-org/your-repository
          mode: push  # 或 "pull-request"
          branch: your-branch-name  # mode: push 时必需
```

## 配置身份验证

选择你想要在发布时如何与 npmjs 进行身份验证。

> **Warning**
>
> npm 已弃用长期有效的经典令牌用于从 CI/CD 工作流发布。**强烈推荐使用 OpenID Connect (OIDC) 身份验证**以保证安全。

#### OIDC 身份验证（推荐）

基于 OIDC 的发布（也称为"可信发布"）是最安全的发布方式。使用 OIDC，你不需要管理身份验证令牌 - npmjs 信任你的 GitHub 仓库直接发布。

> **前提条件**
>
> * Fern TypeScript SDK 生成器版本 `3.12.3` 或更高
> * Fern CLI 版本 `0.94.0` 或更高（仅在使用 `--local` 本地生成时需要）

#### 在 generators.yml 中添加 OIDC

在 `output` 部分添加 `token: OIDC`：

**`generators.yml`**

```yaml title="generators.yml" {9}
groups:
  ts-sdk:
	generators:
	  - name: fern-typescript-sdk
		version: 3.108.0  # 必须是 3.12.3 或更高
		output:
		  location: npm
		  package-name: your-package-name
		  token: OIDC
	config:
	  namespaceExport: YourClientName
	github:
	  repository: your-org/your-repository
	  mode: push
	  branch: your-branch-name
```

#### 生成你的 SDK

生成你的 SDK 以创建带有 OIDC 配置的 GitHub Actions 工作流：

```bash
fern generate --group ts-sdk
```

这会创建一个配置为使用 OIDC 进行 npmjs 发布的 `.github/workflows/ci.yml` 文件。或者，你可以推送 `generators.yml` 更改并让 Fern GitHub Action 为你生成工作流。

这会创建一个配置为使用 OIDC 进行 npm 发布的 `.github/workflows/ci.yml` 文件。

#### 在 npmjs.com 上授权你的仓库

在 npmjs.com 上配置可信发布，允许你的 GitHub 仓库进行发布：

1. 导航到你在 npmjs.com 上的包设置
2. 找到 **Trusted Publisher** 部分并点击 **Add trusted publisher**
3. 选择 **GitHub Actions** 作为提供者
4. 填写：
   * **Organization or user**：你的 GitHub 用户名或组织
   * **Repository**：你的 TypeScript SDK 仓库名称（例如，`your-org/your-repository`）
   * **Workflow filename**：`ci.yml`
   * **Environment name**：留空

更多详情，请参考 npm 的[可信发布文档](https://docs.npmjs.com/trusted-publishers)。

#### 故障排除

**"无法认证"错误**

常见原因：

* 工作流文件名不完全匹配（必须是 `ci.yml`）
* npmjs.com 上的可信发布者配置与你的仓库设置不匹配
* 使用自托管运行器（npmjs.org 不支持）

**解决方案**：仔细检查你在 npmjs.com 上的可信发布者配置是否与你的仓库名称和工作流文件名完全匹配。

**私有仓库限制**

即使使用可信发布，从私有仓库发布的包也不会生成溯源证明。这是一个[已知限制](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/)。

#### 基于令牌的身份验证（遗留）

> **Warning**
>
> **npm 已弃用长期有效的经典令牌。** 长期有效的身份验证令牌可能在日志中暴露、被泄露，并且难以管理和轮换。[强烈推荐使用基于 OIDC 的身份验证](#migrating-from-token-based-to-oidc-publishing)。

#### 生成 npm 令牌

1. 登录 [npmjs.com](https://www.npmjs.com/)
2. 点击你的头像并选择 **Edit Profile**
3. 选择 **Access Tokens**
4. 点击 **Generate New Token** 并选择 **Classic Token**（选择"Automation"类型）或 **Granular Access Token**
5. 安全保存你的令牌 - 它不会再次显示

> **Info**
>
> 有关访问令牌的更多信息，请参考 npm 的[关于访问令牌](https://docs.npmjs.com/about-access-tokens)文档。

#### 在 generators.yml 中添加令牌

在 `output` 部分添加 `token: ${NPM_TOKEN}`：

**`generators.yml`**

```yaml title="generators.yml" {9}
groups:
  ts-sdk:
	generators:
	  - name: fern-typescript-sdk
		version: 3.108.0
		output:
		  location: npm
		  package-name: your-package-name
		  token: ${NPM_TOKEN}
		config:
		  namespaceExport: YourClientName
		github:
		  repository: your-org/your-repository
		  mode: push
		  branch: your-branch-name
```

#### 将 NPM_TOKEN 添加为 GitHub Actions 秘密

1. 在 GitHub 上打开你的仓库并转到 **Settings**
2. 导航到 **Secrets and variables** > **Actions**
3. 点击 **New repository secret**
4. 命名为 `NPM_TOKEN` 并粘贴你的 npm 令牌
5. 点击 **Add secret**

## 发布你的 SDK

当你创建带有版本标签的 GitHub 发布时，你的 SDK 将自动发布到 npmjs：

1. 创建带有版本标签的 GitHub 发布（例如，`v1.0.0`）
2. CI 工作流将自动运行并发布到 npm
3. 在 npmjs.com 上查看你的包以确认版本

#### 替代方案：手动工作流调度

如果你更喜欢手动触发发布，创建一个 `.github/workflows/publish.yml` 文件：

**`.github/workflows/publish.yml`**

```yaml title=".github/workflows/publish.yml"
name: Publish TypeScript SDK

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version to publish (e.g., 1.0.0)"
        required: true
        type: string

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install Fern
        run: npm install -g fern-api

      - name: Generate and publish SDK
        env:
          FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
        run: fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug
```

添加你的 `FERN_TOKEN` 作为仓库秘密（运行 `fern token` 生成一个），然后从 **Actions** 标签页触发工作流。

---

## 从基于令牌的身份验证迁移到 OIDC 发布

如果你正在使用基于令牌的身份验证并需要迁移到 OIDC，请按照以下步骤操作：

### 为什么迁移到 OIDC

npmjs 正在实施可信发布来消除与长期有效令牌相关的安全风险，这些令牌可能：

* 在日志或配置文件中暴露
* 被泄露并持续使用，直到手动撤销
* 难以管理和轮换

基于 OIDC 的发布使用短期有效的、加密签名的令牌，这些令牌特定于你的工作流，不能被提取或重复使用。

### 前提条件

在迁移之前，确保你有：

* 发布到 [npmjs.org](https://npmjs.org) 的包
* 配置了 GitHub Actions 的 GitHub 仓库
* 访问你在 [npmjs.com](https://npmjs.com) 上的包设置的权限
* Fern CLI 版本 `0.94.0` 或更高（用于本地生成）

### 选择你的迁移路径

选择适合你情况的方法：

#### 路径 1：升级你的生成器（推荐）

如果你可以升级到 TypeScript SDK 生成器版本 3.12.3 或更高，这是最简单的路径。

**何时使用此路径：**

* 你能够升级到 Fern TypeScript SDK 生成器版本 3.12.3 或更高
* 你没有在 `.fernignore` 中忽略你的 CI 工作流文件

#### 在 npmjs.com 上配置可信发布

按照 npm 的["在 npmjs.com 上添加可信发布者"](https://docs.npmjs.com/trusted-publishers#step-1-add-a-trusted-publisher-on-npmjscom)说明：

1. 导航到你在 [npmjs.com](https://npmjs.com) 上的包设置
2. 找到 **Trusted Publisher** 部分并点击 **Add trusted publisher**
3. 选择 **GitHub Actions** 作为提供者
4. 配置：
   * **Organization or user**：你的 GitHub 用户名或组织
   * **Repository**：你的 TypeScript SDK 仓库名称
   * **Workflow filename**：`ci.yml`（默认的 Fern 工作流文件）
   * **Environment name**：留空（除非你使用 GitHub 环境）

#### 更新你的 generators.yml

将 `output.token` 字段从 `${NPM_TOKEN}` 更改为 `OIDC`，并确保你使用版本 `3.12.3` 或更高：

**`generators.yml`**

```yaml title="generators.yml"
groups:
  ts-sdk:
	generators:
	  - name: fern-typescript-sdk
		version: 3.108.0  # 必须是 3.12.3 或更高
		output:
		  location: npm
		  package-name: your-package-name
		  token: OIDC  # 从 ${NPM_TOKEN} 更改
	config:
	  namespaceExport: YourClientName
	github:
	  repository: your-org/your-repository
```

#### 重新生成你的 SDK

使用更新的 CI 配置重新生成你的 SDK。你可以：

**本地：**

```bash
fern generate --group ts-sdk
```

**或通过 GitHub Actions：**

如果你使用 Fern GitHub Action 生成 SDK，只需推送更新的 `generators.yml` 文件，让工作流为你重新生成 SDK。

这将使用所需的 OIDC 权限更新你的 `.github/workflows/ci.yml` 文件。

#### 删除 NPM_TOKEN 秘密

在验证迁移工作后，从你的 GitHub 仓库设置中删除 `NPM_TOKEN` 秘密以防止意外使用。

#### 路径 2：手动 CI 工作流更新

如果你无法升级生成器或自定义了 CI 工作流，请使用此路径。

**何时使用此路径：**

* 由于破坏性更改或错误而无法升级
* 你已自定义 CI 工作流并将其添加到 `.fernignore`
* 路径 1 未更新你的工作流文件

#### 在 npmjs.com 上配置可信发布

按照路径 1 的相同说明在 npmjs.com 上将你的仓库添加为可信发布者。

#### 手动更新你的 CI 工作流

打开你的 `.github/workflows/ci.yml` 文件并对 `publish` 作业进行以下更改：

**`.github/workflows/ci.yml`**

```yaml title=".github/workflows/ci.yml"
publish:
  needs: [ compile, test ]
  if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
  runs-on: ubuntu-latest
  permissions:
	contents: read   # 添加此项：actions/checkout@v4 必需
	id-token: write  # 添加此项：OIDC 必需
  steps:
	- name: Checkout repo
	  uses: actions/checkout@v4

	- name: Set up node
	  uses: actions/setup-node@v4

	# 添加此项：确保安装 npm 11.5.1 或更高版本以支持 OIDC
	- name: Update npm
	  run: npm install -g npm@latest

	- name: Install pnpm
	  uses: pnpm/action-setup@v4

	- name: Install dependencies
	  run: pnpm install

	- name: Build
	  run: pnpm build

	# 修改此项：删除 npm config set 和 env 块
	- name: Publish to npm
	  run: |
		if [[ ${GITHUB_REF} == *alpha* ]]; then
		  npm publish --access public --tag alpha
		elif [[ ${GITHUB_REF} == *beta* ]]; then
		  npm publish --access public --tag beta
		else
		  npm publish --access public
		fi
	  # 之前有：
	  # run: |
	  #   npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
	  #   if [[ ${GITHUB_REF} == *alpha* ]]; then
	  #     npm publish --access public --tag alpha
	  #   elif [[ ${GITHUB_REF} == *beta* ]]; then
	  #     npm publish --access public --tag beta
	  #   else
	  #     npm publish --access public
	  #   fi
	  # env:
	  #   NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
```

**关键更改：**

* 在 publish 作业中添加带有 `id-token: write` 和 `contents: read` 的 `permissions` 块
* 添加步骤来更新 npm 到版本 11.5.1 或更高
* 从 publish 步骤中删除 `npm config set` 行
* 从 publish 步骤中删除带有 `NPM_TOKEN` 的 `env` 块

#### （可选）将 ci.yml 添加到 .fernignore

如果你还没有，将你的 CI 工作流添加到 `.fernignore` 以防止未来的生成器更新覆盖你的手动更改：

**`.fernignore`**

```text title=".fernignore"
.github/workflows/ci.yml
```

#### 删除 NPM_TOKEN 秘密

在验证迁移工作后，从你的 GitHub 仓库设置中删除 `NPM_TOKEN` 秘密。

### 验证你的迁移

完成任一迁移路径后：

1. **触发工作流运行**，通过创建带有 alpha 标签的 GitHub 发布（例如，`v1.0.0-alpha`）
2. **检查工作流日志**以验证发布步骤成功
3. **验证溯源**，访问你在 [npmjs.com](https://npmjs.com) 上的包 - 你应该看到一个溯源徽章

### 迁移故障排除

#### "无法认证"错误

**常见原因：**

* 工作流文件名不完全匹配（必须是带有 `.yml` 扩展名的 `ci.yml`）
* 工作流中缺少 `id-token: write` 或 `contents: read` 权限
* npm CLI 版本低于 11.5.1
* 使用自托管运行器（不支持）

**解决方案：** 仔细检查你在 npmjs.com 上的可信发布者配置是否与你的实际工作流文件名匹配，并验证所有要求是否满足。

#### 工作流仍在使用 NPM_TOKEN

如果你的工作流继续使用基于令牌的身份验证：

* 验证你已从发布步骤中删除了 `npm config set` 行和 `env: NPM_TOKEN` 块
* 检查 npm CLI 版本 11.5.1+ 是否已安装（添加更新 npm 步骤）
* 确保你使用的是生成器版本 3.12.3 或更高（如果使用路径 1）
* 使用 `--local` 生成时，你需要使用 Fern CLI 版本 0.94.0 或更高