Skip to content

Commit

Permalink
use nvm from base image
Browse files Browse the repository at this point in the history
  • Loading branch information
barbados-clemens committed May 24, 2024
1 parent 2a772f8 commit c5e955c
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 20 deletions.
93 changes: 73 additions & 20 deletions workflow-steps/install-node/main.js
Original file line number Diff line number Diff line change
@@ -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 || ''}`,
);
}
}
3 changes: 3 additions & 0 deletions workflow-steps/install-node/main.yaml
Original file line number Diff line number Diff line change
@@ -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'
Expand Down

0 comments on commit c5e955c

Please sign in to comment.