[bazel] //cmd/presbmit/presubmit.go: Run "npm ci" step on CI.
In https://skia-review.googlesource.com/c/buildbot/+/787329 I updated Prettier to v3.1.0. Since then, we have seen some (but not all) Housekeeper-OnDemand-Presubmit tasks fail with:
npm WARN exec The following package was not found and will be installed: prettier
npm ERR! code E451
npm ERR! 451 unknown - GET https://npm.skia.org/skia-infra/prettier/-/prettier-3.1.1.tgz
Example: https://task-scheduler.skia.org/job/fybXDSw4BolKQ8FgX6ZP.
The reason for this failure is that:
- Bazel used to manage the node_modules directory for us, but this has ceased to be true since we upgraded to Bazel 6.0.0. This means we don't get a node_modules directory unless we explicitly create one, e.g. with "npm ci".
- The "npx prettier" command first looks for a "prettier" package in node_modules, and if it does not find it, it tries to download the latest "prettier" version, apparently ignoring the exact version specified in //package.json and/or //package-lock.json.
- "npx" fails to download "prettier" because the latest version (3.1.1) is too new, and therefore npm-audit-mirror rejects it, hence the 451 error.
The solution I've found is to run "npm ci" right before "npx prettier", which ensures we have a node_modules directory.
Bug: b/314813928
Change-Id: I2de92c62c82a682afd852f416330766eacfa5e9e
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/789219
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Auto-Submit: Leandro Lovisolo <lovisolo@google.com>
diff --git a/cmd/presubmit/presubmit.go b/cmd/presubmit/presubmit.go
index 579b7ec..418a88f 100644
--- a/cmd/presubmit/presubmit.go
+++ b/cmd/presubmit/presubmit.go
@@ -109,6 +109,16 @@
changedFiles, _ = computeDiffFiles(ctx, branchBaseCommit)
trackErrors(runGofmt(ctx, changedFiles, branchBaseCommit))
changedFiles, _ = computeDiffFiles(ctx, branchBaseCommit)
+ if *commit {
+ // When running the presubmit checks on CI, we must manually ensure that the node_modules
+ // directory exists because Bazel no longer manages that directory for us. Running "npm ci"
+ // accomplishes this. If the node_modules directory does not exist, the prettier step below
+ // will fail.
+ //
+ // When running the presubmit checks as part of the "git cl upload" command, it is the
+ // developer's responsibility to keep their node_modules directory up-to-date.
+ trackErrors(runNpmCi(ctx))
+ }
trackErrors(runPrettier(ctx, changedFiles, *repoDir, branchBaseCommit))
changedFiles, _ = computeDiffFiles(ctx, branchBaseCommit)
trackErrors(runGazelle(ctx, changedFiles, deletedFiles, branchBaseCommit))
@@ -675,6 +685,18 @@
return true
}
+// runNpmCi runs "npm ci" to ensure that the "node_modules" directory exists.
+func runNpmCi(ctx context.Context) bool {
+ cmd := exec.CommandContext(ctx, "bazelisk", "run", "--config=mayberemote", "//:npm", "--", "ci")
+ output, err := cmd.CombinedOutput()
+ if err != nil {
+ logf(ctx, "Command \"npm ci\" failed. Output:\n")
+ logf(ctx, string(output))
+ return false
+ }
+ return true
+}
+
// runPrettier runs prettier --write on any changed files. It returns false if
// prettier returns a non-zero error code.
func runPrettier(ctx context.Context, files []fileWithChanges, workspaceRoot, branchBaseCommit string) bool {