This page documents the automated fix pipeline that continuously enforces code quality, formatting, structural rewrites, and modernization improvements in the Dify codebase. The autofix workflow is triggered on pull requests and pushes targeting the main branch and performs automatic commits of fixes back to the branch. The system covers:
ast-grep), notably modernizing SQLAlchemy usage.Optional[T] → T | None) with compatibility fixes.This automated modernization pipeline ensures gradual migration to current best practices such as SQLAlchemy 2.0 API usage and consolidated formatting, with minimal manual intervention. The implementation is primarily defined in the .github/workflows/autofix.yml GitHub Actions workflow.
Sources: .github/workflows/autofix.yml1-180
The autofix workflow performs a sequential pipeline of code and doc generation steps, orchestrated to detect changed files and conditionally apply fixes.
main.langgenius/dify repository to avoid commit loops on forks.docker-compose.yaml if relevant files changed.autofix-ci/action to create and push a commit if changes exist.Sources: .github/workflows/autofix.yml2-180
To keep local deployment Docker Compose files in sync with templates, the autofix pipeline regenerates docker-compose.yaml using the docker/generate_docker_compose script when any of the following inputs change:
| Input File | Role |
|---|---|
docker/generate_docker_compose | Generation script executable |
docker/.env.example | Base environment variable defaults |
docker/docker-compose-template.yaml | Compose file template |
docker/docker-compose.yaml | Generated Compose file that's updated |
This step is conditional: it only runs if one or more of these files are modified in the current workflow run.
This ensures local Docker orchestration stays consistent with the latest templates for environment and service changes.
Sources: .github/workflows/autofix.yml25-98
Ruff is the primary tool used for Python code formatting, linting, and autofixing across the backend Python server (api/) and the agent backend (dify-agent/).
Stage 1: Initial Format
Prevents errors like "line too long" from blocking later lint fixes by formatting first.
Stage 2: Lint and Fix
Applies Ruff's automatic lint fixes (removing unused imports, fixing syntax issues, enforcing style rules).
Stage 3: Re-format
Ensures code remains consistently formatted after automatic fixes have taken place.
This pipeline runs within the autofix workflow on all Python files in the codebase, guaranteeing fast and consistent enforcement of style guidelines.
Sources: .github/workflows/autofix.yml102-119 .github/workflows/style.yml53-55
Structural code rewriting is performed using ast-grep, a powerful AST-based code search and replacement tool. This enables precise transformations that go beyond text-based regex.
Dify gradually migrates legacy SQLAlchemy patterns to the modern 2.0 API declarative style automatically via AST-based rules:
| Legacy Pattern | Modernized Pattern | Purpose |
|---|---|---|
db.session.query($W).filter($H) | db.session.query($W).where($H) | Replace deprecated .filter() chained calls with .where() for query conditions. |
session.query($W).filter($H) | session.query($W).where($H) | Same as above, for local session usage. |
$A = db.Column($$$B) | $A = mapped_column($$$B) | Switch model column definitions to use mapped_column per SQLAlchemy 2.0 declarative style. |
$A : $T = db.Column($$$B) | $A : $T = mapped_column($$$B) | Same as above but with type annotations. |
These rewrites occur automatically during autofix runs for all modified Python files.
Dify converts Optional[T] to the newer Python union syntax T | None using a custom ast-grep inline rule:
Because Python does not support union annotations with quoted forward references (e.g. "Type" | None is invalid in some runtimes), a post-processing sed step reverts such cases back to the fully qualified Optional["Type"] syntax for compatibility.
Whenever API/backend source files change, the autofix workflow automatically regenerates:
Swagger Markdown Docs: Using the script api/dev/generate_swagger_markdown_docs.py, OpenAPI specs are converted to markdown documentation consumable in the frontend and docs sites.
Frontend API Contracts: Runs pnpm gen-api-contract inside packages/contracts to update TypeScript-generated API client types and contracts in sync with the backend.
For changes to frontend code, the workflow:
.github/actions/setup-web).pnpm lint:eslint:fix to automatically fix any JavaScript/TypeScript ESLint errors.vp check --fix for Vite and other static checks autofix pass.The SQLAlchemy modernization progress is measured by running the script api/cnt_base.sh, which counts remaining legacy code patterns automatically to monitor migration status.
All automated changes performed by the autofix pipeline are committed and pushed back to the branch via the autofix-ci/action GitHub Action.
This integration automates the lifecycle of applying code quality fixes from detection to committing, ensuring pull requests adhere to project standards with minimal human effort.
Sources: .github/workflows/autofix.yml179-180
This diagram bridges natural language descriptions of autofix subsystems with their respective key code entities and location references.
This diagram details the ASP-based transformation layers modernizing code patterns.
Sources: .github/workflows/autofix.yml120-154
The automated fix and modernization system in Dify employs a combination of structured automation and tooling to ensure code base consistency, modern API usage, and maintainability:
This orchestration reduces manual maintenance overhead and smoothly migrates Dify toward the latest development standards.
Sources:
.github/workflows/autofix.yml
.github/workflows/style.yml
api/Dockerfile
Refresh this wiki
This wiki was recently refreshed. Please wait 6 days to refresh again.