Publishing Subgraph Schemas with the Rover CLI

rover subgraph publish is the single command that registers a subgraph’s SDL with a graph variant, triggers recomposition, and rolls the new supergraph out to your routers — the release step at the heart of Schema Registry and Managed Federation. This guide covers the full publish surface, the authentication it requires, exactly what a publish sets in motion, how to wire it into CI on merge, and how to roll back.

When to use this pattern

  • You operate managed federation and need each subgraph to register its schema and routing URL with the registry.
  • You want schema releases decoupled from binary deploys, so publishing SDL — not redeploying the router — ships a change.
  • You are automating subgraph releases in CI and need a deterministic publish-on-merge step.

Prerequisites

The publish command and its arguments

A publish is identified by three things: which variant, which subgraph within it, and the SDL itself. The routing URL is stored in the supergraph and is the address the router dials at query time.

# --- rover subgraph publish: register SDL + routing URL with a variant -----
rover subgraph publish my-graph@production \   # the GRAPH REF (graph-id@variant)
  --name products \                            # subgraph name (unique per variant)
  --schema ./products/schema.graphql \         # the SDL to register
  --routing-url https://products.internal.svc:4001/graphql
# ^ routing-url is baked into the supergraph; the router calls it at runtime.
#   Omit --routing-url on later publishes to keep the previously registered URL.

--name must be stable for the life of the subgraph — it is the identity the registry tracks across publishes. Changing it registers a new subgraph rather than updating the existing one. --routing-url only needs to be supplied when it changes; subsequent publishes reuse the last registered value, so CI publishes that only update SDL can omit it.

Authentication: APOLLO_KEY and APOLLO_GRAPH_REF

Every publish authenticates with two values, both supplied as environment variables so they never appear in command history or source.

# Graph API key with graph:write — store as a CI secret, never commit it.
export APOLLO_KEY="service:my-graph:xxxxxxxxxxxxxxxxxxxx"
# graph-id@variant — pins the publish to exactly one environment.
export APOLLO_GRAPH_REF="my-graph@production"

# With both exported, the graph ref can be omitted from the command:
rover subgraph publish \
  --name products \
  --schema ./products/schema.graphql

The graph ref is the safety boundary. A publish to my-graph@staging cannot affect my-graph@production — different variants have entirely separate supergraphs and routers. Use a distinct key per environment so a staging credential cannot publish to production.

What a publish triggers

A publish is not just an upload — it kicks off the full managed-federation chain:

  1. Store the SDL. The registry records the new subgraph schema for that variant, with full version history.
  2. Recompose. The registry merges the new SDL with every other subgraph’s current SDL for the variant and runs composition.
  3. Validate. If composition fails, the publish is rejected and the live supergraph is left untouched — no broken artifact is ever served.
  4. Create a launch. A successful composition produces a launch: a timestamped, attributable record linking this publish to the resulting supergraph, with build logs.
  5. Serve via Uplink. The new supergraph becomes available on Uplink for that variant.
  6. Routers hot-reload. Routers pinned to the variant fetch the new supergraph on their next poll and swap it in with no downtime and no redeploy.

This is why a single publish can ship a schema change fleet-wide in seconds. It is also why publishing should be gated — see Apollo Studio Schema Checks for Managed Federation for the check that should run before every publish.

CI publish on merge

The standard pattern: run rover subgraph check on pull requests, run rover subgraph publish only after merge to the main branch. The check is the gate; the publish is the release. Publishing on merge (not on every push) ensures only reviewed, composition-safe SDL reaches the registry.

name: Publish Subgraph on Merge
on:
  push:
    branches: [main]
    paths: ['products/schema.graphql']   # publish only when the SDL changes

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rover
        run: |
          curl -sSL https://rover.apollo.dev/nix/latest | sh
          echo "$HOME/.rover/bin" >> $GITHUB_PATH

      - name: Publish to production variant
        run: |
          rover subgraph publish my-graph@production \
            --name products \
            --schema ./products/schema.graphql \
            --routing-url https://products.internal.svc:4001/graphql
        env:
          APOLLO_KEY: ${{ secrets.APOLLO_KEY }}   # graph:write, prod-scoped secret

For multi-subgraph repos, drive the publish with a matrix over subgraph names so each merge publishes only the services that changed. The publish step naturally follows the check workflow described in Schema Validation in CI/CD Pipelines.

Rollback

Because every successful publish creates a launch that records its supergraph artifact, rollback is a re-publish of the last known-good SDL. There is no separate “undo” command — you reapply the prior schema, which the registry recomposes into a new launch.

# Roll back by re-publishing the previously good SDL for the subgraph.
# git checkout the last good schema, then publish it as a fresh launch:
git checkout HEAD~1 -- products/schema.graphql

rover subgraph publish my-graph@production \
  --name products \
  --schema ./products/schema.graphql
# Registry recomposes; Uplink serves the restored supergraph; routers
# pick it up within one poll interval (~10s) — no redeploy required.

The Studio launch history is your rollback log: each launch shows which publish produced it and the resulting supergraph, so you always know which SDL to restore. Because rollout latency is just the router’s poll interval, a rollback propagates as fast as the original bad publish did. For coordinating rollbacks across larger schema transitions, see Migrating and Versioning Federated Schemas.

Verification steps

  1. After publishing, confirm a new launch appears in Studio with a successful composition build.
  2. Run rover subgraph fetch my-graph@production --name products and confirm the returned SDL matches what you published.
  3. Send a query exercising the changed field through the router and confirm the new shape is served (after one poll interval).
  4. Check the router logs for a supergraph reload entry corresponding to the launch timestamp.

Common mistakes & gotchas

Publishing before checking. Publish recomposes immediately; an unchecked breaking publish that still composes will ship to clients. Always run rover subgraph check on the PR first.

Changing --name between publishes. A different name registers a brand-new subgraph and leaves the old one in the supergraph, usually causing composition conflicts. Keep the name stable for the subgraph’s lifetime.

Forgetting --routing-url on the first publish. The first publish for a subgraph must set the routing URL or the router will not know where to fetch data. Later publishes can omit it to reuse the stored value.

Frequently Asked Questions

What permissions does the APOLLO_KEY need to publish?

A graph API key with graph:write, since publishing mutates the registry (stores SDL, recomposes, creates a launch). Read-only checks need only graph:read. Use a separate, environment-scoped key per variant so a staging credential cannot publish to production.

Do I need to redeploy the router after publishing a subgraph?

No. In managed federation the publish triggers recomposition and Uplink serves the new supergraph; routers fetch it on their next poll and hot-reload it, typically within about ten seconds. The router binary is never redeployed for a schema change.

How do I roll back a bad publish?

Re-publish the last known-good SDL for that subgraph. The registry recomposes it into a new launch and Uplink serves it within one poll interval. The Studio launch history records every supergraph artifact, so it serves as your rollback log — there is no separate undo command.