diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 11fb97b6963..e7e167ffef9 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -175,7 +175,7 @@ jobs: uses: ./.github/actions/setup-web - name: Static check - run: pnpm -w check + run: vp run -w check superlinter: name: SuperLinter diff --git a/.vite-hooks/pre-commit b/.vite-hooks/pre-commit index 9de19c91ef8..604e73a9c8f 100755 --- a/.vite-hooks/pre-commit +++ b/.vite-hooks/pre-commit @@ -1,11 +1,5 @@ #!/bin/sh -# get the list of modified files -files=$(git diff --cached --name-only) - -# check if api or web directory is modified - -api_modified=false -skip_web_checks=false +set -eu git_path() { git rev-parse --git-path "$1" @@ -17,42 +11,7 @@ if [ -f "$(git_path MERGE_HEAD)" ] || \ [ -f "$(git_path SQUASH_MSG)" ] || \ [ -d "$(git_path rebase-merge)" ] || \ [ -d "$(git_path rebase-apply)" ]; then - skip_web_checks=true -fi - -for file in $files -do - # Use POSIX compliant pattern matching - case "$file" in - api/*.py) - # set api_modified flag to true - api_modified=true - ;; - esac -done - -# run linters based on the modified modules - -if $api_modified; then - echo "Running Ruff linter on api module" - - # run Ruff linter auto-fixing - uv run --project api --dev ruff check --fix ./api - - # run Ruff linter checks - uv run --project api --dev ruff check ./api || status=$? - - status=${status:-0} - - if [ $status -ne 0 ]; then - echo "Ruff linter on api module error, exit code: $status" - echo "Please run 'dev/reformat' to fix the fixable linting errors." - exit 1 - fi -fi - -if $skip_web_checks; then - echo "Git operation in progress, skipping web checks" + echo "Git operation in progress, skipping staged checks; CI validates the result." exit 0 fi diff --git a/package.json b/package.json index 68ec273fbba..219ee4f6fc7 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "private": true, "type": "module", "scripts": { - "check": "vp check && pnpm lint:eslint", - "check:fix": "pnpm lint:eslint:fix && vp check --fix", + "check": "vp check && vp run lint:eslint", + "check:fix": "vp run lint:eslint:fix && vp check --fix", "dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"", "knip": "knip --workspace web", "knip:production": "knip --workspace web --production --include files", diff --git a/vite.config.ts b/vite.config.ts index 3f97680d425..8d47f7528bb 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -51,6 +51,16 @@ export default defineConfig({ [eslintFiles]: [eslintFix, formatFix], [formatOnlyFiles]: formatFix, '.vite-hooks/*': 'sh -n', + 'api/**/*.{py,pyi}': [ + // Format first so fixable long lines do not fail the API's E501 check. + 'uv run --locked --project api --dev ruff format --force-exclude', + 'uv run --locked --project api --dev ruff check --fix --force-exclude', + 'uv run --locked --project api --dev ruff format --force-exclude', + ], + 'dify-agent/{src,examples,tests,docs}/**/*.py': [ + 'uv run --locked --project dify-agent --dev ruff check --fix --force-exclude', + 'uv run --locked --project dify-agent --dev ruff format --force-exclude', + ], }, fmt: { ignorePatterns: [...nonFrontendIgnores, ...generatedIgnores, ...formatterUnstableInputs], diff --git a/web/docs/lint.md b/web/docs/lint.md index b2644e50b49..05c3b19fbb8 100644 --- a/web/docs/lint.md +++ b/web/docs/lint.md @@ -7,13 +7,13 @@ Vite+ provides the primary static check through `vp check`, which combines Oxfmt Run the complete repository check from the root before committing or pushing: ```sh -pnpm check +vp run -w check ``` Apply safe fixes before running the same checks: ```sh -pnpm check:fix +vp run -w check:fix ``` CI and local development use the same root `vite.config.ts` configuration. @@ -31,14 +31,14 @@ Run only the Web JSX accessibility rules for selected files or directories with `lint:a11y`. Quote paths that contain shell metacharacters such as parentheses: ```sh -pnpm --dir web lint:a11y 'app/(commonLayout)/app/(appDetailLayout)/layout.tsx' +vp run dify-web#lint:a11y 'app/(commonLayout)/app/(appDetailLayout)/layout.tsx' ``` Use dependency mode to resolve an entry file's transitive local imports, including path aliases, re-exports, and dynamic imports, and then lint the resulting JSX and TSX files: ```sh -pnpm --dir web lint:a11y --deps 'app/(commonLayout)/app/(appDetailLayout)/layout.tsx' +vp run dify-web#lint:a11y --deps 'app/(commonLayout)/app/(appDetailLayout)/layout.tsx' ``` This is a local page-scoped diagnostic. The repository-wide accessibility rule baseline remains @@ -47,24 +47,18 @@ owned by `lint.config.ts` and is also enforced by the normal `vp check` path. Run the ESLint fallback separately when targeting JSON, JSONC, JSON5, YAML, TOML, or Markdown: ```sh -pnpm lint:eslint package.json pnpm-workspace.yaml web/docs -pnpm lint:eslint:fix package.json pnpm-workspace.yaml web/docs +vp run -w lint:eslint package.json pnpm-workspace.yaml web/docs +vp run -w lint:eslint:fix package.json pnpm-workspace.yaml web/docs ``` Oxlint and Vite+ type-check scope is defined by `lint.config.ts` `ignorePatterns`, and ESLint's scope is defined by `eslint.config.mjs` global ignores. The primary rule baseline lives in `lint.config.ts` and is connected through the root `vite.config.ts` `lint` block. Oxlint-native rules are preferred, and compatible ESLint rules can run through Oxlint's `jsPlugins` support. The rules are explicit snapshots of the ESLint configurations that were active at migration time. Do not import an upstream preset wholesale: enable a new rule intentionally and review its existing violations first. -Tailwind canonical class cleanup is optional because loading the JavaScript plugin adds noticeable lint startup time. The default `pnpm check` command does not load it. Run `pnpm lint:tailwind` to inspect `web/` and `packages/dify-ui/`, or `pnpm lint:tailwind:fix` to apply safe replacements. Both commands run the complete lint configuration with the additional `better-tailwindcss/enforce-canonical-classes` rule, using `web/app/styles/globals.css` and a 16px root font size. +Tailwind canonical class cleanup is optional because loading the JavaScript plugin adds noticeable lint startup time. The default `vp run -w check` command does not load it. Run `vp run -w lint:tailwind` to inspect `web/` and `packages/dify-ui/`, or `vp run -w lint:tailwind:fix` to apply safe replacements. Both commands run the complete lint configuration with the additional `better-tailwindcss/enforce-canonical-classes` rule, using `web/app/styles/globals.css` and a 16px root font size. The non-code baseline and its repository-wide file scope live in `eslint.config.mjs`. ESLint checks JSON, JSONC, JSON5, YAML, TOML, and Markdown only. The configuration globally ignores JavaScript, JSX, TypeScript, TSX, and declaration files; a comment-only inventory records the removed code checks as a migration tradeoff. It does not import or depend on the Antfu ESLint config. -### Auto-fix Workflow - -Configure the Oxc and ESLint editor extensions to apply their respective fixes on save. The commit hook runs `vp staged`, which delegates staged files to `vp check --fix` and adds the ESLint fallback for non-code files. The autofix workflow uses the same combined Vite+ check. - -Always review automatic fixes before committing. JS plugins are allowed to provide fixes, and their behavior is not necessarily identical to a native Oxlint rule. - ### Type-aware Linting The root configuration enables both `typeAware` and `typeCheck`, so `vp check` runs type-aware rules and full diagnostics through the repository's `@typescript/native` compiler. @@ -72,7 +66,7 @@ The root configuration enables both `typeAware` and `typeCheck`, so `vp check` r The web package still runs its existing TSSLint rule separately: ```sh -pnpm --dir web lint:tss +vp run dify-web#lint:tss ``` ### Bulk Suppressions @@ -82,8 +76,8 @@ Existing Oxlint error diagnostics are tracked in the root `oxlint-suppressions.j The bulk-suppression flags are available in the bundled Oxlint version but are currently hidden from `vp lint --help`. Run them from the repository root so every package uses the same baseline: ```sh -pnpm lint:oxlint --suppress-all -pnpm lint:oxlint --prune-suppressions +vp run -w lint:oxlint --suppress-all +vp run -w lint:oxlint --prune-suppressions ``` The Oxc editor extension does not yet apply the bulk-suppression baseline, so the editor may still display findings that the CLI suppresses.