Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/node/devcontainer-feature.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@
"default": "/usr/local/share/nvm",
"description": "The path where NVM will be installed."
},
"npmVersion": {
"type": "string",
"proposals": [
"lts",
"latest",
"10.9.0",
"10.8.0",
"10.7.0",
"9.9.3",
"8.19.4",
"latest",
"none"
],
"default": "10.9.0",
"description": "Select or enter a specific NPM version to install globally. Use 'latest' for the latest version, 'none' to skip npm version update, or specify a version like '10.9.0'."
},
"pnpmVersion": {
"type": "string",
"proposals": [
Expand Down Expand Up @@ -78,4 +94,4 @@
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
}
36 changes: 36 additions & 0 deletions src/node/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Maintainer: The Dev Container spec maintainers

export NODE_VERSION="${VERSION:-"lts"}"
export NPM_VERSION="${NPMVERSION:-"lts"}"
export PNPM_VERSION="${PNPMVERSION:-"latest"}"
export NVM_VERSION="${NVMVERSION:-"latest"}"
export NVM_DIR="${NVMINSTALLPATH:-"/usr/local/share/nvm"}"
Expand Down Expand Up @@ -381,6 +382,41 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then
IFS=$OLDIFS
fi

# Install or update npm to specific version
if [ ! -z "${NPM_VERSION}" ] && [ "${NPM_VERSION}" = "none" ]; then
echo "Ignoring NPM version update"
else
if bash -c ". '${NVM_DIR}/nvm.sh' && type npm >/dev/null 2>&1"; then
(
. "${NVM_DIR}/nvm.sh"
[ ! -z "$http_proxy" ] && npm set proxy="$http_proxy"
[ ! -z "$https_proxy" ] && npm set https-proxy="$https_proxy"
[ ! -z "$no_proxy" ] && npm set noproxy="$no_proxy"
echo "Installing npm version ${NPM_VERSION}..."

# Clear npm cache to avoid conflicts
npm cache clean --force 2>/dev/null || true

# Try npm installation with retries
for i in {1..3}; do
if npm install -g npm@$NPM_VERSION --force; then
echo "Successfully installed npm@${NPM_VERSION}"
break
else
echo "Attempt $i failed, retrying..."
sleep 2
if [ $i -eq 3 ]; then
echo "Failed to install npm@${NPM_VERSION} after 3 attempts. Trying latest npm as fallback..."
npm install -g npm@latest --force || echo "Fallback to latest npm also failed. Keeping current npm version $(npm --version 2>/dev/null || echo 'unknown')."
fi
fi
done
)
else
echo "Skip installing/updating npm because npm is not available"
fi
fi

# Install pnpm
if [ ! -z "${PNPM_VERSION}" ] && [ "${PNPM_VERSION}" = "none" ]; then
echo "Ignoring installation of PNPM"
Expand Down
15 changes: 15 additions & 0 deletions test/node/install_npm_latest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Verify npm is latest version (valid version format)
check "npm_latest_version" bash -c "npm -v | grep -E '^[0-9]+\.[0-9]+\.[0-9]+'"

# Also verify pnpm works as configured
check "pnpm_version" bash -c "pnpm -v | grep 8.8.0"

# Report result
reportResults
12 changes: 12 additions & 0 deletions test/node/install_npm_none.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# When npmVersion is "none", npm should not be updated from node's bundled version
check "npm_not_updated" bash -c "npm --version"

# Report result
reportResults
12 changes: 12 additions & 0 deletions test/node/install_specific_npm_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Verify npm is installed with specific version 10.8.0
check "npm_specific_version" bash -c "npm -v | grep '^10.8.0'"

# Report result
reportResults
38 changes: 33 additions & 5 deletions test/node/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
"version": "lts"
}
}
},
},
"install_node_debian_bookworm": {
"image": "debian:12",
"features": {
"node": {
"version": "lts"
}
}
},
},
"nvm_test_fallback": {
"image": "debian:11",
"features": {
"node": {
"version": "lts"
}
}
},
},
"install_additional_node": {
"image": "debian:11",
"features": {
Expand Down Expand Up @@ -98,7 +98,7 @@
"features": {
"node": {
"version": "22",
"pnpmVersion":"8.8.0"
"pnpmVersion": "8.8.0"
}
}
},
Expand Down Expand Up @@ -207,5 +207,33 @@
"version": "lts"
}
}
},
"install_specific_npm_version": {
"image": "debian:12",
"features": {
"node": {
"version": "lts",
"npmVersion": "10.8.0"
}
}
},
"install_npm_none": {
"image": "mcr.microsoft.com/devcontainers/base",
"features": {
"node": {
"version": "lts",
"npmVersion": "none"
}
}
},
"install_npm_latest": {
"image": "debian:12",
"features": {
"node": {
"version": "22",
"npmVersion": "latest",
"pnpmVersion": "8.8.0"
}
}
}
}
}
Loading