EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
Using Rover in CI/CD
Integrate Rover into continuous integration and deployment workflows
You can use Rover in any CI/CD environment that uses a Rover-supported operating system (Linux, macOS, or Windows). Most commonly, this is to run schema checks with rover graph check or rover subgraph check.
Apollo distributes Rover in three forms that are well-suited to CI:
Official Docker images on Docker Hub and GitHub Container Registry, with immutable tags pinned to each Rover release.
Apollo-published GitHub Actions on the GitHub Actions Marketplace, with one action per common Rover CI command. The Docker-based actions run inside the official image, so the Rover version is pinned to the action's release tag.
Native binary installers for Linux, macOS, and Windows. These are useful when Docker isn't available, when you need to run Rover on a non-Linux CI runner, or when you want to invoke Rover commands that don't have a dedicated action.
The rest of this page covers each option in detail, including end-to-end examples for the most common CI/CD providers:
If you're using Rover with a CI/CD provider not listed here, we'd love for you to share the steps by opening an issue or pull request.
Use API keys
Rover commands that communicate with GraphOS require an API key. GraphOS supports graph API keys, subgraph API keys, and personal API keys.
On your local development machine, use a personal API key and provide it to Rover with the rover config auth command.
In shared environments like CI, use a graph or subgraph API key and set it as an environment variable.
Choosing an integration method
| You're using… | Recommended approach |
|---|---|
| GitHub Actions | The Apollo-published GitHub Actions (apollographql-gh-actions/*). |
| Any other CI provider that can run a container as a step (CircleCI, Bitbucket Pipelines, GitLab CI/CD, Jenkins with a Docker agent, etc.) | The official Rover Docker image. |
| Windows or macOS CI runners, environments without Docker, or commands not covered by a published action | The native binary installer. |
| Node.js-based workflows | The npm distribution (@apollo/rover). |
The Docker images and the lockstep GitHub Action tags are immutable per Rover release. Pin to a specific version (for example, ghcr.io/apollographql/rover:0.39.1 or apollographql-gh-actions/install-rover@rover-v0.39.1) so your pipeline behavior doesn't change when a new Rover version ships.
Docker images
Starting with Rover 0.39.1, Apollo publishes immutable Linux container images for every release. These images include the Rover binary as the default entry point running as a non-root user.
1# GitHub Container Registry
2docker pull ghcr.io/apollographql/rover:0.39.1
3
4# Docker Hub
5docker pull apollograph/rover:0.39.10.39.1) rather than a moving tag. Apollo enforces tag immutability per release, so a pinned tag is safe to use across long-lived pipelines.Running a command
The default ENTRYPOINT is rover, so you can pass arguments to docker run directly:
1docker run --rm \
2 -e APOLLO_KEY \
3 -v "$PWD:/workspace" -w /workspace \
4 ghcr.io/apollographql/rover:0.39.1 \
5 subgraph check my-graph@prod --name products --schema ./schema.graphql-e APOLLO_KEYforwards your API key from the host environment.-v "$PWD:/workspace" -w /workspacemounts your repo so Rover can read schema files. Inside the container, paths are relative to/workspace.
The recommended approach for most CI providers (CircleCI, Bitbucket Pipelines, GitLab CI/CD, Jenkins with a Docker agent) is to set the image at the job or step level. This allows Rover commands to run as if they were on the host — see the per-provider examples below.
GitHub
build.environment by name and set build.env variables using the saved secrets.Apollo-published GitHub Actions
Apollo publishes GitHub Actions for common Rover CI commands, plus an installer action for everything else. For full input documentation, see each action's Marketplace listing:
Starting with Rover v0.39.1, the per-command actions are immutable Docker container actions that run inside the official ghcr.io/apollographql/rover image. Each Rover release publishes a matching @rover-v<version> tag for every action, so a single tag pins both the action and the Rover binary it runs.
ubuntu-latest). To run Rover on macOS or Windows runners, use install-rover plus a run: step instead.Full example using the Apollo-published GitHub Actions
1name: Rover Actions
2
3# Controls when the action will run. Triggers the workflow on push or pull request events
4on: [push, pull_request]
5
6# A workflow run is made up of one or more jobs that can run sequentially or in parallel
7jobs:
8 # This workflow contains a single job called "build"
9 build:
10 # The type of runner that the job will run on
11 runs-on: ubuntu-latest
12
13 # https://docs.github.com/en/actions/reference/encrypted-secrets
14 # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsenv
15 env:
16 APOLLO_KEY: ${{ secrets.APOLLO_KEY }}
17 APOLLO_VCS_BRANCH: ${{ github.head_ref }}
18 APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }}
19
20 steps:
21 # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
22 - uses: actions/checkout@v4
23
24 # Run a schema check against your graph
25 - uses: apollographql-gh-actions/rover-subgraph-check@rover-v0.39.1
26 with:
27 apollo-key: ${{ secrets.APOLLO_KEY }}
28 # This could also be provided via an environment variable or GitHub Action variable
29 graph-ref: ${{ secrets.APOLLO_GRAPH_REF }}
30 name: subgraph-name
31 # If you use a code-first subgraph, you can generate the schema in another step for use with this action
32 schema: ./path/to/schema.graphql
33 # Only run this command with the `background` setting if you have the Apollo Studio GitHub integration enabled on your repository
34 background: true
35
36 # Lint the subgraph schema.
37 - uses: apollographql-gh-actions/rover-subgraph-lint@rover-v0.39.1
38 with:
39 apollo-key: ${{ secrets.APOLLO_KEY }}
40 # This could also be provided via an environment variable or GitHub Action variable
41 graph-ref: ${{ secrets.APOLLO_GRAPH_REF }}
42 name: subgraph-name
43 # If you use a code-first subgraph, you can generate the schema in another step for use with this action
44 schema: ./path/to/schema.graphql
45
46 # Publish the subgraph to GraphOS
47 - uses: apollographql-gh-actions/rover-subgraph-publish@rover-v0.39.1
48 with:
49 apollo-key: ${{ secrets.APOLLO_KEY }}
50 # This could also be provided via an environment variable or GitHub Action variable
51 graph-ref: ${{ secrets.APOLLO_GRAPH_REF }}
52 name: subgraph-name
53 # If you use a code-first subgraph, you can generate the schema in another step for use with this action
54 schema: ./path/to/schema.graphql
55
56 # If running the first time, you will need to pass the `routing-url` parameter to the publish action.
57 # This URL is used for the Apollo Router to route requests to your subgraph.
58 routing-url: http://localhost:4000/graphql
59 # If the routing-url is invalid for one reason or another, you can also pass the `allow-invalid-routing-url` parameter to the publish action.
60 allow-invalid-routing-url: true
61
62 # If you are publishing to a Connectors-based subgraph, you can pass the `no-url` parameter to the publish action, which is equivalent to passing "" to `routing-url` and true to `allow-invalid-routing-url`.
63 no-url: true
64
65 # Publish persisted queries to GraphOS.
66 - uses: apollographql-gh-actions/rover-persisted-queries-publish@rover-v0.39.1
67 with:
68 apollo-key: ${{ secrets.APOLLO_KEY }}
69 graph-ref: ${{ secrets.APOLLO_GRAPH_REF }}
70 for-client-name: example-publish
71 manifest: ./path/to/persisted-queries-manifest.json
72
73 # Target a list by graph-id + list-id instead of graph-ref:
74 - uses: apollographql-gh-actions/rover-persisted-queries-publish@rover-v0.39.1
75 with:
76 apollo-key: ${{ secrets.APOLLO_KEY }}
77 graph-id: ${{ vars.APOLLO_GRAPH_ID }}
78 list-id: 1234-5678
79 for-client-name: example-publish
80 manifest: ./path/to/persisted-queries-manifest.jsonVersioning the actions
@rover-v<version>— runs the matching Rover release. Both the action and Rover are released as immutable artifacts, so no SHA pinning is needed.@v1— pre-lockstep tag for the install action; accepts aversion:input. Use this only if you need a Rover version older than v0.39.1, or if you can't use the Docker-based per-command actions (for example, on a Windows or macOS runner).
Installing Rover on non-Linux runners
If your job runs on macos-* or windows-* runners, or if you want to invoke a Rover command that doesn't have a published action, use install-rover to put rover on PATH and then call it directly:
1jobs:
2 check:
3 runs-on: ubuntu-latest # works equally well on macos-latest / windows-latest
4 env:
5 APOLLO_KEY: ${{ secrets.APOLLO_KEY }}
6 steps:
7 - uses: actions/checkout@v4
8 - uses: apollographql-gh-actions/install-rover@rover-v0.39.1
9 - run: rover graph check my-graph@prod --schema ./schema.graphql --backgroundLinux/macOS jobs using the curl installer
If you'd rather not depend on the Apollo-published action, you can install Rover with the shell installer. Note that GitHub Actions doesn't persist $PATH between run steps, so you must append Rover's bin directory to $GITHUB_PATH:
1echo "$HOME/.rover/bin" >> $GITHUB_PATHFull example
1# .github/workflows/check.yml
2
3name: Check Schema
4
5# Controls when the action will run. Triggers the workflow on push or pull request events
6on: [push, pull_request]
7
8# A workflow run is made up of one or more jobs that can run sequentially or in parallel
9jobs:
10 # This workflow contains a single job called "build"
11 build:
12 # The type of runner that the job will run on
13 runs-on: ubuntu-latest
14
15 # https://docs.github.com/en/actions/reference/environments
16 environment: apollo
17
18 # https://docs.github.com/en/actions/reference/encrypted-secrets
19 # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsenv
20 env:
21 APOLLO_KEY: ${{ secrets.APOLLO_KEY }}
22 APOLLO_VCS_BRANCH: ${{ github.head_ref }}
23 APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }}
24
25 # Steps represent a sequence of tasks that will be executed as part of the job
26 steps:
27 # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
28 - uses: actions/checkout@v4
29
30 - name: Install Rover
31 run: |
32 curl -sSL https://rover.apollo.dev/nix/v0.39.1 | sh
33
34 # Add Rover to the $GITHUB_PATH so it can be used in another step
35 # https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#adding-a-system-path
36 echo "$HOME/.rover/bin" >> $GITHUB_PATH
37 # only run this command with the `--background` flag if you have the Apollo Studio GitHub integration enabled on your repository
38 - name: Run check against prod
39 run: |
40 rover graph check my-graph@prod --schema ./test.graphql --backgroundDisplaying schema check results on GitHub pull requests
If you use GitHub Actions to automatically run schema checks on every pull request as shown above, you can install the Apollo Studio GitHub app to provide links to the results of those checks alongside your other pull request checks:
To display schema check results on pull requests correctly, you need to make sure Rover associates the schema check execution with the pull request's HEAD commit, as opposed to the merge commit that GitHub adds. To guarantee this, set the APOLLO_VCS_BRANCH and APOLLO_VCS_COMMIT environment variables in your action's configuration, like so:
1env:
2 APOLLO_VCS_BRANCH: ${{ github.head_ref }}
3 APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }}CircleCI
Recommended: Rover Docker image
CircleCI's docker executor runs any image. Use the official Rover image as the executor for steps that invoke Rover — no separate install step is required
1# .circleci/config.yml
2version: 2.1
3
4jobs:
5 schema-check:
6 docker:
7 - image: ghcr.io/apollographql/rover:0.39.1
8 # The image's default entrypoint is `rover`. Override it so CircleCI's
9 # `run:` steps can execute shell commands.
10 entrypoint: ""
11 steps:
12 - checkout
13 - run:
14 name: Subgraph check
15 command: |
16 rover subgraph check $APOLLO_GRAPH_REF \
17 --name $APOLLO_SUBGRAPH_NAME \
18 --schema ./schema.graphql
19
20workflows:
21 ci:
22 jobs:
23 - schema-check:
24 context: apollo # exposes APOLLO_KEY, APOLLO_GRAPH_REF, APOLLO_SUBGRAPH_NAMEAlternative: Linux jobs using the curl installer
If you need to install Rover into an existing executor image (for example, one of the cimg/* images), use the shell installer. CircleCI doesn't persist $PATH between run steps, so append Rover's bin directory to $BASH_ENV, which CircleCI sources at the start of every step:
1echo 'export PATH=$HOME/.rover/bin:$PATH' >> $BASH_ENVFull example
1version: 2.1
2
3jobs:
4 build:
5 docker:
6 - image: cimg/node:15.11.0
7 steps:
8 - run:
9 name: Install
10 command: |
11 curl -sSL https://rover.apollo.dev/nix/v0.39.1 | sh
12 # Persist the PATH change for subsequent steps.
13 echo 'export PATH=$HOME/.rover/bin:$PATH' >> $BASH_ENV
14 - checkout
15 # Only run with `--background` if you have the Apollo Studio GitHub integration enabled.
16 - run: rover graph check my-graph@prod --schema ./schema.graphql --backgroundBitbucket Pipelines
Recommended: Rover Docker image
Bitbucket Pipelines runs every step inside a container, so you can use the official Rover image directly as the step image.
The following example shows how to:
Run
rover subgraph checkfor each commit on all branchesRun
rover subgraph publishto keep the schema of yourmainbranch synchronized with a base variant (@localin this case)
It expects the following Pipeline Repository Variables to keep the configuration portable across repositories:
APOLLO_KEYAPOLLO_SUBGRAPH_NAME— the name of the subgraph being checked or publishedAPOLLO_LOCAL_PORT— the port number of the base variant
1# ./bitbucket-pipelines.yml
2
3definitions:
4 steps:
5 - step: &rover-subgraph-check
6 name: "[Rover] Subgraph Check"
7 image: ghcr.io/apollographql/rover:0.39.1
8 script:
9 - rover subgraph check my-graph@prod
10 --name "$APOLLO_SUBGRAPH_NAME"
11 --schema ./schema.graphql
12
13 - step: &local-publish
14 name: "[Rover] @local publish (sync with main/master)"
15 image: ghcr.io/apollographql/rover:0.39.1
16 script:
17 - rover subgraph publish my-graph@local
18 --name "$APOLLO_SUBGRAPH_NAME"
19 --schema ./schema.graphql
20 --routing-url "http://localhost:$APOLLO_LOCAL_PORT/graphql"
21
22pipelines:
23 default:
24 - step: *rover-subgraph-check
25
26 branches:
27 "{main,master}":
28 - step: *rover-subgraph-check
29 - step: *local-publishAlternative: install Rover with the shell installer
If you can't pull the Rover image (for example, you're already using a custom build image with other tooling baked in), install Rover with the shell installer and add it to PATH for subsequent commands. Bitbucket Pipelines runs each script: entry in the same shell, so the export PATH=... persists within the step.
1image: debian:stable-slim
2
3definitions:
4 steps:
5 - step: &rover-subgraph-check
6 name: "[Rover] Subgraph Check"
7 script:
8 - apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
9 - curl -sSL https://rover.apollo.dev/nix/v0.39.1 | sh
10 - export PATH="$HOME/.rover/bin:$PATH"
11 - rover subgraph check my-graph@prod
12 --name "$APOLLO_SUBGRAPH_NAME"
13 --schema ./schema.graphqlJenkins
Recommended: Rover Docker image via the docker agent
If your Jenkins controller has Docker available, run the Rover-using stages inside the official image. The image already contains the Rover binary, so no install step is needed.
1pipeline {
2 agent none
3 stages {
4 stage('Rover Check') {
5 agent {
6 docker {
7 image 'ghcr.io/apollographql/rover:0.39.1'
8 // The image's default entrypoint is `rover`. Override it so Jenkins
9 // can run shell steps inside the container.
10 args '--entrypoint='
11 }
12 }
13 steps {
14 sh '''
15 rover subgraph check "$APOLLO_GRAPH_REF" \
16 --name "$APOLLO_SUBGRAPH_NAME" \
17 --schema "$SCHEMA_PATH"
18 '''
19 }
20 }
21
22 stage('Schema Publish to Dev') {
23 when { expression { env.BRANCH_NAME == 'main' } }
24 agent {
25 docker {
26 image 'ghcr.io/apollographql/rover:0.39.1'
27 args '--entrypoint='
28 }
29 }
30 steps {
31 sh '''
32 rover subgraph publish "$APOLLO_GRAPH_REF" \
33 --name "$APOLLO_SUBGRAPH_NAME" \
34 --schema "$SCHEMA_PATH"
35 '''
36 }
37 }
38 }
39 environment {
40 APOLLO_KEY = credentials('apollo_key')
41 APOLLO_SUBGRAPH_NAME = 'products'
42 APOLLO_GRAPH_REF = 'ApolloJenkins@dev'
43 SCHEMA_PATH = './graph/schema.graphqls'
44 }
45}Apollo strongly recommends passing APOLLO_KEY via a Jenkins credential and referencing it with credentials(...), as shown above.
Alternative: install Rover inside a custom build image
If you'd rather bake Rover into your existing build image, use the shell installer and reference the binary by full path so it works across sh steps:
1FROM golang:1.18
2RUN useradd -m rover && echo "rover:rover" | chpasswd
3USER rover
4RUN curl -sSL https://rover.apollo.dev/nix/v0.39.1 | shReference Rover by its full path in pipeline steps (Jenkins doesn't persist $PATH across sh blocks):
1sh '$HOME/.rover/bin/rover subgraph check "$APOLLO_GRAPH_REF" --name "$APOLLO_SUBGRAPH_NAME" --schema "$SCHEMA_PATH"'GitLab
Recommended: Rover Docker image
GitLab CI/CD supports a per-job image:, so you can use Rover directly from the official image with no install step:
1stages:
2 - publish_subgraphs
3
4publish_subgraphs:
5 stage: publish_subgraphs
6 image: ghcr.io/apollographql/rover:0.39.1
7 retry: 1
8 script:
9 - rover subgraph publish "$APOLLO_GRAPH_REF"
10 --name "$APOLLO_SUBGRAPH_NAME"
11 --schema "$SCHEMA_PATH"
12 variables:
13 APOLLO_KEY: $APOLLO_FEDERATION_KEYAlternative: debian:stable-slim + curl
If you can't pull from ghcr.io or Docker Hub, you can install Rover into a generic Debian image:
1stages:
2 - publish_subgraphs
3
4publish_subgraphs:
5 stage: publish_subgraphs
6 image: debian:stable-slim
7 retry: 1
8 before_script:
9 - apt-get update && apt-get install curl -y
10 script:
11 - curl -sSL https://rover.apollo.dev/nix/v0.39.1 | sh
12 - export PATH="$HOME/.rover/bin:$PATH"
13 - export APOLLO_KEY=$APOLLO_FEDERATION_KEY
14 - rover subgraph publish "$APOLLO_GRAPH_REF" --name "$APOLLO_SUBGRAPH_NAME" --schema "$SCHEMA_PATH"Using With npm/npx
If you're running in a Node.js workflow, you can adopt the npm distribution of Rover. This way, you don't need to adjust the PATH to run Rover, and it fits well into your existing workflow.
You can use Rover by adding it to your package.json dependencies using these instructions and then execute it using npm scripts, similar to other workflows you might already have. If you don't want to install Rover as a dependency, you can run it with npx by using the -p flag:
--background flag if you have the Apollo Studio GitHub integration enabled on your repository.1npx -p @apollo/rover rover graph check my-graph@prod --schema=./schema.graphql --backgroundnpx (without first installing it as a devDependency) bypasses lockfiles — including Rover's own — and is the highest-risk install path in terms of supply-chain exposure. In CI, prefer adding @apollo/rover to your project's devDependencies so the resolved version is captured in your lockfile.