Skip to content

CI/CD Integration

This guide covers how to use datamodel-code-generator in CI/CD pipelines and development workflows to ensure generated code stays in sync with schemas.

Note

The package name is datamodel-code-generator, and the CLI command is datamodel-codegen.


Official GitHub Action

The official GitHub Action provides a simple way to validate generated models in your CI pipeline.

Basic Usage

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel

By default, the action runs in check mode (--check), which validates that the existing output file matches what would be generated. If they differ, the action fails.

Inputs

Input Required Default Description
input Yes - Input schema file or directory
output Yes - Output file or directory
input-file-type Yes - Input file type (openapi, jsonschema, json, yaml, csv, graphql)
output-model-type Yes - Output model type (pydantic_v2.BaseModel, pydantic.BaseModel, dataclasses.dataclass, typing.TypedDict, msgspec.Struct)
check No true Validate that existing output is up to date (no generation)
working-directory No . Working directory (where pyproject.toml is located)
profile No - Named profile from pyproject.toml
extra-args No - Additional CLI arguments
version No - Specific version to install (defaults to action's tag version)
extras No - Optional extras to install (comma-separated: graphql, http, validation, ruff, all)

Example: Validate on Pull Request

.github/workflows/validate-models.yml
name: Validate Generated Models

on:
  pull_request:
    paths:
      - 'schemas/**'
      - 'src/models/**'

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

      - uses: koxudaxi/datamodel-code-generator@0.44.0
        with:
          input: schemas/api.yaml
          output: src/models/api.py
          input-file-type: openapi
          output-model-type: pydantic_v2.BaseModel

Example: Monorepo with Multiple Schemas

.github/workflows/validate-models.yml
jobs:
  validate:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - working-directory: packages/api
            input: schemas/openapi.yaml
            output: src/models.py
            input-file-type: openapi
          - working-directory: packages/admin
            input: schemas/schema.json
            output: src/models.py
            input-file-type: jsonschema
    steps:
      - uses: actions/checkout@v4

      - uses: koxudaxi/datamodel-code-generator@0.44.0
        with:
          input: ${{ matrix.input }}
          output: ${{ matrix.output }}
          input-file-type: ${{ matrix.input-file-type }}
          output-model-type: pydantic_v2.BaseModel
          working-directory: ${{ matrix.working-directory }}

Example: Using Profiles

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schemas/api.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    profile: api

Example: Generate Models (Instead of Validation)

Set check: 'false' to actually generate the models:

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    check: 'false'

Example: GraphQL Schema

For GraphQL schemas, use the extras input to install the required dependency:

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schema.graphql
    output: src/models.py
    input-file-type: graphql
    output-model-type: pydantic_v2.BaseModel
    extras: 'graphql'

Example: Multiple Extras

You can install multiple extras with comma-separated values:

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    extras: 'http,validation,ruff'

Example: Additional CLI Options

Use extra-args for CLI options not covered by the inputs:

- uses: koxudaxi/datamodel-code-generator@0.44.0
  with:
    input: schema.yaml
    output: src/models.py
    input-file-type: openapi
    output-model-type: pydantic_v2.BaseModel
    extra-args: '--snake-case-field --field-constraints'

Version Pinning

Always pin the action to a specific version tag (e.g., @0.44.0) to ensure reproducible builds. The action installs the same version of datamodel-code-generator as the tag.


The --check Flag

The --check flag verifies that generated code matches existing files without modifying them. If the output would differ, it exits with a non-zero status code.

datamodel-codegen --check

Success (Exit code 0)

When generated code matches the existing file, the command exits silently with code 0:

$ datamodel-codegen --check
$ echo $?
0

Failure (Exit code 1)

When the schema has changed and the generated code would differ, a unified diff is shown and the command exits with code 1:

$ datamodel-codegen --check
--- models.py
+++ models.py (expected)
@@ -12,3 +12,4 @@
     name: Optional[str] = None
     age: Optional[int] = None
     email: Optional[str] = None
+    active: Optional[bool] = None
$ echo $?
1

Best Practice: Use pyproject.toml

Instead of passing many CLI options, configure all settings in pyproject.toml. This keeps CI commands simple, ensures consistency between local development and CI, and makes configuration easier to maintain.

pyproject.toml
[tool.datamodel-codegen]
input = "schemas/api.yaml"
output = "src/models/api.py"
output-model-type = "pydantic_v2.BaseModel"
disable-timestamp = true

Then simply run:

datamodel-codegen --check

For projects with multiple schemas, use named profiles to organize configurations by purpose.

Related: --check, --disable-timestamp, pyproject.toml Configuration


GitHub Actions

Basic Example

.github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  check-generated-code:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.14"

      - name: Install dependencies
        run: pip install datamodel-code-generator

      - name: Verify generated models are up-to-date
        run: datamodel-codegen --check

Using Profiles for Multiple Schemas

For projects with multiple schemas, use named profiles to organize configurations by purpose:

pyproject.toml
[tool.datamodel-codegen]
output-model-type = "pydantic_v2.BaseModel"
disable-timestamp = true

[tool.datamodel-codegen.profiles.api]
input = "schemas/openapi/api.yaml"
output = "src/models/api.py"

[tool.datamodel-codegen.profiles.events]
input = "schemas/jsonschema/events.json"
output = "src/models/events.py"
input-file-type = "jsonschema"
.github/workflows/ci.yml
- name: Verify API models are up-to-date
  run: datamodel-codegen --profile api --check

- name: Verify event models are up-to-date
  run: datamodel-codegen --profile events --check

Using uv

If your project uses uv, you can run the CLI via uv run. This example installs the tool ephemerally (no need to add it to your project dependencies):

.github/workflows/ci.yml
- name: Install uv
  uses: astral-sh/setup-uv@v4

- name: Verify generated models are up-to-date
  run: uv run --with datamodel-code-generator datamodel-codegen --profile api --check

Pre-commit Hook

You can use datamodel-code-generator as a pre-commit hook to automatically check or regenerate models before commits.

Tip

Pin rev to a released tag (e.g., vX.Y.Z) to keep generated output stable and reproducible across developer machines and CI.

Configure settings in pyproject.toml and use a simple pre-commit hook:

.pre-commit-config.yaml
repos:
  - repo: https://github.com/koxudaxi/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        args: [--check]
        files: ^schemas/

With Profiles

For projects with multiple schemas using named profiles:

.pre-commit-config.yaml
repos:
  - repo: https://github.com/koxudaxi/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        name: Check API models
        args: [--profile, api, --check]
        files: ^schemas/openapi/
      - id: datamodel-code-generator
        name: Check event models
        args: [--profile, events, --check]
        files: ^schemas/jsonschema/

Auto-regenerate Mode

This configuration automatically regenerates models when schema files change:

.pre-commit-config.yaml
repos:
  - repo: https://github.com/koxudaxi/datamodel-code-generator
    rev: vX.Y.Z
    hooks:
      - id: datamodel-code-generator
        files: ^schemas/

Installing the hook

Ensure pre-commit is installed, then install the hooks:

pip install pre-commit
pre-commit install

GitLab CI

.gitlab-ci.yml
check-generated-code:
  image: python:3.14
  script:
    - pip install datamodel-code-generator
    - datamodel-codegen --check
  rules:
    - changes:
        - schemas/**/*
        - src/models/**/*

Makefile Integration

Add targets to your Makefile for easy generation and checking:

Makefile
.PHONY: generate-models check-models

generate-models:
    datamodel-codegen

check-models:
    datamodel-codegen --check

Then use in CI:

.github/workflows/ci.yml
- name: Check generated models
  run: make check-models

For projects with multiple profiles:

Makefile
.PHONY: generate-all check-all

generate-all:
    datamodel-codegen --profile api
    datamodel-codegen --profile events

check-all:
    datamodel-codegen --profile api --check
    datamodel-codegen --profile events --check

Troubleshooting

Check fails due to formatting differences

Ensure you're using the same formatters in CI as locally. Configure formatters in pyproject.toml:

pyproject.toml
[tool.datamodel-codegen]
formatters = ["ruff"]

See Formatting for details.

Related: --formatters

Check fails due to timestamp

Always use disable-timestamp = true in pyproject.toml:

pyproject.toml
[tool.datamodel-codegen]
disable-timestamp = true

Related: --disable-timestamp

Different Python versions produce different output

Some type annotations differ between Python versions. Pin the target version in pyproject.toml and ensure CI uses the same Python version as development:

pyproject.toml
[tool.datamodel-codegen]
target-python-version = "3.14"

Related: --target-python-version