# Set up SDK on GitHub
Source: https://speakeasy.com/docs/sdks/manage/github-setup

import { Callout, Screenshot } from "@/mdx/components";



The [Speakeasy CLI](https://github.com/speakeasy-api/speakeasy) and the Speakeasy [SDK Generation GitHub Action](https://github.com/speakeasy-api/sdk-generation-action) power the SDK generation workflow. The workflow automates the process of:

- Downloading or loading the OpenAPI document from a URL or repository.
- Validating the OpenAPI document.
- Generating SDKs for multiple languages.
- Committing the generated SDKs to the repository or opening a pull request (PR).

<Callout title="Warning" type="warning">
  Branches and pull requests created by the GitHub action are owned by it. Any
  future generations (whether scheduled or manually triggered) will overwrite
  all changes in that branch/PR. To make changes to the generated code, create a
  separate PR instead of modifying the action-generated PR.
</Callout>

## Example workflow file

```yml
name: SDK Generation
permissions:
  checks: write
  contents: write
  pull-requests: write
  statuses: write

on:
  workflow_dispatch:
    inputs:
      force:
        description: Force SDK generation, even if no changes are detected.
        type: boolean
        default: false
      runs-on:
        description: Runner to use for the workflow (e.g., large-ubuntu-runner)
        type: string
        default: ubuntu-latest

jobs:
  generate:
    uses: speakeasy-api/sdk-generation-action/.github/workflows/workflow-executor.yaml@v15
    with:
      speakeasy_version: latest
      force: ${{ github.event.inputs.force }}
      mode: pr
      runs-on: ${{ github.event.inputs.runs-on }}
    secrets:
      github_access_token: ${{ secrets.GITHUB_TOKEN }}
      speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
```

## Step-by-step guide

### Initialize the SDK repository

Create a new GitHub repository to host the autogenerated SDKs. It is recommended to use a separate repository for each SDK, but a [monorepo](/guides/sdks/creating-a-monorepo) is also supported.

### Generate the SDK workflow configuration

Run the Speakeasy CLI to configure the SDK generation workflow. This command creates the necessary workflow files.

```bash
speakeasy configure github
```

After running the command, `.speakeasy/workflow.yaml` and `.github/workflows/sdk_generation.yaml` will be created. These files define the SDK generation workflow and the associated GitHub Action.

<Screenshot
  variant="cli"
  image={{
    src: "/assets/docs/configure-github/configure.png",
    alt: "Screenshot of the terminal after successfully running Speakeasy configure Github.",
  }}
/>

If further customization is needed, [manual configuration](/docs/workflow-reference/generation-reference) of the workflow files is available.

### Set up GitHub secrets

Configure GitHub secrets for authentication:

- Navigate to **Settings > Secrets & Variables > Actions** in your GitHub repository.
- Add a new secret named `SPEAKEASY_API_KEY` which can be obtained from the Speakeasy dashboard.

### Push the workflow to GitHub

Commit and push the generated workflow files to the repository. To test the GitHub Action without modifying any GitHub branches, put the action into `mode: test`.

Navigate to **Actions** in the GitHub repository to trigger the SDK generation workflow manually or wait for it to run automatically. A green checkmark indicates successful workflow completion. If the publishing step has not been configured, it will be skipped.

<Screenshot
  variant="web"
  url="https://github.com/speakeasy-sdks/example/actions/runs/9900330987"
  image={{
    src: "/assets/docs/configure-github/successful-workflow.png",
    alt: "A screenshot of a successful generate flow.",
  }}
/>

For details on package publishing, refer to the [Publishing SDKs guide](/docs/publish-sdk).

### Update the GitHub Actions workflow permissions

If the error `403 GitHub Actions is not permitted to create or approve pull requests` occurs, the repository's GitHub Actions permissions must be updated.

Navigate to **Settings > Actions > Workflow permissions** and adjust the permissions accordingly.

<Screenshot
  variant="web"
  url="https://github.com/speakeasy-sdks/example/settings/actions"
  image={{
    src: "/assets/docs/configure-github/workflow-permissions.png",
    alt: "Github Actions workflow permissions.",
  }}
/>

### Configure remote URLs for schemas

<Callout title="Warning" type="warning">
  Remote URLs for OpenAPI schemas must remain stable. Dynamically constructed
  URLs in workflow files are not supported.
</Callout>

If the OpenAPI schema is hosted in another repository or at a remote URL, set the `source` as the remote URL in `.speakeasy/workflow.yaml`. Use the following command to add the remote URL:

<Screenshot
  variant="cli"
  image={{
    src: "/assets/docs/configure-github/remote-url-schema.png",
    alt: "Configure Remote URL for schema.",
  }}
/>

If the remote URL requires authentication, follow the prompts to provide a token or key stored as an environment variable (for example, `$OPENAPI_DOC_AUTH_TOKEN`).

<Screenshot
  variant="cli"
  image={{
    src: "/assets/docs/configure-github/remote-url-schema.png",
    alt: "Screenshot prompting the user to setup authentication.",
  }}
/>

**Important**: When fetching OpenAPI documents from private repositories, ensure that you prefix the token value with `Bearer ` when setting the value. For example:

```bash
OPENAPI_DOC_AUTH_TOKEN="Bearer <TOKEN_VALUE>"
```

Add a [GitHub secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) with the same name and value as the token or key (including the `Bearer ` prefix for private repositories).

## Using larger GitHub-hosted runners

For resource-intensive SDK generation builds (such as large TypeScript projects that fail during compilation due to memory constraints), you can configure larger GitHub-hosted runners with more RAM and CPU resources.

### Set up larger runners

1. **Configure larger runners in your GitHub organization**: Larger runners are not enabled by default and require separate billing setup.
   - Follow the [GitHub documentation for managing larger runners](https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/using-github-hosted-runners/using-larger-runners/managing-larger-runners)
   - Choose a runner size with sufficient RAM (standard `ubuntu-latest` runners have only 7GB RAM)
   - Assign a custom label to your larger runner (e.g., `large-ubuntu-runner`)

2. **Update your workflow**: Once your larger runner is configured, update your workflow file to use the custom runner label:

```yml
name: SDK Generation
permissions:
  checks: write
  contents: write
  pull-requests: write
  statuses: write

on:
  workflow_dispatch:
    inputs:
      force:
        description: Force SDK generation, even if no changes are detected.
        type: boolean
        default: false
      runs-on:
        description: Runner to use for the workflow (e.g., large-ubuntu-runner)
        type: string
        default: large-ubuntu-runner # Use your custom label here

jobs:
  generate:
    uses: speakeasy-api/sdk-generation-action/.github/workflows/workflow-executor.yaml@v15
    with:
      speakeasy_version: latest
      force: ${{ github.event.inputs.force }}
      mode: pr
      runs-on: ${{ github.event.inputs.runs-on }}
    secrets:
      github_access_token: ${{ secrets.GITHUB_TOKEN }}
      speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
```

This configuration allows you to specify different runner types when manually triggering the workflow, or set a default larger runner for all builds.

## Enable signed commits

To include signed commits from the SDK Generation workflow, add `signed_commits: true` to the workflow file. This configuration ensures that GitHub Actions creates verified commits during workflow execution.

```yml
name: SDK Generation
permissions:
  checks: write
  contents: write
  pull-requests: write
  statuses: write

on:
  workflow_dispatch:
    inputs:
      force:
        description: Force SDK generation, even if no changes are detected.
        type: boolean
        default: false
      runs-on:
        description: Runner to use for the workflow (e.g., large-ubuntu-runner)
        type: string
        default: ubuntu-latest

jobs:
  generate:
    uses: speakeasy-api/sdk-generation-action/.github/workflows/workflow-executor.yaml@v15
    with:
      speakeasy_version: latest
      force: ${{ github.event.inputs.force }}
      mode: pr
      runs-on: ${{ github.event.inputs.runs-on }}
      signed_commits: true
    secrets:
      github_access_token: ${{ secrets.GITHUB_TOKEN }}
      speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
```