From ff3ce9fe935c23030dc7b86d910d2ea9aae1f35a Mon Sep 17 00:00:00 2001 From: Valery Bugakov Date: Fri, 2 Jun 2023 01:37:40 -0700 Subject: [PATCH] bazel: improve ESLint rule and disable ESLint outside of Bazel (#52667) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Custom ESLint Bazel rule now relies on `sh_test`. The build part of the rule produces the output file with ESLint errors, and the `sh_test` target verifies that it's empty. If it's not empty, the ESLint test fails, and the report content is printed to stdout. - Added additional ESLint targets to `*.js` files in the root of each client package. - Added additional ESLint targets for `*.story.tsx` files for client packages with stories. It's temporary until we start building Storybook story modules with `ts_project`. - Disabled ESLint outside of Bazel: **10-12m job is gone!** 🎉 ## Test plan bazel test `bazel query 'attr("name", ".*_eslint$", //client/...)'` --- BUILD.bazel | 11 ++ client/app-shell/BUILD.bazel | 4 +- client/branded/BUILD.bazel | 19 ++- client/browser/BUILD.bazel | 22 ++- client/build-config/BUILD.bazel | 4 +- client/build-config/tsconfig.json | 2 +- client/client-api/BUILD.bazel | 4 +- client/client-api/tsconfig.json | 2 +- client/codeintellify/BUILD.bazel | 4 +- client/codeintellify/tsconfig.json | 2 +- client/cody-cli/BUILD.bazel | 4 +- client/cody-shared/BUILD.bazel | 4 +- client/cody-slack/BUILD.bazel | 4 +- client/cody-ui/BUILD.bazel | 4 +- client/cody-web/BUILD.bazel | 4 +- client/cody/BUILD.bazel | 6 +- client/common/BUILD.bazel | 4 +- client/common/tsconfig.json | 2 +- client/extension-api-types/BUILD.bazel | 4 +- client/extension-api/.eslintrc.js | 2 +- client/extension-api/BUILD.bazel | 15 +- client/extension-api/tsconfig.eslint.json | 9 ++ client/http-client/BUILD.bazel | 4 +- client/http-client/tsconfig.json | 2 +- client/jetbrains/BUILD.bazel | 16 +- client/observability-client/BUILD.bazel | 4 +- client/observability-server/BUILD.bazel | 4 +- client/observability-server/tsconfig.json | 2 +- client/shared/BUILD.bazel | 19 ++- client/storybook/BUILD.bazel | 4 +- client/storybook/tsconfig.json | 2 +- client/template-parser/BUILD.bazel | 4 +- client/template-parser/tsconfig.json | 2 +- client/testing/BUILD.bazel | 4 +- client/testing/tsconfig.json | 2 +- client/vscode/BUILD.bazel | 4 +- client/web/BUILD.bazel | 25 ++- client/web/dev/BUILD.bazel | 1 + client/web/scripts/report-bundle-diff.ts | 2 +- client/wildcard/BUILD.bazel | 21 ++- dev/BUILD.bazel | 2 +- dev/defs.bzl | 2 - dev/eslint-report-test.sh | 28 ++++ dev/eslint.bzl | 153 +++++++++++++----- doc/dev/background-information/bazel_web.md | 7 + .../background-information/ci/reference.md | 24 +-- enterprise/dev/ci/internal/ci/operations.go | 42 ++--- enterprise/dev/ci/internal/ci/pipeline.go | 6 +- 48 files changed, 373 insertions(+), 149 deletions(-) create mode 100644 client/extension-api/tsconfig.eslint.json create mode 100755 dev/eslint-report-test.sh diff --git a/BUILD.bazel b/BUILD.bazel index 1260ef95c79..362bbdcc2d8 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -9,6 +9,7 @@ load("@io_bazel_rules_go//proto/wkt:well_known_types.bzl", "WELL_KNOWN_TYPES_API load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev/linters/staticcheck:analyzers.bzl", "STATIC_CHECK_ANALYZERS") load("@npm//:eslint/package_json.bzl", eslint_bin = "bin") +load("//dev:eslint.bzl", "eslint_test_with_types") # Gazelle config # @@ -243,6 +244,7 @@ js_library( ], data = [ ".eslintignore", + "package.json", ":eslint-relative-formatter", ], deps = [ @@ -270,6 +272,15 @@ js_library( ], ) +eslint_test_with_types( + name = "eslint_test", + srcs = glob(["*.js"]), + config = ":eslint_config", + deps = [ + ":node_modules/@types/node", + ], +) + # Go # nogo config diff --git a/client/app-shell/BUILD.bazel b/client/app-shell/BUILD.bazel index 1eb01a3ae18..9d04a103863 100644 --- a/client/app-shell/BUILD.bazel +++ b/client/app-shell/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/branded/BUILD.bazel b/client/branded/BUILD.bazel index 78d4edb178c..5a8ce35eed2 100644 --- a/client/branded/BUILD.bazel +++ b/client/branded/BUILD.bazel @@ -1,7 +1,7 @@ load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "sass", "ts_project") load("//client/shared/dev:tools.bzl", "module_style_typings") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # TODO(bazel): storybook build # gazelle:exclude **/*.story.{ts,tsx} @@ -12,7 +12,22 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() + +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob([ + "src/**/*.story.tsx", + "src/**/*.fixtures.ts", + ]), + config = ":eslint_config", + deps = [ + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], +) ts_config( name = "tsconfig", diff --git a/client/browser/BUILD.bazel b/client/browser/BUILD.bazel index 4b8af13d092..3f2796b84a6 100644 --- a/client/browser/BUILD.bazel +++ b/client/browser/BUILD.bazel @@ -7,7 +7,7 @@ load("//client/shared/dev:generate_graphql_operations.bzl", "generate_graphql_op load("//client/shared/dev:build_code_intel_extensions.bzl", "build_code_intel_extensions") load("//client/shared/dev:tools.bzl", "module_style_typings") load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # TODO(bazel): storybook build # gazelle:exclude **/*.story.{ts,tsx} @@ -22,12 +22,28 @@ load("//dev:eslint.bzl", "eslint_config") npm_link_all_packages(name = "node_modules") -eslint_config( - deps = [ +eslint_config_and_lint_root( + config_deps = [ "//client/browser/src/end-to-end:tsconfig", ], ) +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob([ + "src/**/*.story.tsx", + "src/**/*.fixtures.ts", + ]), + config = ":eslint_config", + deps = [ + ":node_modules/@sourcegraph/shared", # required for import/extensions rule not to fail. + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], +) + ts_config( name = "tsconfig", src = "tsconfig.json", diff --git a/client/build-config/BUILD.bazel b/client/build-config/BUILD.bazel index a0aa939930a..ef3dc601df2 100644 --- a/client/build-config/BUILD.bazel +++ b/client/build-config/BUILD.bazel @@ -1,14 +1,14 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # TODO(bazel): currently handled with #keep # gazelle:js_resolve **/esbuild/* //client/build-config/src/esbuild npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/build-config/tsconfig.json b/client/build-config/tsconfig.json index 0096b9f73a8..27a83aca1f6 100644 --- a/client/build-config/tsconfig.json +++ b/client/build-config/tsconfig.json @@ -7,5 +7,5 @@ "outDir": "./out", "baseUrl": "./src", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/client-api/BUILD.bazel b/client/client-api/BUILD.bazel index 29498486c79..56f6b6dcd0a 100644 --- a/client/client-api/BUILD.bazel +++ b/client/client-api/BUILD.bazel @@ -1,11 +1,11 @@ load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") load("@aspect_rules_ts//ts:defs.bzl", "ts_config") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/client-api/tsconfig.json b/client/client-api/tsconfig.json index 6d501187605..60550412a70 100644 --- a/client/client-api/tsconfig.json +++ b/client/client-api/tsconfig.json @@ -22,5 +22,5 @@ "path": "../template-parser", }, ], - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/codeintellify/BUILD.bazel b/client/codeintellify/BUILD.bazel index ab675d1eaaf..59d184a53ad 100644 --- a/client/codeintellify/BUILD.bazel +++ b/client/codeintellify/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/codeintellify/tsconfig.json b/client/codeintellify/tsconfig.json index e1895d7c8e4..664aeeaa9c2 100644 --- a/client/codeintellify/tsconfig.json +++ b/client/codeintellify/tsconfig.json @@ -15,5 +15,5 @@ "path": "../extension-api-types", }, ], - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/cody-cli/BUILD.bazel b/client/cody-cli/BUILD.bazel index fb40ee3f14e..5f6161b8ea6 100644 --- a/client/cody-cli/BUILD.bazel +++ b/client/cody-cli/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/cody-shared/BUILD.bazel b/client/cody-shared/BUILD.bazel index 24770c301a7..4ccddc95e96 100644 --- a/client/cody-shared/BUILD.bazel +++ b/client/cody-shared/BUILD.bazel @@ -1,13 +1,13 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # gazelle:js_resolve vscode //:node_modules/@vscode npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/cody-slack/BUILD.bazel b/client/cody-slack/BUILD.bazel index 2ebf15806f7..6a04fc7c2ab 100644 --- a/client/cody-slack/BUILD.bazel +++ b/client/cody-slack/BUILD.bazel @@ -2,12 +2,12 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/cody-ui/BUILD.bazel b/client/cody-ui/BUILD.bazel index 3a76c8940d2..174c58968e0 100644 --- a/client/cody-ui/BUILD.bazel +++ b/client/cody-ui/BUILD.bazel @@ -1,13 +1,13 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # gazelle:js_ignore_imports **/*.css npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/cody-web/BUILD.bazel b/client/cody-web/BUILD.bazel index 589f9960922..7ba60a72687 100644 --- a/client/cody-web/BUILD.bazel +++ b/client/cody-web/BUILD.bazel @@ -1,13 +1,13 @@ load("//dev:defs.bzl", "ts_project") load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # gazelle:js_ignore_imports **/*.css npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/cody/BUILD.bazel b/client/cody/BUILD.bazel index 9dc67194c67..8e476be46c8 100644 --- a/client/cody/BUILD.bazel +++ b/client/cody/BUILD.bazel @@ -1,7 +1,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # gazelle:js_resolve vscode //:node_modules/@vscode # gazelle:js_files src/**/*.{ts,tsx} @@ -10,8 +10,8 @@ load("//dev:eslint.bzl", "eslint_config") npm_link_all_packages(name = "node_modules") -eslint_config( - deps = [ +eslint_config_and_lint_root( + config_deps = [ "//client/cody/scripts:tsconfig", "//client/cody/test/integration:tsconfig", ], diff --git a/client/common/BUILD.bazel b/client/common/BUILD.bazel index 91e7d1de1cb..f99738fc236 100644 --- a/client/common/BUILD.bazel +++ b/client/common/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/common/tsconfig.json b/client/common/tsconfig.json index 5e2fc40613b..1b8d963ddce 100644 --- a/client/common/tsconfig.json +++ b/client/common/tsconfig.json @@ -7,7 +7,7 @@ "outDir": "./out", "baseUrl": "./src", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], "references": [ { "path": "../extension-api-types", diff --git a/client/extension-api-types/BUILD.bazel b/client/extension-api-types/BUILD.bazel index 7f033124c68..aea73c15a1c 100644 --- a/client/extension-api-types/BUILD.bazel +++ b/client/extension-api-types/BUILD.bazel @@ -1,7 +1,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") package(default_visibility = ["//visibility:public"]) @@ -10,7 +10,7 @@ package(default_visibility = ["//visibility:public"]) npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/extension-api/.eslintrc.js b/client/extension-api/.eslintrc.js index 12e5f8f90e2..e74c327bedf 100644 --- a/client/extension-api/.eslintrc.js +++ b/client/extension-api/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { extends: '../../.eslintrc.js', parserOptions: { ...baseConfig.parserOptions, - project: __dirname + '/tsconfig.json', + project: __dirname + '/tsconfig.eslint.json', }, overrides: baseConfig.overrides, } diff --git a/client/extension-api/BUILD.bazel b/client/extension-api/BUILD.bazel index 89435e2876e..6670fd939c7 100644 --- a/client/extension-api/BUILD.bazel +++ b/client/extension-api/BUILD.bazel @@ -1,7 +1,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # Disable gazelle for the js/dts-only package # gazelle:js disabled @@ -11,7 +11,18 @@ package(default_visibility = ["//visibility:public"]) npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root( + config_deps = [":tsconfig-eslint"], +) + +ts_config( + name = "tsconfig-eslint", + src = "tsconfig.eslint.json", + visibility = ["//client:__subpackages__"], + deps = [ + "//:tsconfig", + ], +) ts_config( name = "tsconfig", diff --git a/client/extension-api/tsconfig.eslint.json b/client/extension-api/tsconfig.eslint.json new file mode 100644 index 00000000000..372f844bff6 --- /dev/null +++ b/client/extension-api/tsconfig.eslint.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "allowJs": true, + "outDir": "out", + "rootDir": "src", + }, + "include": ["src", "*.js"], +} diff --git a/client/http-client/BUILD.bazel b/client/http-client/BUILD.bazel index 1f82372f8ca..1fe0bc33938 100644 --- a/client/http-client/BUILD.bazel +++ b/client/http-client/BUILD.bazel @@ -1,7 +1,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") @@ -81,4 +81,4 @@ jest_test( ], ) -eslint_config() +eslint_config_and_lint_root() diff --git a/client/http-client/tsconfig.json b/client/http-client/tsconfig.json index bdea15729f2..a9485fc71c1 100644 --- a/client/http-client/tsconfig.json +++ b/client/http-client/tsconfig.json @@ -8,7 +8,7 @@ "baseUrl": "./src", "jsx": "react-jsx", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], "references": [ { "path": "../common", diff --git a/client/jetbrains/BUILD.bazel b/client/jetbrains/BUILD.bazel index a8546767cd1..5539bd625c8 100644 --- a/client/jetbrains/BUILD.bazel +++ b/client/jetbrains/BUILD.bazel @@ -1,14 +1,26 @@ load("@aspect_rules_js//js:defs.bzl", "js_library") load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # dts-only done manually # gazelle:js disabled npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() + +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob(["webview/src/**/*.story.tsx"]), + config = ":eslint_config", + deps = [ + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], +) ts_config( name = "tsconfig", diff --git a/client/observability-client/BUILD.bazel b/client/observability-client/BUILD.bazel index 6c471f7413e..0371b149ed4 100644 --- a/client/observability-client/BUILD.bazel +++ b/client/observability-client/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/observability-server/BUILD.bazel b/client/observability-server/BUILD.bazel index 350a7f6f153..3e3f0188c89 100644 --- a/client/observability-server/BUILD.bazel +++ b/client/observability-server/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/observability-server/tsconfig.json b/client/observability-server/tsconfig.json index 2c79f77465c..c1a0feae7a6 100644 --- a/client/observability-server/tsconfig.json +++ b/client/observability-server/tsconfig.json @@ -7,7 +7,7 @@ "outDir": "./out", "baseUrl": "./src", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], "references": [ { "path": "../build-config", diff --git a/client/shared/BUILD.bazel b/client/shared/BUILD.bazel index 952b773b38e..395fa7a8fbd 100644 --- a/client/shared/BUILD.bazel +++ b/client/shared/BUILD.bazel @@ -5,7 +5,7 @@ load("//dev:defs.bzl", "jest_test", "npm_package", "sass", "ts_project") load("//client/shared/dev:generate_schema.bzl", "generate_schema") load("//client/shared/dev:generate_graphql_operations.bzl", "generate_graphql_operations") load("//client/shared/dev:tools.bzl", "module_style_typings") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # TODO(bazel): storybook build # gazelle:exclude **/*.story.{ts,tsx} @@ -16,7 +16,22 @@ load("//dev:eslint.bzl", "eslint_config") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() + +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob([ + "src/**/*.story.tsx", + "src/**/*.fixtures.ts", + ]), + config = ":eslint_config", + deps = [ + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], +) ts_config( name = "tsconfig", diff --git a/client/storybook/BUILD.bazel b/client/storybook/BUILD.bazel index b49ad01f80b..c991f7b5c4b 100644 --- a/client/storybook/BUILD.bazel +++ b/client/storybook/BUILD.bazel @@ -1,7 +1,7 @@ load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "sass", "ts_project") load("//client/shared/dev:tools.bzl", "module_style_typings") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # gazelle:js_resolve **/*.module.scss :module_style_typings @@ -9,7 +9,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/storybook/tsconfig.json b/client/storybook/tsconfig.json index 48f7debc5bd..2f674393369 100644 --- a/client/storybook/tsconfig.json +++ b/client/storybook/tsconfig.json @@ -25,5 +25,5 @@ "path": "../wildcard", }, ], - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/template-parser/BUILD.bazel b/client/template-parser/BUILD.bazel index 85b9d045f4a..d2cae89ec19 100644 --- a/client/template-parser/BUILD.bazel +++ b/client/template-parser/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/template-parser/tsconfig.json b/client/template-parser/tsconfig.json index 0096b9f73a8..27a83aca1f6 100644 --- a/client/template-parser/tsconfig.json +++ b/client/template-parser/tsconfig.json @@ -7,5 +7,5 @@ "outDir": "./out", "baseUrl": "./src", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/testing/BUILD.bazel b/client/testing/BUILD.bazel index d9042108933..6b011d7bf39 100644 --- a/client/testing/BUILD.bazel +++ b/client/testing/BUILD.bazel @@ -1,11 +1,11 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "npm_package", "ts_project") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/testing/tsconfig.json b/client/testing/tsconfig.json index b86bed5ac3e..1532ece7185 100644 --- a/client/testing/tsconfig.json +++ b/client/testing/tsconfig.json @@ -9,5 +9,5 @@ "outDir": "./out", "baseUrl": "./src", }, - "include": ["./src/**/*", "./*.ts"], + "include": ["src", "*.js"], } diff --git a/client/vscode/BUILD.bazel b/client/vscode/BUILD.bazel index 1324bfb4855..ec11817e808 100644 --- a/client/vscode/BUILD.bazel +++ b/client/vscode/BUILD.bazel @@ -4,7 +4,7 @@ load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "sass", "ts_project") load("//client/shared/dev:generate_graphql_operations.bzl", "generate_graphql_operations") load("//client/shared/dev:tools.bzl", "module_style_typings") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root") # TODO(bazel): webpack workers? # gazelle:js_ignore_imports **/*.worker.ts @@ -14,7 +14,7 @@ load("//dev:eslint.bzl", "eslint_config") npm_link_all_packages(name = "node_modules") -eslint_config() +eslint_config_and_lint_root() ts_config( name = "tsconfig", diff --git a/client/web/BUILD.bazel b/client/web/BUILD.bazel index 19995d92753..8ecdde86fe1 100644 --- a/client/web/BUILD.bazel +++ b/client/web/BUILD.bazel @@ -6,8 +6,8 @@ load("//client/shared/dev:generate_graphql_operations.bzl", "generate_graphql_op load("//client/shared/dev:tools.bzl", "module_style_typings") load("//dev:defs.bzl", "jest_test", "npm_package", "sass", "ts_project") load("//dev:webpack.bzl", "webpack_bundle", "webpack_devserver", "webpack_web_app") -load("//dev:eslint.bzl", "eslint_config") load("@aspect_rules_ts//ts:defs.bzl", "ts_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # TODO(bazel): storybook build # gazelle:exclude **/*.story.{ts,tsx} @@ -22,12 +22,31 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") npm_link_all_packages(name = "node_modules") -eslint_config( - deps = [ +eslint_config_and_lint_root( + config_deps = [ "//client/web/src/end-to-end:tsconfig", "//client/web/src/integration:tsconfig", "//client/web/src/regression:tsconfig", ], + root_js_deps = [ + "//client/web/dev:dev", + ], +) + +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob([ + "src/**/*.story.tsx", + "src/**/*.fixtures.ts", # required for import/extensions rule not to fail. + ]), + config = ":eslint_config", + deps = [ + ":web_tests", + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], ) ts_config( diff --git a/client/web/dev/BUILD.bazel b/client/web/dev/BUILD.bazel index 88484e4046f..c181392704c 100644 --- a/client/web/dev/BUILD.bazel +++ b/client/web/dev/BUILD.bazel @@ -35,6 +35,7 @@ ts_project( ], module = "commonjs", tsconfig = ":tsconfig", + visibility = ["//client/web:__subpackages__"], deps = [ "//:node_modules/@types/compression", "//:node_modules/@types/connect-history-api-fallback", diff --git a/client/web/scripts/report-bundle-diff.ts b/client/web/scripts/report-bundle-diff.ts index f58495e31ee..fdd11e8890c 100644 --- a/client/web/scripts/report-bundle-diff.ts +++ b/client/web/scripts/report-bundle-diff.ts @@ -163,7 +163,7 @@ type Report = [Header, Metric, Metric, Metric, Metric, Metric, Metric, Metric, M function parseReport(commitFile: string, compareFile: string): Report { const queryFile = path.join(__dirname, 'report-bundle-jora-query') const rawReport = execSync(`cat "${queryFile}" | ${STATOSCOPE_BIN} query -i "${compareFile}" -i "${commitFile}"`, { - encoding: 'utf-8', + encoding: 'utf8', }) return JSON.parse(rawReport) as Report diff --git a/client/wildcard/BUILD.bazel b/client/wildcard/BUILD.bazel index 8ee26aed354..cd8046cdbd8 100644 --- a/client/wildcard/BUILD.bazel +++ b/client/wildcard/BUILD.bazel @@ -3,7 +3,7 @@ load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//dev:defs.bzl", "jest_test", "npm_package", "sass", "ts_project") load("//client/shared/dev:tools.bzl", "module_style_typings") -load("//dev:eslint.bzl", "eslint_config") +load("//dev:eslint.bzl", "eslint_config_and_lint_root", "eslint_test_with_types") # TODO(bazel): storybook build # gazelle:exclude **/*.story.{ts,tsx} @@ -13,6 +13,23 @@ load("//dev:eslint.bzl", "eslint_config") npm_link_all_packages(name = "node_modules") +eslint_config_and_lint_root() + +# Temporary ESLint target to lint stories. This will be removed once we have a +# custom gazelle targets. E.g., `gazelle:custom_js_files stories src/**/*.story.tsx` +eslint_test_with_types( + name = "stories_eslint", + srcs = glob([ + "src/**/*.story.tsx", + "src/**/*.fixtures.ts", + ]), + config = ":eslint_config", + deps = [ + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ], +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -24,8 +41,6 @@ ts_config( ], ) -eslint_config() - module_style_typings( name = "module_style_typings", deps = [ diff --git a/dev/BUILD.bazel b/dev/BUILD.bazel index e6aaa6ff8a6..d3c247754ac 100644 --- a/dev/BUILD.bazel +++ b/dev/BUILD.bazel @@ -5,4 +5,4 @@ webpack_binary( node_modules = "//:node_modules", ) -exports_files(srcs = ["mocha-xvfb.sh"]) +exports_files(srcs = ["eslint-report-test.sh"]) diff --git a/dev/defs.bzl b/dev/defs.bzl index 5ce329f5eec..2a476ec5955 100644 --- a/dev/defs.bzl +++ b/dev/defs.bzl @@ -32,8 +32,6 @@ def ts_project(name, srcs = [], deps = [], use_preset_env = True, **kwargs): name = "%s_eslint" % name, srcs = srcs, deps = deps, - testonly = True, - binary = "//:eslint", config = "//{}:eslint_config".format(get_client_package_path()), ) diff --git a/dev/eslint-report-test.sh b/dev/eslint-report-test.sh new file mode 100755 index 00000000000..b40fbceb10f --- /dev/null +++ b/dev/eslint-report-test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# The relative path to the eslint report +ESLINT_REPORT="$1" + +# Ensure that the eslint report exists +if [ ! -f "$ESLINT_REPORT" ]; then + echo "${ESLINT_REPORT} does not exist." + exit 1 +fi + +# Check if the eslint report is empty +if [ -s "$ESLINT_REPORT" ]; then + # Get the absolute path to the eslint report. + absolute_report_path="$(realpath "$ESLINT_REPORT")" + + # Remove everything before "__main__/" from the absolute path to the report. + workspace_report_path="${absolute_report_path#*__main__/}" + + # Print the relative report path. + echo "ESLint report: $workspace_report_path" + + cat "$ESLINT_REPORT" + exit 1 +else + echo "No ESLint issues found." + exit 0 +fi diff --git a/dev/eslint.bzl b/dev/eslint.bzl index b1713b17cd9..8723849b866 100644 --- a/dev/eslint.bzl +++ b/dev/eslint.bzl @@ -2,16 +2,33 @@ load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_files_to_bin_actions") load("//dev:js_lib.bzl", "gather_files_from_js_providers", "gather_runfiles") load("@aspect_rules_js//js:defs.bzl", "js_library") load("@aspect_rules_js//js:providers.bzl", "JsInfo") -load("@bazel_skylib//rules:build_test.bzl", "build_test") -def get_client_package_path(): - # Used to reference the `eslint_config` target in the client package - # We assume that eslint config files are located at `client/` - return "/".join(native.package_name().split("/")[:2]) +def eslint_config_and_lint_root(name = "eslint_config", config_deps = [], root_js_deps = []): + """ + Creates an ESLint configuration target and an ESLint test target for a client package root JS files. + + Args: + name: The name of the ESLint configuration target. + config_deps: A list of dependencies for the ESLint config target. + root_js_deps: A list of dependencies for the `root_js_eslint` target. + + The macro assumes the presence of specific files (".eslintrc.js", ".eslintignore", "package.json") + and a tsconfig target in the current directory. It adds a reference to a top-level ESLint configuration + as a dependency, and sets the visibility to the current package and its subpackages. + + For the 'root_js_eslint' target, it assumes all '.js' files in the current directory as its sources and + additional dependencies provided by 'root_js_deps'. It uses a global ESLint binary and the generated + ESLint configuration as its config. + + Example usage: + eslint_config_and_lint_root( + config_deps = ["//my:dependency"], + root_js_deps = ["//other:dependency"], + ) + """ -def eslint_config(deps = []): js_library( - name = "eslint_config", + name = name, testonly = True, srcs = [".eslintrc.js"], data = [ @@ -21,15 +38,28 @@ def eslint_config(deps = []): ], deps = [ "//:eslint_config", - ] + deps, + ] + config_deps, visibility = ["//{}:__subpackages__".format(get_client_package_path())], ) + eslint_test_with_types( + name = "root_js_eslint", + srcs = native.glob(["*.js"]), + config = ":eslint_config", + deps = [ + "//:jest_config", # required for import/extensions rule not to fail on the `jest.config.base` import. + "//:node_modules/@types/node", + ] + root_js_deps, + ) + +# This private rule implementation wraps the ESLint binary. +# It executes ESLint against the provided source files and +# ensures that depenencies' type are available at lint time. def _custom_eslint_impl(ctx): copied_srcs = copy_files_to_bin_actions(ctx, ctx.files.srcs) inputs_depset = depset( - copied_srcs, + copied_srcs + [ctx.executable.binary], transitive = [gather_files_from_js_providers( targets = [ctx.attr.config] + ctx.attr.deps, include_sources = False, @@ -47,24 +77,17 @@ def _custom_eslint_impl(ctx): deps = [], ) - args = ctx.actions.args() + # Declare the output file for the ESLint output. + report = ctx.actions.declare_file(ctx.attr.report) - # TODO: add context on why it doesn't work well with `overrides` globs. - # args.add("--no-eslintrc") - # args.add_all(["--config", get_path(ctx.files.config[0])]) + args = ctx.actions.args() # Create the argument list for the ESLint command. + args.add("--quiet") # Ignore warnings and fail only on errors. + args.add_all(["--format", "./{}".format(ctx.files.formatter[0].short_path)]) # Use the custom formatter to ouput relative paths. + args.add_all([s.short_path for s in copied_srcs]) # Specify the files to lint. + args.add_all(["--output-file", report.short_path]) # Specify the output file for the ESLint output. - # Ignore warnings and fail only on errors. - args.add("--quiet") - - # Use the custom formatter to ouput relative paths. - args.add_all(["--format", "./{}".format(ctx.files.formatter[0].short_path)]) - - # Specify the files to lint. - args.add_all([s.short_path for s in copied_srcs]) - - # Declare the output file for the eslint output. - output = ctx.actions.declare_file(ctx.attr.output) - # args.add_all(["--output-file", output.short_path]) + # Declare the output file for the exit code output. + exit_code_out = ctx.actions.declare_file("exit_%s" % ctx.attr.report) env = { "BAZEL_BINDIR": ctx.bin_dir.path, @@ -72,28 +95,45 @@ def _custom_eslint_impl(ctx): # "JS_BINARY__LOG_INFO": "1", # "JS_BINARY__LOG_ERROR": "1", # "JS_BINARY__SILENT_ON_SUCCESS": "0", - "JS_BINARY__STDOUT_OUTPUT_FILE": output.path, - "JS_BINARY__STDERR_OUTPUT_FILE": output.path, - # "JS_BINARY__EXPECTED_EXIT_CODE": "0", - # "JS_BINARY__EXIT_CODE_OUTPUT_FILE": output.path, + # "JS_BINARY__STDOUT_OUTPUT_FILE": report.path, + # "JS_BINARY__STDERR_OUTPUT_FILE": report.path, + "JS_BINARY__EXIT_CODE_OUTPUT_FILE": exit_code_out.path, } - ctx.actions.run( + # The script wrapper around the ESLint binary is essential to create an empty 'report' + # file in cases where ESLint finds no errors. Bazel expects all declared outputs of + # ctx.actions.run_shell to be created during its execution. Failure to do so results + # in Bazel errors, hence if ESLint doesn't generate a 'report', we manually create one. + command = """ + #!/usr/bin/env bash + set -o pipefail -o errexit -o nounset + + # Call the ESLint @aspect_rules_js wrapper. + "{binary}" "$@" + + # If the ESLint report is not created, create the empty one. + if [ ! -f "{report}" ]; then + touch "{report}" + fi + """.format(binary = ctx.executable.binary.path, report = report.path) + + # Generate and run a bash script to wrap the binary + ctx.actions.run_shell( env = env, inputs = inputs_depset, - outputs = [output], - executable = ctx.executable.binary, + outputs = [report, exit_code_out], + command = command, arguments = [args], mnemonic = "ESLint", ) return [ DefaultInfo( - files = depset([output]), + files = depset([report]), runfiles = runfiles, ), OutputGroupInfo( - output = depset([output]), + report = depset([report]), runfiles = runfiles.files, ), ] @@ -106,17 +146,54 @@ _eslint_test_with_types = rule( "config": attr.label(allow_single_file = True), "formatter": attr.label(allow_single_file = True, default = Label("//:eslint-relative-formatter")), "binary": attr.label(executable = True, cfg = "exec", allow_files = True), - "output": attr.string(), + "report": attr.string(), }, ) def eslint_test_with_types(name, **kwargs): - lint_name = "%s_lint" % name + """ + A higher-level function to perform an ESLint test on TypeScript files with type checking. - build_test(name, targets = [lint_name]) + Args: + name: A string representing the name of the test. + **kwargs: Arbitrary keyword arguments for additional customization of the test. This can + include the source files (`srcs`), dependencies (`deps`), ESLint configuration + (`config`), and more. + + This macro wraps the `_eslint_test_with_types` rule and subsequently runs a shell test to + verify the output. It generates an output report named '-output.txt' and a linting + target with the name of the original test suffixed with '_lint'. + + Example usage: + eslint_test_with_types( + name = "my_test", + srcs = ["my_file.ts"], + deps = [":my_dependency"], + testonly = True, + config = ":my_eslint_config", + ) + """ + lint_name = "%s_lint" % name + report = "%s-output.txt" % name _eslint_test_with_types( + testonly = True, name = lint_name, - output = "%s-output.txt" % name, + report = report, + binary = "//:eslint", **kwargs ) + + lint_target_name = ":%s" % lint_name + + native.sh_test( + name = name, + srcs = ["//dev:eslint-report-test.sh"], + args = ["$(location %s)" % lint_target_name], + data = [lint_target_name], + ) + +# This function provides the path to the client package, assuming +# that eslint config files are located at `client/`. +def get_client_package_path(): + return "/".join(native.package_name().split("/")[:2]) diff --git a/doc/dev/background-information/bazel_web.md b/doc/dev/background-information/bazel_web.md index a70e9e4f727..a05d1229e40 100644 --- a/doc/dev/background-information/bazel_web.md +++ b/doc/dev/background-information/bazel_web.md @@ -133,3 +133,10 @@ If you want to run tests for a specific package, replace `//...` with the packag bazel test `bazel query 'attr("name", ".*_typecheck_test", //client/vscode...)'` ``` +### How do I run ESLint on a client package? + +Similar to the above, we can use bazel query to find all target names ending with `_eslint` and test them: + +```sh +bazel test `bazel query 'attr("name", ".*_eslint$", //client/wildcard/...)'` +``` diff --git a/doc/dev/background-information/ci/reference.md b/doc/dev/background-information/ci/reference.md index 0bab2d92e53..01caba5428d 100644 --- a/doc/dev/background-information/ci/reference.md +++ b/doc/dev/background-information/ci/reference.md @@ -27,7 +27,7 @@ The default run type. - Tests - BackCompat Tests - **Linters and static analysis**: Run sg lint - - **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) + - **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - **Pipeline setup**: Trigger async - Pipeline for `GraphQL` changes: @@ -35,7 +35,7 @@ The default run type. - Ensure buildfiles are up to date - Tests - BackCompat Tests - - **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) + - **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - Pipeline for `DatabaseSchema` changes: - **Metadata**: Pipeline metadata @@ -150,9 +150,9 @@ The run type for environment including `{"BEXT_NIGHTLY":"true"}`. Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Test (client/browser) - Puppeteer tests for chrome extension - Test (all) @@ -164,9 +164,9 @@ The run type for environment including `{"VSCE_NIGHTLY":"true"}`. Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Tests for VS Code extension ### Cody VS Code extension nightly release build @@ -175,9 +175,9 @@ The run type for environment including `{"CODY_NIGHTLY":"true"}`. Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Unit, integration, and E2E tests for the Cody VS Code extension - Cody release @@ -211,7 +211,7 @@ Base pipeline (more steps might be included based on branch changes): - Tests - BackCompat Tests - **Linters and static analysis**: Run sg lint -- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) +- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - **Integration tests**: Backend integration tests (gRPC), Backend integration tests, Code Intel QA - **End-to-end tests**: Executors E2E, Sourcegraph E2E, Sourcegraph Upgrade - **Publish images**: server, executor, alpine-3.14, postgres-12-alpine, blobstore, cadvisor, codeinsights-db, codeintel-db, frontend, github-proxy, gitserver, grafana, indexed-searcher, migrator, node-exporter, opentelemetry-collector, postgres_exporter, precise-code-intel-worker, prometheus, prometheus-gcp, redis-cache, redis-store, redis_exporter, repo-updater, search-indexer, searcher, syntax-highlighter, worker, symbols, batcheshelper, blobstore2, bundled-executor, dind, embeddings, executor-kubernetes, executor-vm, jaeger-agent, jaeger-all-in-one, cody-gateway, sg, cody-slack, Publish executor image, Publish executor binary, Publish docker registry mirror image @@ -230,7 +230,7 @@ Base pipeline (more steps might be included based on branch changes): - Tests - BackCompat Tests - **Linters and static analysis**: Run sg lint -- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) +- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - **Integration tests**: Backend integration tests (gRPC), Backend integration tests, Code Intel QA - **End-to-end tests**: Executors E2E, Sourcegraph E2E, Sourcegraph Upgrade - **Publish images**: server, executor, alpine-3.14, postgres-12-alpine, blobstore, cadvisor, codeinsights-db, codeintel-db, frontend, github-proxy, gitserver, grafana, indexed-searcher, migrator, node-exporter, opentelemetry-collector, postgres_exporter, precise-code-intel-worker, prometheus, prometheus-gcp, redis-cache, redis-store, redis_exporter, repo-updater, search-indexer, searcher, syntax-highlighter, worker, symbols, batcheshelper, blobstore2, bundled-executor, dind, embeddings, executor-kubernetes, executor-vm, jaeger-agent, jaeger-all-in-one, cody-gateway, sg, cody-slack @@ -241,9 +241,9 @@ The run type for branches matching `bext/release` (exact match). Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Test (client/browser) - Puppeteer tests for chrome extension - Test (all) @@ -258,9 +258,9 @@ The run type for branches matching `vsce/release` (exact match). Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Tests for VS Code extension - Extension release @@ -270,9 +270,9 @@ The run type for branches matching `cody/release` (exact match). Base pipeline (more steps might be included based on branch changes): +- Stylelint (all) - ESLint (all) - ESLint (web) -- Stylelint (all) - Unit, integration, and E2E tests for the Cody VS Code extension - Cody release @@ -290,7 +290,7 @@ Base pipeline (more steps might be included based on branch changes): - Tests - BackCompat Tests - **Linters and static analysis**: Run sg lint -- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) +- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - **Integration tests**: Backend integration tests (gRPC), Backend integration tests, Code Intel QA - **End-to-end tests**: Executors E2E, Sourcegraph E2E, Sourcegraph Upgrade - **Publish images**: server, executor, alpine-3.14, postgres-12-alpine, blobstore, cadvisor, codeinsights-db, codeintel-db, frontend, github-proxy, gitserver, grafana, indexed-searcher, migrator, node-exporter, opentelemetry-collector, postgres_exporter, precise-code-intel-worker, prometheus, prometheus-gcp, redis-cache, redis-store, redis_exporter, repo-updater, search-indexer, searcher, syntax-highlighter, worker, symbols, batcheshelper, blobstore2, bundled-executor, dind, embeddings, executor-kubernetes, executor-vm, jaeger-agent, jaeger-all-in-one, cody-gateway, sg, cody-slack, Publish executor image, Publish executor binary @@ -314,7 +314,7 @@ Base pipeline (more steps might be included based on branch changes): - Tests - BackCompat Tests - **Linters and static analysis**: Run sg lint -- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, ESLint (all), ESLint (web), Stylelint (all) +- **Client checks**: Upload Storybook to Chromatic, Enterprise build, Build (client/jetbrains), Tests for VS Code extension, Unit, integration, and E2E tests for the Cody VS Code extension, Stylelint (all) - **Integration tests**: Backend integration tests (gRPC), Backend integration tests, Code Intel QA - **End-to-end tests**: Executors E2E, Sourcegraph E2E, Sourcegraph Upgrade - **Publish images**: server, executor, alpine-3.14, postgres-12-alpine, blobstore, cadvisor, codeinsights-db, codeintel-db, frontend, github-proxy, gitserver, grafana, indexed-searcher, migrator, node-exporter, opentelemetry-collector, postgres_exporter, precise-code-intel-worker, prometheus, prometheus-gcp, redis-cache, redis-store, redis_exporter, repo-updater, search-indexer, searcher, syntax-highlighter, worker, symbols, batcheshelper, blobstore2, bundled-executor, dind, embeddings, executor-kubernetes, executor-vm, jaeger-agent, jaeger-all-in-one, cody-gateway, sg, cody-slack diff --git a/enterprise/dev/ci/internal/ci/operations.go b/enterprise/dev/ci/internal/ci/operations.go index 91a76c7e29c..cb3cd696d42 100644 --- a/enterprise/dev/ci/internal/ci/operations.go +++ b/enterprise/dev/ci/internal/ci/operations.go @@ -22,10 +22,9 @@ import ( // e.g. by adding flags, and not as a condition for adding steps or commands. type CoreTestOperationsOptions struct { // for clientChromaticTests - ChromaticShouldAutoAccept bool - MinimumUpgradeableVersion string - ClientLintOnlyChangedFiles bool - ForceReadyForReview bool + ChromaticShouldAutoAccept bool + MinimumUpgradeableVersion string + ForceReadyForReview bool // for addWebAppOSSBuild CacheBundleSize bool CreateBundleSizeDiff bool @@ -80,6 +79,8 @@ func CoreTestOperations(diff changed.Diff, opts CoreTestOperationsOptions) *oper // addTypescriptCheck is now covered by Bazel addVsceTests, // ~3.0m addCodyExtensionTests, // ~2.5m + // addESLint, + addStylelint, ) } else { // If there are any Graphql changes, they are impacting the client as well. @@ -94,15 +95,11 @@ func CoreTestOperations(diff changed.Diff, opts CoreTestOperationsOptions) *oper addTypescriptCheck, // ~4m addVsceTests, // ~3.0m addCodyExtensionTests, // ~2.5m + addESLint, + addStylelint, ) } - if opts.ClientLintOnlyChangedFiles { - clientChecks.Append(addClientLintersForChangedFiles) - } else { - clientChecks.Append(addClientLintersForAllFiles) - } - ops.Merge(clientChecks) } @@ -169,8 +166,13 @@ func addTypescriptCheck(pipeline *bk.Pipeline) { bk.Cmd("dev/ci/pnpm-run.sh build-ts")) } -// Adds client linters to check all files. -func addClientLintersForAllFiles(pipeline *bk.Pipeline) { +func addStylelint(pipeline *bk.Pipeline) { + pipeline.AddStep(":stylelint: Stylelint (all)", + withPnpmCache(), + bk.Cmd("dev/ci/pnpm-run.sh lint:css:all")) +} + +func addESLint(pipeline *bk.Pipeline) { pipeline.AddStep(":eslint: ESLint (all)", withPnpmCache(), bk.Cmd("dev/ci/pnpm-run.sh lint:js:all")) @@ -178,21 +180,11 @@ func addClientLintersForAllFiles(pipeline *bk.Pipeline) { pipeline.AddStep(":eslint: ESLint (web)", withPnpmCache(), bk.Cmd("dev/ci/pnpm-run.sh lint:js:web")) - - pipeline.AddStep(":stylelint: Stylelint (all)", - withPnpmCache(), - bk.Cmd("dev/ci/pnpm-run.sh lint:css:all")) } -// Adds client linters to check changed in PR files. -func addClientLintersForChangedFiles(pipeline *bk.Pipeline) { - pipeline.AddStep(":eslint: ESLint (changed)", - withPnpmCache(), - bk.Cmd("dev/ci/pnpm-run.sh lint:js:changed")) - - pipeline.AddStep(":stylelint: Stylelint (changed)", - withPnpmCache(), - bk.Cmd("dev/ci/pnpm-run.sh lint:css:changed")) +func addClientLintersForAllFiles(pipeline *bk.Pipeline) { + addStylelint(pipeline) + addESLint(pipeline) } // Adds steps for the OSS and Enterprise web app builds. Runs the web app tests. diff --git a/enterprise/dev/ci/internal/ci/pipeline.go b/enterprise/dev/ci/internal/ci/pipeline.go index efd8a07658d..b1fef724bc2 100644 --- a/enterprise/dev/ci/internal/ci/pipeline.go +++ b/enterprise/dev/ci/internal/ci/pipeline.go @@ -173,10 +173,8 @@ func GeneratePipeline(c Config) (*bk.Pipeline, error) { ops.Merge(CoreTestOperations(c.Diff, CoreTestOperationsOptions{ MinimumUpgradeableVersion: minimumUpgradeableVersion, ForceReadyForReview: c.MessageFlags.ForceReadyForReview, - // TODO: (@umpox, @valerybugakov) Figure out if we can reliably enable this in PRs. - ClientLintOnlyChangedFiles: false, - CreateBundleSizeDiff: true, - ForceBazel: !c.MessageFlags.NoBazel, + CreateBundleSizeDiff: true, + ForceBazel: !c.MessageFlags.NoBazel, })) // At this stage, we don't break builds because of a Bazel failure.