From 258c8b07f49504cc1d5b67f582a4ba58ede0dafa Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Wed, 23 Jul 2025 11:13:30 -0400 Subject: [PATCH 1/6] page setup for github guide --- fern/products/sdks/github-setup.mdx | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 fern/products/sdks/github-setup.mdx diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx new file mode 100644 index 000000000..d272e3d52 --- /dev/null +++ b/fern/products/sdks/github-setup.mdx @@ -0,0 +1,4 @@ +--- +title: Set up your GitHub Structure +description: +--- \ No newline at end of file From f82cdb2516d9053eb441dbe19a4fbf1ae758581b Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 28 Jul 2025 14:26:57 -0400 Subject: [PATCH 2/6] add github actions workflow for npm publishing page --- fern/products/sdks/github-setup.mdx | 65 ++++++- .../overview/typescript/publishing-to-npm.mdx | 176 +++++++++++++----- fern/products/sdks/sdks.yml | 3 + 3 files changed, 193 insertions(+), 51 deletions(-) diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx index d272e3d52..18c992258 100644 --- a/fern/products/sdks/github-setup.mdx +++ b/fern/products/sdks/github-setup.mdx @@ -1,4 +1,67 @@ --- title: Set up your GitHub Structure description: ---- \ No newline at end of file +--- + +next steps for this: +-try this flow out for typescript +-put GitHub actions info into snippet +-put token info directly into npm page? +-understand where GitHub architecture should fit with docs as a whole. in overview section? + + + + +## Overall GitHub structure + +Structure the top-level GitHub repository containing all of your SDKs and APIs +so it's intuitive for you and your users to access, maintain, and update. + +For example: + +``` +--fern + apis + generators.yml + openapi-overrides.yml + openapi.json +``` +your `generators.yml` file has a group for each of your SDKs. Each group points +to the GitHub repository for the relevant SDK: + +``` +github: + repository: organization/repo-name +``` + +### GitHub structure for a specific SDK + +The repository structure for a specific SDK should look similar to this: + +``` +sdk-repo-name (company-typescript or similar) +.github/workflows/ +scripts/ +src/ +tests/ +.fernignore +``` + +Fern generates the SDK files in this repository (scripts/, src/, tests, +.fernignore, etc), including any custom code you added. Depending on your GitHub +configuration (link), Fern commits, makes a pull request, or pushes the code to +a branch. + +You have to manually set up .github/workflows to execute actions, like +publishing SDK versions to a package repository. + +Configure your GitHub to specify that Fern should commit and release, create a +pull request, or push code to a branch when you make changes to your SDK code. + +## Set up your GitHub integration + + 1. Create a new GitHub repository called `company-typescript` (or something similar) for your SDK, if you haven't done so already. + 1. Install the [Fern GitHub App](https://github.com/apps/fern-api): Select **Configure**, then scroll down to **Repository Access**. Select **Only select repositories** and in the dropdown select the repository for your SDK. Click **Save**. + + + diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 4605c4a4e..8487800c4 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -11,52 +11,27 @@ you'll have a versioned package published on npm. Versioned package published on npm - +## Prerequisites -## Set up your GitHub integration +This page assumes that you have: - 1. Create a new GitHub repository called `company-typescript` (or something similar) for your SDK, if you haven't done so already. - 1. Install the [Fern GitHub App](https://github.com/apps/fern-api): Select **Configure**, then scroll down to **Repository Access**. Select **Only select repositories** and in the dropdown select the repository for your SDK. Click **Save**. - +* An initialized `fern` folder on your local machine. See [Set up the `fern` + folder](/sdks/overview/quickstart). +* A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). +* A TypeScript generator group in `generators.yml`. See [TypeScript + Quickstart](quickstart#add-the-sdk-generator). ## Configure `generators.yml` - - - Navigate to your `generators.yml` on your local machine. Your `generators.yml` lives inside of your `fern` folder and contains all the configuration for your Fern generators. - - Add a new generator to `generators.yml`: - - - ```bash - fern add fern-typescript-sdk --group ts-sdk - ``` - - Once the command completes, you'll see a new group created in your `generators.yml`: - - ```yaml {3-9} - groups: - ... - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: - output: - location: local-file-system - path: ../sdks/typescript - ``` - - - - Next, change the output location in `generators.yml` from `local-file-system` (the default) to `npm` to indicate that Fern should publish your package directly to the npm registry: + In the `group` for your TypeScript SDK, change the output location in from `local-file-system` (the default) to `npm` to indicate that Fern should publish your package directly to the npm registry: ```yaml {6-7} groups: - ts-sdk: + ts-sdk: # Group name for your TypeScript SDK generators: - name: fernapi/fern-typescript-sdk version: @@ -126,7 +101,7 @@ groups: -## Set up npm publishing authentication +## Generate an npm token @@ -184,6 +159,115 @@ groups: + + +## Configure npm authentication + + + + +Alternatively, you can use GitHub Actions automatically publish new versions of your SDK to npm. When you push new SDK code changes +GitHub actions allow you to automatically trigger releases for your SDKs and automatically push new releases to relevant package managers. +example: https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml + +For more information, see GitHub's quickstart guide: https://docs.github.com/en/actions/get-started/quickstart + + + + + + Open your Fern repository in GitHub. + + + + + + Click on the **Settings** tab in your repository. Then, under the **Security** section, open **Secrets and variables** > **Actions**. + + + Adding GitHub Repository Secret + + + You can also use the url `https://github.com//settings/secrets/actions`. + + + + + + 1. Select **New repository secret**. + 1. Name your secret `NPM_TOKEN`. + 1. Add the corresponding token you generated above. + 1. Click **Add secret**. + + + + + + 1. Generate a Fern token by running `fern token` and saving the token id. + 1. Select **New repository secret**. + 1. Name your secret `FERN_TOKEN`. + 1. Add the corresponding token you generated above. + 1. Click **Add secret**. + + + + + + Change your workflow permissions to allow GitHub to run workflows: + + 1. Click on the **Settings** tab in your repository. + 1. Under the **Code and automation** section, navigate to **Actions** > **General**. + 1. Under **Actions permissions**, select **Allow all actions and reusable workflows**. + 1. **Save** your settings. Now GitHub can run any actions you configure. + + + + + Add a GitHub Action to trigger releases for your SDK. + + Navigate to the **Actions** tab in your repositiory and select **set up a workflow yourself**. GitHub will automatically set up a blank yml file in a new `.github/workflows` directory. + + Rename this file `publish-typescript-sdk.yml` (or something similar). Your file should look like this: + + + ```yaml title="TypeScript" maxLines=0 + name: Publish TypeScript SDK + + on: + workflow_dispatch: + inputs: + version: + description: "The version of the TypeScript SDK that you would like to release" + required: true + type: string + + jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install Fern CLI + run: npm install -g fern-api + + - name: Release TypeScript SDK + env: + FERN_TOKEN: ${{ secrets.FERN_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug + ``` + + + Once your workflow is configured, add github/workflow/ci.yml files to .fernignore so regenerating releases doesn't overwrite your workflow. + + + + + + + Add `token: ${NPM_TOKEN}` to `generators.yml` to tell Fern to use the `NPM_TOKEN` environment variable for authentication when publishing to the npm registry. @@ -204,15 +288,6 @@ groups: repository: your-org/your-repository ``` - - - -## Release your SDK to NPM - - At this point, you're ready to generate a release for your SDK. - - - Set the `NPM_TOKEN` environment variable on your local machine: @@ -222,8 +297,13 @@ groups: ``` + + + + - + +## Release your SDK to npm Regenerate your SDK and publish it on npm: @@ -232,8 +312,4 @@ groups: ``` Local machine output will verify that the release is pushed to your repository and tagged with the version you specified. Log back into npm and - navigate to **Packages** to see your new release. - - - - \ No newline at end of file + navigate to **Packages** to see your new release. \ No newline at end of file diff --git a/fern/products/sdks/sdks.yml b/fern/products/sdks/sdks.yml index b48ae588d..2ebfda420 100644 --- a/fern/products/sdks/sdks.yml +++ b/fern/products/sdks/sdks.yml @@ -7,6 +7,9 @@ navigation: - page: Quickstart path: ./fern-folder.mdx slug: quickstart + - page: GitHub Setup + path: ./github-setup.mdx + slug: github - page: Capabilities path: ./capabilities.mdx slug: capabilities From c54c826b8079d6d32354f92ac2b1c5c1da7eb8b3 Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 28 Jul 2025 17:18:10 -0400 Subject: [PATCH 3/6] add github architecture doc and edit npm publishing guide --- fern/products/sdks/github-setup.mdx | 94 ++++++----- .../overview/typescript/publishing-to-npm.mdx | 156 ++++++++++-------- .../sdks/overview/typescript/quickstart.mdx | 12 +- 3 files changed, 150 insertions(+), 112 deletions(-) diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx index 18c992258..57b696bf0 100644 --- a/fern/products/sdks/github-setup.mdx +++ b/fern/products/sdks/github-setup.mdx @@ -1,67 +1,81 @@ --- title: Set up your GitHub Structure -description: +description: Set up GitHub repositories for your SDKs --- -next steps for this: --try this flow out for typescript --put GitHub actions info into snippet --put token info directly into npm page? --understand where GitHub architecture should fit with docs as a whole. in overview section? - +Before generating SDKs with Fern, you'll need to set up the proper GitHub repository structure to house your API definitions and SDK code. +## Create or identify your GitHub repositories + 1. Identify or create a top-level GitHub repository where you want all of your SDK and API code to live. + 1. Create a new GitHub repository called `company-` (or something similar) for each of your SDKs, if you haven't done so already. + 1. Install the [Fern GitHub App](https://github.com/apps/fern-api) on the top-level repository and all SDK repositories. Select **Configure**, then scroll down to **Repository Access**. Select **Only select repositories** and in the dropdown select the repository for your SDK. Click **Save**. ## Overall GitHub structure Structure the top-level GitHub repository containing all of your SDKs and APIs so it's intuitive for you and your users to access, maintain, and update. -For example: +For example, your basic GitHub file structure should look something like this: ``` ---fern - apis - generators.yml - openapi-overrides.yml - openapi.json -``` -your `generators.yml` file has a group for each of your SDKs. Each group points -to the GitHub repository for the relevant SDK: - +├─ company-repo # Top-level repo for all SDKs + ├─ fern/ + ├─ apis/ + ├─ sdks/ + └── generators.yml # Contains settings for all SDKs ``` -github: - repository: organization/repo-name +your `generators.yml` file will contain a group for each of your SDKs. Each group points +to the GitHub repository for the relevant SDK. + +For example, the `group` for a TypeScript SDK might look like this: + +```yaml title="generators.yml" + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: 2.6.3 + github: + repository: your-organization/your-typescript-repo ``` -### GitHub structure for a specific SDK +For additional examples, see Cohere's [`generators.yml` +file](https://github.com/cohere-ai/cohere-developer-experience/blob/23d6c541a01eb6b54dd9bb3588c805bb0e307713/fern/apis/sdks/generators.yml) +and Vapi's [`generators.yml` +file](https://github.com/VapiAI/docs/blob/9c674c2b16ba03e864e26673c5290c88048c9a7a/fern/apis/api/generators.yml). -The repository structure for a specific SDK should look similar to this: +To get started configuring your SDK, see the Quickstart -``` -sdk-repo-name (company-typescript or similar) -.github/workflows/ -scripts/ -src/ -tests/ -.fernignore -``` +You can also additionally configure the `github` section to whether Fern +should commit and release, create a pull request, or push code to a branch when +you make changes to your SDK code. See [GitHub +Configuration](/sdks/reference/generators-yml#github-configuration) for more +details. -Fern generates the SDK files in this repository (scripts/, src/, tests, -.fernignore, etc), including any custom code you added. Depending on your GitHub -configuration (link), Fern commits, makes a pull request, or pushes the code to -a branch. +### Structure a repository for a specific SDK -You have to manually set up .github/workflows to execute actions, like -publishing SDK versions to a package repository. +The repository structure for a specific SDK should look similar to this: -Configure your GitHub to specify that Fern should commit and release, create a -pull request, or push code to a branch when you make changes to your SDK code. +```{6-11} +├─ company-repo # Top-level repo for all SDKs + ├─ fern/ + ├─ apis/ + ├─ sdks/ + └── generators.yml # Contains settings for all SDKs + ├─ typescript-sdk-repo # Repository for a TypeScript SDK + ├─ .github/workflows/ # Contains GitHub Actions for publishing to package repositories, etc. + ├─ scripts/ + ├─ src/ + ├─ tests/ + └── .fernignore # Lists files that Fern shouldn't modify + ├─ python-sdk-repo + └── go-sdk-repo +``` -## Set up your GitHub integration +Fern generates most of the SDK files listed in this example repository (`scripts/`, `src/`, `tests`, +`.fernignore`, etc.), including any custom code you added. You have to manually set up `.github/workflows` to execute actions, like publishing SDK versions to a package repository. - 1. Create a new GitHub repository called `company-typescript` (or something similar) for your SDK, if you haven't done so already. - 1. Install the [Fern GitHub App](https://github.com/apps/fern-api): Select **Configure**, then scroll down to **Repository Access**. Select **Only select repositories** and in the dropdown select the repository for your SDK. Click **Save**. +For additional examples, see Cohere's [Python SDK repository](https://github.com/cohere-ai/cohere-python) and [Vapi's TypeScript SDK repository](https://github.com/VapiAI/server-sdk-typescript). diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 8487800c4..5598b23b4 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -11,15 +11,16 @@ you'll have a versioned package published on npm. Versioned package published on npm -## Prerequisites + + This page assumes that you have: -This page assumes that you have: + * An initialized `fern` folder on your local machine. See [Set up the `fern` + folder](/sdks/overview/quickstart). + * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). + * A TypeScript generator group in `generators.yml`. See [TypeScript + Quickstart](quickstart#add-the-sdk-generator). -* An initialized `fern` folder on your local machine. See [Set up the `fern` - folder](/sdks/overview/quickstart). -* A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). -* A TypeScript generator group in `generators.yml`. See [TypeScript - Quickstart](quickstart#add-the-sdk-generator). + ## Configure `generators.yml` @@ -81,7 +82,7 @@ groups: - Add the path to your GitHub repository to `generators.yml`: + Add the path to your GitHub repository to `generators.yml`, if you haven't already: ```yaml {11-12} groups: @@ -166,23 +167,13 @@ groups: -Alternatively, you can use GitHub Actions automatically publish new versions of your SDK to npm. When you push new SDK code changes -GitHub actions allow you to automatically trigger releases for your SDKs and automatically push new releases to relevant package managers. -example: https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml - -For more information, see GitHub's quickstart guide: https://docs.github.com/en/actions/get-started/quickstart +Use [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) to automatically publish new SDK versions to npm when you push code changes. - - - Open your Fern repository in GitHub. - - - - Click on the **Settings** tab in your repository. Then, under the **Security** section, open **Secrets and variables** > **Actions**. + Open your Fern repository in GitHub. Click on the **Settings** tab in your repository. Then, under the **Security** section, open **Secrets and variables** > **Actions**. Adding GitHub Repository Secret @@ -192,7 +183,7 @@ For more information, see GitHub's quickstart guide: https://docs.github.com/en/ - + 1. Select **New repository secret**. 1. Name your secret `NPM_TOKEN`. @@ -201,16 +192,6 @@ For more information, see GitHub's quickstart guide: https://docs.github.com/en/ - - - 1. Generate a Fern token by running `fern token` and saving the token id. - 1. Select **New repository secret**. - 1. Name your secret `FERN_TOKEN`. - 1. Add the corresponding token you generated above. - 1. Click **Add secret**. - - - Change your workflow permissions to allow GitHub to run workflows: @@ -218,49 +199,86 @@ For more information, see GitHub's quickstart guide: https://docs.github.com/en/ 1. Click on the **Settings** tab in your repository. 1. Under the **Code and automation** section, navigate to **Actions** > **General**. 1. Under **Actions permissions**, select **Allow all actions and reusable workflows**. - 1. **Save** your settings. Now GitHub can run any actions you configure. + 1. **Save** your settings. Now GitHub can run the actions you configure. - - - Add a GitHub Action to trigger releases for your SDK. - - Navigate to the **Actions** tab in your repositiory and select **set up a workflow yourself**. GitHub will automatically set up a blank yml file in a new `.github/workflows` directory. - - Rename this file `publish-typescript-sdk.yml` (or something similar). Your file should look like this: - - - ```yaml title="TypeScript" maxLines=0 - name: Publish TypeScript SDK - - on: - workflow_dispatch: - inputs: - version: - description: "The version of the TypeScript SDK that you would like to release" - required: true - type: string - - jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Install Fern CLI - run: npm install -g fern-api + + + Use GitHub Actions to set up a workflow that automatically publishes your new releases to npm. + + To get started, navigate to the **Actions** tab in your repositiory and select **set up a workflow yourself**. GitHub will automatically set up a blank yml file in a new `.github/workflows` directory. + + Rename this file `ci.yml`. Your file should look like this: + + ```yaml title=".github/workflows/ci.yml" maxLines=0 +name: ci + +on: [push] + +jobs: + compile: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn build + + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn test + + publish: + needs: [ compile, test ] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up node + uses: actions/setup-node@v3 + - name: Install dependencies + run: yarn install + - name: Build + run: yarn build + + - name: Publish to npm + 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 }} + ``` - - name: Release TypeScript SDK - env: - FERN_TOKEN: ${{ secrets.FERN_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug - ``` + For another example, see Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) + - Once your workflow is configured, add github/workflow/ci.yml files to .fernignore so regenerating releases doesn't overwrite your workflow. + Once your workflow is configured, add your new workflow file to `.fernignore` so regenerating releases doesn't overwrite your workflow. + + ```diff title=".fernignore" + + .github/workflows/ci.yml + ``` diff --git a/fern/products/sdks/overview/typescript/quickstart.mdx b/fern/products/sdks/overview/typescript/quickstart.mdx index 58ede0763..f3a974160 100644 --- a/fern/products/sdks/overview/typescript/quickstart.mdx +++ b/fern/products/sdks/overview/typescript/quickstart.mdx @@ -5,13 +5,19 @@ description: Get started quickly with the Fern TypeScript SDK. Generate a TypeScript SDK by following the instructions on this page. - + + This page assumes that you have: + + * An initialized `fern` folder on your local machine. See [Set up the `fern` + folder](/sdks/overview/quickstart). + * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). + -### Add the SDK generator +## Add the SDK generator Run the following command to add the TypeScript SDK generator to `generators.yml`: @@ -37,7 +43,7 @@ This command adds the following `group` to `generators.yml`: location: local-file-system path: ../sdks/typescript ``` -### Generate the SDK +## Generate the SDK Run the following command to generate your SDK: From 194726249ce3e5d05e5ad993652d347d0c833b26 Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 28 Jul 2025 17:41:02 -0400 Subject: [PATCH 4/6] edit github structure page --- fern/products/sdks/github-setup.mdx | 58 ++++++--- .../typescript/assets/npm-token-secret.png | Bin 0 -> 50510 bytes .../overview/typescript/publishing-to-npm.mdx | 120 +++++++++--------- 3 files changed, 105 insertions(+), 73 deletions(-) create mode 100644 fern/products/sdks/overview/typescript/assets/npm-token-secret.png diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx index 57b696bf0..a856d33b9 100644 --- a/fern/products/sdks/github-setup.mdx +++ b/fern/products/sdks/github-setup.mdx @@ -3,18 +3,19 @@ title: Set up your GitHub Structure description: Set up GitHub repositories for your SDKs --- -Before generating SDKs with Fern, you'll need to set up the proper GitHub repository structure to house your API definitions and SDK code. +Before generating SDKs with Fern, you'll need to set up the proper GitHub +repository structure to house your API definitions and SDK code so it's +intuitive for you and your users to access, maintain, and update code. -## Create or identify your GitHub repositories + +## Structuring your top-level repository - 1. Identify or create a top-level GitHub repository where you want all of your SDK and API code to live. - 1. Create a new GitHub repository called `company-` (or something similar) for each of your SDKs, if you haven't done so already. - 1. Install the [Fern GitHub App](https://github.com/apps/fern-api) on the top-level repository and all SDK repositories. Select **Configure**, then scroll down to **Repository Access**. Select **Only select repositories** and in the dropdown select the repository for your SDK. Click **Save**. - -## Overall GitHub structure - -Structure the top-level GitHub repository containing all of your SDKs and APIs -so it's intuitive for you and your users to access, maintain, and update. +1. Identify or create a top-level GitHub repository where you want all of your + SDK and API code to live. +1. Install the [Fern GitHub App](https://github.com/apps/fern-api) on the + top-level repository and all SDK repositories. Select **Configure**, then + scroll down to **Repository Access**. Select **Only select repositories** and + in the dropdown select the repository for your SDK. Click **Save**. For example, your basic GitHub file structure should look something like this: @@ -25,7 +26,7 @@ For example, your basic GitHub file structure should look something like this: ├─ sdks/ └── generators.yml # Contains settings for all SDKs ``` -your `generators.yml` file will contain a group for each of your SDKs. Each group points +Your `generators.yml` file will contain a group for each of your SDKs. Each group points to the GitHub repository for the relevant SDK. For example, the `group` for a TypeScript SDK might look like this: @@ -44,15 +45,21 @@ file](https://github.com/cohere-ai/cohere-developer-experience/blob/23d6c541a01e and Vapi's [`generators.yml` file](https://github.com/VapiAI/docs/blob/9c674c2b16ba03e864e26673c5290c88048c9a7a/fern/apis/api/generators.yml). -To get started configuring your SDK, see the Quickstart - You can also additionally configure the `github` section to whether Fern should commit and release, create a pull request, or push code to a branch when you make changes to your SDK code. See [GitHub Configuration](/sdks/reference/generators-yml#github-configuration) for more details. -### Structure a repository for a specific SDK +## Structuring SDK-specific repositories + +1. Create a new GitHub repository called `company-` (or something + similar) for each of your SDKs, if you haven't done so already. +1. Install the [Fern GitHub App](https://github.com/apps/fern-api) on the + top-level repository and all SDK repositories. Select **Configure**, then + scroll down to **Repository Access**. Select **Only select repositories** and + in the dropdown select the repository for your SDK. Click **Save**. + The repository structure for a specific SDK should look similar to this: @@ -77,5 +84,26 @@ Fern generates most of the SDK files listed in this example repository (`scripts For additional examples, see Cohere's [Python SDK repository](https://github.com/cohere-ai/cohere-python) and [Vapi's TypeScript SDK repository](https://github.com/VapiAI/server-sdk-typescript). - +## Generate an SDK in your desired language + +Once you've set up your GitHub repository structure, you can proceed with generating SDKs in your desired languages. + + + } href="/sdks/generators/typescript/quickstart"> + + } href="/sdks/generators/python/quickstart"> + + } href="/sdks/generators/go/quickstart"> + + } href="/sdks/generators/java/quickstart"> + + } href="/sdks/generators/csharp/quickstart"> + + } href="/sdks/generators/php/quickstart"> + + } href="/sdks/generators/php/quickstart"> + + + + diff --git a/fern/products/sdks/overview/typescript/assets/npm-token-secret.png b/fern/products/sdks/overview/typescript/assets/npm-token-secret.png new file mode 100644 index 0000000000000000000000000000000000000000..b071b8df8fca3f4a261e52e41d74fc7d5ccd659c GIT binary patch literal 50510 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 Fe*maYxB&nF literal 0 HcmV?d00001 diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 5598b23b4..12ff0157c 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -190,9 +190,13 @@ Use [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) 1. Add the corresponding token you generated above. 1. Click **Add secret**. + + NPM_TOKEN secret + + - + Change your workflow permissions to allow GitHub to run workflows: @@ -211,63 +215,63 @@ Use [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) Rename this file `ci.yml`. Your file should look like this: ```yaml title=".github/workflows/ci.yml" maxLines=0 -name: ci - -on: [push] - -jobs: - compile: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v3 - - - name: Compile - run: yarn && yarn build - - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v3 - - - name: Compile - run: yarn && yarn test - - publish: - needs: [ compile, test ] - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - name: Set up node - uses: actions/setup-node@v3 - - name: Install dependencies - run: yarn install - - name: Build - run: yarn build - - - name: Publish to npm - 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 }} + name: ci + + on: [push] + + jobs: + compile: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn build + + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn test + + publish: + needs: [ compile, test ] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up node + uses: actions/setup-node@v3 + - name: Install dependencies + run: yarn install + - name: Build + run: yarn build + + - name: Publish to npm + 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 }} ``` For another example, see Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) From aa8d9c2f14f4add9682671b93826462852a62ebe Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 28 Jul 2025 17:46:21 -0400 Subject: [PATCH 5/6] edit language and links --- fern/products/sdks/fern-folder.mdx | 21 +++---------------- fern/products/sdks/github-setup.mdx | 2 +- .../overview/typescript/publishing-to-npm.mdx | 2 +- .../sdks/overview/typescript/quickstart.mdx | 2 +- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/fern/products/sdks/fern-folder.mdx b/fern/products/sdks/fern-folder.mdx index 02be7ced0..a2053ea6d 100644 --- a/fern/products/sdks/fern-folder.mdx +++ b/fern/products/sdks/fern-folder.mdx @@ -30,24 +30,9 @@ in different languages. {/* */} - ### Generate an SDK in your desired language - - - } href="/sdks/generators/typescript/quickstart"> - - } href="/sdks/generators/python/quickstart"> - - } href="/sdks/generators/go/quickstart"> - - } href="/sdks/generators/java/quickstart"> - - } href="/sdks/generators/csharp/quickstart"> - - } href="/sdks/generators/php/quickstart"> - - } href="/sdks/generators/php/quickstart"> - - + ### Set up GitHub + + Now, you're ready to [set up your GitHub repositories](/sdks/overview/github). diff --git a/fern/products/sdks/github-setup.mdx b/fern/products/sdks/github-setup.mdx index a856d33b9..737154be9 100644 --- a/fern/products/sdks/github-setup.mdx +++ b/fern/products/sdks/github-setup.mdx @@ -1,5 +1,5 @@ --- -title: Set up your GitHub Structure +title: Structure your GitHub repositories description: Set up GitHub repositories for your SDKs --- diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 12ff0157c..e85a9fd56 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -16,7 +16,7 @@ you'll have a versioned package published on npm. * An initialized `fern` folder on your local machine. See [Set up the `fern` folder](/sdks/overview/quickstart). - * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). + * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/overview/github). * A TypeScript generator group in `generators.yml`. See [TypeScript Quickstart](quickstart#add-the-sdk-generator). diff --git a/fern/products/sdks/overview/typescript/quickstart.mdx b/fern/products/sdks/overview/typescript/quickstart.mdx index f3a974160..a9a15e6e4 100644 --- a/fern/products/sdks/overview/typescript/quickstart.mdx +++ b/fern/products/sdks/overview/typescript/quickstart.mdx @@ -10,7 +10,7 @@ Generate a TypeScript SDK by following the instructions on this page. * An initialized `fern` folder on your local machine. See [Set up the `fern` folder](/sdks/overview/quickstart). - * A GitHub repository for your TypeScript SDK. See [Set up your GitHub structure](/sdks/github). + * A GitHub repository for your TypeScript SDK. See [Set up your GitHub repositories](/sdks/overview/github). From 18509f997e8dbf345c1a7245ee52c4cac1df2d10 Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Wed, 30 Jul 2025 13:53:38 -0400 Subject: [PATCH 6/6] remove manual github actions step --- .../overview/typescript/publishing-to-npm.mdx | 99 ++++--------------- 1 file changed, 21 insertions(+), 78 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index e85a9fd56..c06ccfc13 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -94,7 +94,7 @@ groups: location: npm package-name: your-package-name config: - namespaceExport: your-client-name + namespaceExport: YourClientName github: repository: your-org/company-typescript ``` @@ -206,84 +206,27 @@ Use [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) 1. **Save** your settings. Now GitHub can run the actions you configure. - - - Use GitHub Actions to set up a workflow that automatically publishes your new releases to npm. - - To get started, navigate to the **Actions** tab in your repositiory and select **set up a workflow yourself**. GitHub will automatically set up a blank yml file in a new `.github/workflows` directory. - - Rename this file `ci.yml`. Your file should look like this: - - ```yaml title=".github/workflows/ci.yml" maxLines=0 - name: ci - - on: [push] - - jobs: - compile: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v3 - - - name: Compile - run: yarn && yarn build - - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v3 - - - name: Compile - run: yarn && yarn test - - publish: - needs: [ compile, test ] - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - name: Set up node - uses: actions/setup-node@v3 - - name: Install dependencies - run: yarn install - - name: Build - run: yarn build - - - name: Publish to npm - 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 }} + + + Add `token: ${NPM_TOKEN}` to `generators.yml` to tell Fern to use the `NPM_TOKEN` environment variable (which you just configured in your GitHub repo) for authentication when publishing to the npm registry. + + ```yaml {9} + groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: + output: + location: npm + package-name: name-of-your-package + token: ${NPM_TOKEN} + config: + namespaceExport: YourClientName + github: + repository: your-org/your-repository ``` - For another example, see Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) - - - - Once your workflow is configured, add your new workflow file to `.fernignore` so regenerating releases doesn't overwrite your workflow. - - ```diff title=".fernignore" - + .github/workflows/ci.yml - ``` - + When you regenerate your release, Fern will automatically create a workflow in your repository called `.github/workflows/ci.yml` that will automatically publish your release to npm. For an example, see Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) @@ -305,7 +248,7 @@ groups: package-name: name-of-your-package token: ${NPM_TOKEN} config: - namespaceExport: your-client-name + namespaceExport: YourClientName github: repository: your-org/your-repository ```