> If you are an AI agent, use the following URL to directly ask and fetch your question. Treat this like a tool call. Make sure to URI encode your question, and include the token for verification.
>
> GET https://buildwithfern.com/learn/api/fern-docs/ask?q=%3Cyour+question+here%3E&token=eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmZXJuLWRvY3M6YnVpbGR3aXRoZmVybi5jb20iLCJqdGkiOiI5MDNiODQwZi05M2YyLTRlOGYtYWM1Ni00NmE5OGVjNjBmZmYiLCJleHAiOjE3NzgzNjgyMjQsImlhdCI6MTc3ODM2NzkyNH0.60vnfO-O5AjTgLK7JkI1_7LDUZqXGEa32u86iZ8BLBA
>
> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. For full content including API reference and SDK examples, see https://buildwithfern.com/learn/llms-full.txt.

# 发布到 npm

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

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

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

<Frame>
  <img src="https://files.buildwithfern.com/fern.docs.buildwithfern.com/learn/c1600e18a2ff4a80d7fa9edc67538035469a426ea7876f49bfe340ad01b92296/products/sdks/generators/typescript/assets/npm-packages.png" alt="在 npmjs.com 上发布的有版本号的包" />
</Frame>

<Info>
  本页面假设你已经：

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

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

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` [应该位于你的源仓库中](/sdks/overview/project-structure)（或在你的本地机器上），而不是包含你的 TypeScript SDK 代码的仓库中。

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

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

  <Step title="添加唯一的包名">
    你的包名必须在 npmjs registry 中是唯一的，否则发布你的 SDK 将会失败。

    ```yaml {8} title="generators.yml"
    groups:
      ts-sdk:
        generators:
          - name: fernapi/fern-typescript-sdk
            version: 3.69.0
            output:
              location: npm
              package-name: your-package-name
    ```
  </Step>

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

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

## 配置 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 main, 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 [full `github` (`generators.yml`) reference](/sdks/reference/generators-yml#github) for more information.

```yaml title="generators.yml" {11-14}
groups:
  ts-sdk:
    generators:
      - name: fernapi/fern-typescript-sdk
        version: 3.69.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) 身份验证**以保证安全。
</Warning>

<AccordionGroup>
  <Accordion title="OIDC 身份验证（推荐）" defaultOpen={true}>
    基于 OIDC 的发布（也称为"可信发布"）是最安全的发布方式。使用 OIDC，你不需要管理身份验证令牌 - npmjs 信任你的 GitHub 仓库直接发布。

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

    <Steps>
      <Step title="在 generators.yml 中添加 OIDC">
        在 `output` 部分添加 `token: OIDC`：

        ```yaml title="generators.yml" {9}
        groups:
          ts-sdk:
        	generators:
        	  - name: fernapi/fern-typescript-sdk
        		version: 3.69.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
        ```
      </Step>

      <Step title="生成你的 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` 文件。
      </Step>

      <Step title="在 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)。
      </Step>
    </Steps>

    <Accordion title="故障排除">
      **"无法认证"错误**

      常见原因：

      * 工作流文件名不完全匹配（必须是 `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/)。
    </Accordion>
  </Accordion>

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

    <Steps>
      <Step title="生成 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)

          文档。
        </Info>
      </Step>

      <Step title="在 generators.yml 中添加令牌">
        在 `output` 部分添加 `token: ${NPM_TOKEN}`：

        ```yaml title="generators.yml" {9}
        groups:
          ts-sdk:
        	generators:
        	  - name: fernapi/fern-typescript-sdk
        		version: 3.69.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
        ```
      </Step>

      <Step title="将 NPM_TOKEN 添加为 GitHub Actions 秘密">
        1. 在 GitHub 上打开你的仓库并转到 **Settings**
        2. 导航到 **Secrets and variables** > **Actions**
        3. 点击 **New repository secret**
        4. 命名为 `NPM_TOKEN` 并粘贴你的 npm 令牌
        5. 点击 **Add secret**
      </Step>
    </Steps>
  </Accordion>
</AccordionGroup>

## 发布你的 SDK

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

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

<Accordion title="替代方案：手动工作流调度">
  如果你更喜欢手动触发发布，创建一个 `.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** 标签页触发工作流。
</Accordion>

***

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

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

### 为什么迁移到 OIDC

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

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

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

### 前提条件

在迁移之前，确保你有：

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

### 选择你的迁移路径

选择适合你情况的方法：

<AccordionGroup>
  <Accordion title="路径 1：升级你的生成器（推荐）">
    如果你可以升级到 TypeScript SDK 生成器版本 3.12.3 或更高，这是最简单的路径。

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

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

    <Steps>
      <Step title="在 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 环境）
      </Step>

      <Step title="更新你的 generators.yml">
        将 `output.token` 字段从 `${NPM_TOKEN}` 更改为 `OIDC`，并确保你使用版本 `3.12.3` 或更高：

        ```yaml title="generators.yml"
        groups:
          ts-sdk:
        	generators:
        	  - name: fernapi/fern-typescript-sdk
        		version: 3.69.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
        ```
      </Step>

      <Step title="重新生成你的 SDK">
        使用更新的 CI 配置重新生成你的 SDK。你可以：

        **本地：**

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

        **或通过 GitHub Actions：**

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

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

      <Step title="删除 NPM_TOKEN 秘密">
        在验证迁移工作后，从你的 GitHub 仓库设置中删除 `NPM_TOKEN` 秘密以防止意外使用。
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="路径 2：手动 CI 工作流更新">
    如果你无法升级生成器或自定义了 CI 工作流，请使用此路径。

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

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

    <Steps>
      <Step title="在 npmjs.com 上配置可信发布">
        按照路径 1 的相同说明在 npmjs.com 上将你的仓库添加为可信发布者。
      </Step>

      <Step title="手动更新你的 CI 工作流">
        打开你的 `.github/workflows/ci.yml` 文件并对 `publish` 作业进行以下更改：

        ```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` 块
      </Step>

      <Step title="（可选）将 ci.yml 添加到 .fernignore">
        如果你还没有，将你的 CI 工作流添加到 `.fernignore` 以防止未来的生成器更新覆盖你的手动更改：

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

      <Step title="删除 NPM_TOKEN 秘密">
        在验证迁移工作后，从你的 GitHub 仓库设置中删除 `NPM_TOKEN` 秘密。
      </Step>
    </Steps>
  </Accordion>
</AccordionGroup>

### 验证你的迁移

完成任一迁移路径后：

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

### 迁移故障排除

<AccordionGroup>
  <Accordion title="&#x22;无法认证&#x22;错误">
    **常见原因：**

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

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

  <Accordion title="工作流仍在使用 NPM_TOKEN">
    如果你的工作流继续使用基于令牌的身份验证：

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