From c5e955c09900fd593e6d0887e8a4057f2c4aaf71 Mon Sep 17 00:00:00 2001 From: Caleb Ukle Date: Tue, 14 May 2024 12:41:17 -0500 Subject: [PATCH] use nvm from base image --- workflow-steps/install-node/main.js | 93 +++++++++++++++++++++------ workflow-steps/install-node/main.yaml | 3 + 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/workflow-steps/install-node/main.js b/workflow-steps/install-node/main.js index 0a49929..0134b72 100644 --- a/workflow-steps/install-node/main.js +++ b/workflow-steps/install-node/main.js @@ -1,36 +1,89 @@ const { execSync } = require('child_process'); -const { existsSync } = require('fs'); +const { existsSync, readFileSync } = require('fs'); -// TODO: switch step to remove nvm instaall when nvm is in the base image -if (process.env.NX_CLOUD_NODE_VERSION || existsSync('.nvmrc')) { +// Allow using inputs or env until we fully switch to inputs +const nodeVersionInput = + process.env.NX_CLOUD_INPUT_node_version || process.env.NODE_VERSION; + +// set defaults incase they are not set yet +process.env.NVM_DIR ??= '/home/workflows/.nvm'; +process.env.COREPACK_ENABLE_AUTO_PIN ??= 0; + +const maybeVoltaNodeVersion = getVoltaNodeVersion(); + +if (nodeVersionInput) { + runNvmInstall(nodeVersionInput); +} else if (isUsingNvm()) { + // nvm will auto detect version in .nvmrc, no need to pass version + runNvmInstall(null); +} else if (maybeVoltaNodeVersion) { + runNvmInstall(maybeVoltaNodeVersion); +} else { + console.warn( + `No node version specified. You can use the step inputs to define a node version.`, + ); + console.log( + `Falling back to the default node version in the base image. ${execSync( + 'node -v', + )}`, + ); +} + +function getVoltaNodeVersion() { try { - // have to run as single command to keep the nvm env vars in the same shell - - // nvm does not work with npm_config_prefix set, so unset it - const nvmSetupCommand = `unset NPM_CONFIG_PREFIX`; - const nvmInstallCommand = `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash && source ~/.profile`; - // if NX_CLOUD_NODE_VERSION is set, use it, otherwise assume a .nvmrc file exists - const installNodeCommand = `nvm install ${ - process.env.NX_CLOUD_NODE_VERSION || '' + if (existsSync('package.json')) { + const packageJsonContents = + JSON.parse(readFileSync('package.json')) ?? {}; + + return packageJsonContents['volta']?.['node']; + } + } catch (e) { + return null; + } +} + +function isUsingNvm() { + try { + return existsSync('.nvmrc'); + } catch (e) { + return false; + } +} + +function runNvmInstall(version) { + try { + // enable nvm and then run the install command + // nvm command isn't available since nx agents don't run the bash profile + const installNodeWithNvm = `. $NVM_DIR/nvm.sh && nvm install ${ + version || '' } --default`; - // nvm sets up the node path in the active shell - // we need to append it to the nx cloud env, so next steps will get the correct node version - const appendPathCommand = `echo "PATH=$PATH" >> ${process.env.NX_CLOUD_ENV}`; + const reenableCorePack = `corepack enable`; + // install outside of the current directory, + // otherwise corepack errors if a different package mangager is used than is defined in the workspace + const reinstallPackageManagers = `cd .. && corepack prepare yarn@1 && corepack prepare pnpm@8`; + const printVersions = ['node', 'npm', 'yarn', 'pnpm'] + .map((cmd) => `echo "${cmd}: $(${cmd} -v)"`) + .join(' && '); + + // path will be updated via nvm to include the new node versions, + const saveEnvVars = `echo "PATH=$PATH\nNVM_DIR=${process.env.NVM_DIR}\nCOREPACK_ENABLE_AUTO_PIN=0" >> $NX_CLOUD_ENV`; execSync( - `${nvmSetupCommand} && ${nvmInstallCommand} && ${installNodeCommand} && ${appendPathCommand}`, + [ + installNodeWithNvm, + reenableCorePack, + reinstallPackageManagers, + printVersions, + saveEnvVars, + ].join(' && '), { stdio: 'inherit', - // use bash, since we need to call `source` to load nvm - shell: '/bin/bash', }, ); } catch (e) { console.error(e); throw new Error( - `Failed to install node version using nvm ${ - process.env.NX_CLOUD_NODE_VERSION || '' - }`, + `Failed to install node version using nvm ${version || ''}`, ); } } diff --git a/workflow-steps/install-node/main.yaml b/workflow-steps/install-node/main.yaml index 0640bc3..02110f1 100644 --- a/workflow-steps/install-node/main.yaml +++ b/workflow-steps/install-node/main.yaml @@ -1,5 +1,8 @@ name: Install Node description: Install a specific version of Node.js via nvm +inputs: + - name: node_version + description: 'The node version to be installed' definition: using: 'node'