From 7cd73d526a16588e5389d7d3b7cd862dfa607c07 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 4 Aug 2022 10:58:56 -0700 Subject: [PATCH 1/2] switch e2e tests to use corepack A quick and dirty switch to use corepack for managing package managers for our e2e tests. A few things to note: - Running these tests on a local machine will enable corepack on that machine, this could be undesired for some devs. - I found that it is necessary to forcibly add the corepack install dir to the top of $PATH in case a dev has a package manager installed elsewhere that would take priority. --- cli/scripts/e2e/e2e.ts | 16 ++++++++++++++-- cli/scripts/monorepo.ts | 21 +++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/cli/scripts/e2e/e2e.ts b/cli/scripts/e2e/e2e.ts index d79ecfc704efd..f549eee938561 100644 --- a/cli/scripts/e2e/e2e.ts +++ b/cli/scripts/e2e/e2e.ts @@ -36,10 +36,12 @@ const basicPipeline = { // This is injected by github actions process.env.TURBO_TOKEN = ""; +const COREPACK_BIN_DIR = setupCorepack(); + let suites = []; for (let npmClient of ["yarn", "berry", "pnpm", "npm"] as const) { const Suite = uvu.suite(`${npmClient}`); - const repo = new Monorepo("basics"); + const repo = new Monorepo("basics", COREPACK_BIN_DIR); repo.init(npmClient, basicPipeline); repo.install(); repo.addPackage("a", ["b"]); @@ -48,7 +50,7 @@ for (let npmClient of ["yarn", "berry", "pnpm", "npm"] as const) { repo.linkPackages(); repo.expectCleanGitStatus(); runSmokeTests(Suite, repo, npmClient); - const sub = new Monorepo("in-subdirectory"); + const sub = new Monorepo("in-subdirectory", COREPACK_BIN_DIR); sub.init(npmClient, basicPipeline, "js"); sub.install(); sub.addPackage("a", ["b"]); @@ -590,3 +592,13 @@ function getCachedLogFilePathForTask( ): string { return path.join(cacheDir, pathToPackage, ".turbo", `turbo-${taskName}.log`); } + +// Setup corepack and provide the dir to the binaries that corepack installs +// It is important that this dir has a higher priority in $PATH than any other +// dirs that may versions of package managers installed by other mechanisms +// e.g. homebrew or pnpm +function setupCorepack(): string { + execa.sync("corepack", ["enable"]); + const corepack_path = execa.sync("which", ["corepack"]).stdout; + return path.dirname(corepack_path); +} diff --git a/cli/scripts/monorepo.ts b/cli/scripts/monorepo.ts index ab33047ea0082..0d22b7acfb164 100644 --- a/cli/scripts/monorepo.ts +++ b/cli/scripts/monorepo.ts @@ -13,6 +13,7 @@ export class Monorepo { static tmpdir = os.tmpdir(); static yarnCache = path.join(__dirname, "yarn-cache-"); root: string; + corepackDir?: string; subdir?: string; name: string; npmClient: NPMClient; @@ -21,9 +22,16 @@ export class Monorepo { ? path.join(this.root, this.subdir, "node_modules") : path.join(this.root, "node_modules"); } + get binPath() { + const path_delimiter = process.platform == "win32" ? ";" : ":"; + return this.corepackDir + ? `${this.corepackDir}${path_delimiter}${process.env.PATH}` + : process.env.PATH; + } - constructor(name) { + constructor(name: string, corepackDir?: string) { this.root = fs.mkdtempSync(path.join(__dirname, `turbo-monorepo-${name}-`)); + this.corepackDir = corepackDir; } init(npmClient: NPMClient, turboConfig = {}, subdir?: string) { @@ -116,12 +124,14 @@ importers: }); execa.sync("pnpm", ["install", "--recursive"], { cwd, + env: { PATH: this.binPath }, }); return; } if (this.npmClient == "npm") { execa.sync("npm", ["install"], { cwd, + env: { PATH: this.binPath }, }); this.commitAll(); return; @@ -154,13 +164,11 @@ importers: this.commitFiles({ "yarn.lock": yarnYaml }); if (this.npmClient == "berry") { - execa.sync("yarn", ["set", "version", "stable"], { - cwd, - }); execa.sync("yarn", ["install"], { cwd, env: { YARN_ENABLE_IMMUTABLE_INSTALLS: "false", + PATH: this.binPath, }, }); this.commitAll(); @@ -323,6 +331,7 @@ fs.copyFileSync( return execa.sync(turboPath, [command, ...resolvedArgs], { cwd: this.root, shell: true, + env: { PATH: this.binPath }, ...options, }); } @@ -333,24 +342,28 @@ fs.copyFileSync( return execa.sync("yarn", [command, ...(args || [])], { cwd: this.root, shell: true, + env: { PATH: this.binPath }, ...options, }); case "berry": return execa.sync("yarn", [command, ...(args || [])], { cwd: this.root, shell: true, + env: { PATH: this.binPath }, ...options, }); case "pnpm": return execa.sync("pnpm", [command, ...(args || [])], { cwd: this.root, shell: true, + env: { PATH: this.binPath }, ...options, }); case "npm": return execa.sync("npm", ["run", command, ...(args || [])], { cwd: this.root, shell: true, + env: { PATH: this.binPath }, ...options, }); default: From 782c1b3005be8cc5191c418f098c2e0557cf85fc Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 4 Aug 2022 16:41:22 -0700 Subject: [PATCH 2/2] setup latest corepack version on CI to avoid https://github.com/nodejs/corepack/issues/110 --- .github/workflows/ci-go.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-go.yml b/.github/workflows/ci-go.yml index d2d71988cbb1f..a4664a008205a 100644 --- a/.github/workflows/ci-go.yml +++ b/.github/workflows/ci-go.yml @@ -55,7 +55,25 @@ jobs: cache: pnpm - name: Install dependencies - run: pnpm install + # corepack 0.10 has a race condition in it that can cause the inital + # package manger installs to fail. + # Once we update to a version of node that ships with corepack 0.12 or + # higher we can remove the second install command. + # Windows installs global packages to a directory that has lower priority than + # the default node install so we also need to edit $PATH + shell: bash + run: | + pnpm install; + if [ "$RUNNER_OS" == "Windows" ]; then + npm install --force --global corepack@latest + npm config get prefix >> $GITHUB_PATH + else + npm install --global corepack@latest + fi + + + - name: Debug CI @donotmerge + run: which -a corepack; echo $PATH; corepack -v - name: Build & Unit Test run: pnpm -- turbo run test --filter=cli --color