# Embed in CI
Source: https://fragment.dev/guides/embed-in-ci
[Documentation index](https://fragment.dev/llms.txt)
Fragment publishes [SDKs](https://fragment.dev/markdown/api-reference/ledger-sdks.md) in TypeScript, Go, Python and Ruby, and a [CLI](https://fragment.dev/markdown/api-reference/ledger-cli-commands.md) for generating SDK code and deploying Schemas.
## Workspaces
Each Fragment Workspace is an isolated environment. Create a separate Workspace for each stage in your release process. For example, development, staging, and production.
[API Client](https://fragment.dev/markdown/api-reference/ledger-overview.md#authentication) credentials are scoped to a single Workspace. Provide the credentials as secrets to `fragment login` in your CI pipeline:
```bash title="Authenticating to a Workspace"
fragment login \
--client-id ${{ vars.FRAGMENT_CLIENT_ID }} \
--client-secret ${{ secrets.FRAGMENT_CLIENT_SECRET }} \
--api-url ${{ vars.FRAGMENT_API_URL }} \
--oauth-url ${{ vars.FRAGMENT_OAUTH_URL }} \
--oauth-scope ${{ vars.FRAGMENT_OAUTH_SCOPE }}
```
Run `fragment workspace` to verify the Workspace the CLI is authenticated to.
## Generate the SDK
Check your Schema file into source control to keep your application code in sync with your Schema. A common pattern is to regenerate the SDK, then check that the output of `git diff` is empty.
1. Generate GraphQL queries from your Schema:
```bash
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql
```
2. Run your language's codegen tool to produce the SDK client:
```bash group="typescript"
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql &&\
npm install --save @fragment-dev/node-client &&\
npx fragment-node-client-codegen \
--input=queries.graphql \
--outputFilename=fragment-client.ts
```
```bash group="python"
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql &&\
pip install fragment-python &&\
fragment-python-client-codegen \
--input-dir=. \
--target-package-name=sdk \
--output-dir=.
```
```bash group="go"
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql &&\
go get 'github.com/fragment-dev/fragment-go/v3' &&\
go run github.com/fragment-dev/fragment-go/v3 \
--input=queries.graphql \
--output=generated.go \
--package=main
```
```bash group="ruby"
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql &&\
gem install fragment-dev
# The Ruby SDK reads queries.graphql at runtime,
# so no code generation step is required.
```
3. Fail the build if the generated SDK is out of date:
```bash
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql &&\
npx fragment-node-client-codegen \
--input=queries.graphql \
--outputFilename=fragment-client.ts &&\
git diff --exit-code
```
## Store your Schema
Treat your Schema file the same way you treat a database migration: it lives in source control, and CI applies it to the target Workspace on every deploy.
Validate the Schema on pull requests:
```bash
fragment verify-schema --path my-schema.jsonc
```
Store the Schema to your Workspace at deploy time:
```bash
fragment store-schema --path my-schema.jsonc
```
Storing a Schema is idempotent. The Schema's `key` is its idempotency key. Fragment enforces changes to your Schema are backwards compatible so you don't break your application.
## Check backwards compatibility
`store-schema` rejects a backwards-incompatible change, such as removing an account, once the Schema has Ledgers. To catch the change on the pull request, run `verify-schema --against` with a previous version of the Schema. To compare against the Schema in your Workspace, download it with `get-schema`:
```bash
fragment get-schema \
--key my-schema \
--output deployed-schema.jsonc &&\
fragment verify-schema \
--path my-schema.jsonc \
--against deployed-schema.jsonc
```
To compare against your base branch instead, write the branch's copy of the Schema with `git show`. This needs no API credentials. A shallow clone may not have the branch, so fetch it first:
```bash
git fetch --depth=1 origin main &&\
git show origin/main:my-schema.jsonc > base-schema.jsonc &&\
fragment verify-schema \
--path my-schema.jsonc \
--against base-schema.jsonc
```
`--against` enforces the rules even for a Schema with no Ledgers. A Schema you have not stored yet has no previous version, so skip the check until its first deploy.
## Example workflow
Here's a GitHub Actions workflow that authenticates, verifies the Schema, checks that it is backwards compatible, generates the SDK, and stores the Schema on deploy:
```yaml expandable=true title="Fragment CLI in Github Actions"
- name: Use Node.js 20.x
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
with:
node-version: 20.x
- name: Install Fragment CLI
run: |
npm install -g @fragment-dev/cli
echo "Fragment CLI installed"
- name: Authenticate with Fragment
run: |
fragment login \
--client-id ${{ vars.FRAGMENT_CLIENT_ID }} \
--client-secret ${{ secrets.FRAGMENT_CLIENT_SECRET }} \
--api-url ${{ vars.FRAGMENT_API_URL }} \
--oauth-url ${{ vars.FRAGMENT_OAUTH_URL }} \
--oauth-scope ${{ vars.FRAGMENT_OAUTH_SCOPE }}
- name: Verify Schema
run: |
fragment verify-schema --path my-schema.jsonc
- name: Check Schema backwards compatibility
run: |
fragment get-schema \
--key my-schema \
--output deployed-schema.jsonc
fragment verify-schema \
--path my-schema.jsonc \
--against deployed-schema.jsonc
- name: Generate SDK
run: |
fragment gen-graphql \
--path=my-schema.jsonc \
--output=queries.graphql
npm install --save @fragment-dev/node-client
npx fragment-node-client-codegen \
--input=queries.graphql \
--outputFilename=fragment-client.ts
git diff --exit-code
- name: Store Schema
run: |
fragment store-schema --path my-schema.jsonc
```