# Embed in CI

Source: https://fragment.dev/guides/embed-in-ci

[Documentation index](https://fragment.dev/llms.txt)

<a id="embed-in-ci"></a>

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.

<a id="workspaces"></a>

## 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.

<a id="generate-the-sdk"></a>

## 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
   ```

<a id="store-your-schema"></a>

## 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.

<a id="check-backwards-compatibility"></a>

## 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.

<a id="example-workflow"></a>

## 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
```
