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¶
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¶
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.
Success (Exit code 0)¶
When generated code matches the existing file, the command exits silently with code 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.
[tool.datamodel-codegen]
input = "schemas/api.yaml"
output = "src/models/api.py"
output-model-type = "pydantic_v2.BaseModel"
disable-timestamp = true
Then simply run:
For projects with multiple schemas, use named profiles to organize configurations by purpose.
Related: --check, --disable-timestamp, pyproject.toml Configuration
GitHub Actions¶
Basic Example¶
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:
[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"
- 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):
- 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.
With pyproject.toml (Recommended)¶
Configure settings in pyproject.toml and use a simple pre-commit hook:
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:
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:
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:
GitLab CI¶
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:
.PHONY: generate-models check-models
generate-models:
datamodel-codegen
check-models:
datamodel-codegen --check
Then use in CI:
For projects with multiple profiles:
.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:
See Formatting for details.
Related: --formatters
Check fails due to timestamp¶
Always use disable-timestamp = true in pyproject.toml:
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:
Related: --target-python-version