Back to Turborepo

GitHub Actions

apps/docs/content/docs/guides/ci-vendors/github-actions.mdx

2.10.98.6 KB
Original Source

The following example shows how to use Turborepo with GitHub Actions.

For a given root package.json:

json
{
  "name": "my-turborepo",
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test"
  },
  "devDependencies": {
    "turbo": "latest"
  }
}

And a turbo.json:

json
{
  "$schema": "https://turborepo.dev/schema.json",
  "tasks": {
    "build": {
      "outputs": [".next/**", "!.next/cache/**", "!.next/dev/**", "other-output-dirs/**"],
      "dependsOn": ["^build"]
    },
    "test": {
      "dependsOn": ["^build"]
    }
  }
}

Create a file called .github/workflows/ci.yml in your repository with the following contents:

<PackageManagerTabs> <Tab value="pnpm"> ```yaml title=".github/workflows/ci.yml" name: CI
on:
  push:
    branches: ["main"]
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    name: Build and Test
    timeout-minutes: 15
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - uses: pnpm/action-setup@v3
        with:
          version: 8

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm build

      - name: Test
        run: pnpm test
```
</Tab> <Tab value="yarn">
```yaml title=".github/workflows/ci.yml"
name: CI

on:
  push:
    branches: ["main"]
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    name: Build and Test
    timeout-minutes: 15
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'yarn'

      - name: Install dependencies
        run: yarn

      - name: Build
        run: yarn build

      - name: Test
        run: yarn test
```
</Tab> <Tab value="npm">
```yaml title=".github/workflows/ci.yml"
name: CI

on:
  push:
    branches: ["main"]
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    name: Build and Test
    timeout-minutes: 15
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm install

      - name: Build
        run: npm run build

      - name: Test
        run: npm run test
```
</Tab> <Tab value="bun"> ```yaml title=".github/workflows/ci.yml" name: CI
on:
  push:
    branches: ["main"]
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    name: Build and Test
    timeout-minutes: 15
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - uses: oven-sh/setup-bun@v2

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install dependencies
        run: bun install

      - name: Build
        run: bun run build

      - name: Test
        run: bun run test
```
</Tab> </PackageManagerTabs>

Remote Caching with Vercel Remote Cache

There are two ways to authenticate to Vercel Remote Cache from GitHub Actions:

  • OpenID Connect (OIDC): configure a policy that allows exchanging the CI/CD provider's OIDC tokens for short-lived Turborepo access tokens that grant access to Remote Cache (recommended).
  • Personal Access Token (PAT): configure a long-lived, team-scoped PAT as a secret in your CI/CD provider (use when OIDC is not an option).

For the full setup, see Use Remote Caching from external CI/CD. The GitHub Actions workflow configuration is shown below.

Follow these instructions to create an OIDC policy on your Vercel team and configure your TURBO_TEAM variable. Then add vercel/setup-turborepo-remote-cache-action before any step that runs turbo. It requests a GitHub OIDC token, exchanges it for a short-lived Turborepo access token, and sets TURBO_TOKEN and TURBO_TEAM environment variables for later steps that run turbo:

yaml
# ...
jobs:
  build:
    runs-on: ubuntu-latest
    permissions: # [!code highlight]
      contents: read # [!code highlight]
      id-token: write # [!code highlight]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Turborepo Remote Cache # [!code highlight]
        uses: vercel/[email protected] # [!code highlight]
        with: # [!code highlight]
          team: ${{ vars.TURBO_TEAM }} # [!code highlight]
    # ...

Using a Personal Access Token

Follow these instructions to create a Personal Access Token, configure your TURBO_TOKEN secret, and configure your TURBO_TEAM variable. Then provide them to jobs that run turbo:

yaml
# ...
jobs:
  build:
    runs-on: ubuntu-latest
    env: # [!code highlight]
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} # [!code highlight]
      TURBO_TEAM: ${{ vars.TURBO_TEAM }} # [!code highlight]
    steps:
      - uses: actions/checkout@v4
    # ...

Using Remote Caching with Reusable Workflows

For information on passing secrets to reusable workflows, see GitHub's documentation on passing secrets to nested workflows.

Remote Caching with GitHub actions/cache

The following steps show how you could use actions/cache to cache your monorepo artifacts on GitHub.

<Steps> <Step> Supply a package.json script that will run tasks using Turborepo.

Example package.json with a build script:

json
{
  "name": "my-turborepo",
  "scripts": {
    "build": "turbo run build"
  },
  "devDependencies": {
    "turbo": "1.2.5"
  }
}
</Step> <Step> Configure your GitHub pipeline with a step which uses the `actions/cache@v4` action before the build steps of your CI file.
  • Make sure that the path attribute set within the actions/cache action matches the output location above. In the example below, path was set to .turbo.
  • State the cache key for the current run under the key attribute. In the example below, we used a combination of the runner OS and GitHub SHA as the cache key.
  • State the desired cache prefix pattern under the restore-keys attribute. Make sure this pattern will remain valid for future CI runs. In the example below, we used the ${{ runner.os }}-turbo- as the cache key prefix pattern to search against. This allows us to hit the cache on any subsequent CI runs despite github.sha changing.

Example ci yaml with .turbo as chosen cache folder:

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Cache turbo build setup # [!code highlight]
        uses: actions/cache@v4 # [!code highlight]
        with: # [!code highlight]
          path: .turbo # [!code highlight]
          key: ${{ runner.os }}-turbo-${{ github.sha }} # [!code highlight]
          restore-keys: | # [!code highlight]
            ${{ runner.os }}-turbo-

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "npm"

      - name: Install dependencies
        run: npm install

      - name: Build
        run: npm run build
</Step> </Steps>