mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-07-18 12:58:21 +08:00
The full suite cannot run on Alpine: the install-based suites pin ancient Node (0.10.x, io.js) that has no musl binary and cannot source-compile on musl. Run the fast unit suite instead (mirroring the ubuntu runner: non-root via su-exec, passwordless sudo, a PTY, no system node), plus a binary-only regression matrix that installs every (Alpine, Node) pair with a real unofficial musl binary via `nvm install -b`: x64 back to node 8.17.0 on old Alpine, arm64 at the v20.20.1/v22.21.1/v24.9.0 floors on modern Alpine.
194 lines
7.4 KiB
YAML
194 lines
7.4 KiB
YAML
name: 'Tests: alpine'
|
|
|
|
on: [push, pull_request]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
fast:
|
|
permissions:
|
|
contents: read
|
|
|
|
# Native runners per arch (no QEMU): arm64 uses the ubuntu-24.04-arm image.
|
|
name: 'fast ${{ matrix.arch }} (alpine ${{ matrix.alpine }}, ${{ matrix.shell }})'
|
|
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
alpine:
|
|
- '3.15'
|
|
- '3.19'
|
|
- '3'
|
|
arch:
|
|
- x64
|
|
- arm64
|
|
shell:
|
|
- sh
|
|
- bash
|
|
- dash
|
|
- zsh
|
|
# - ksh (#574)
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@v2
|
|
with:
|
|
allowed-endpoints:
|
|
github.com:443
|
|
registry.npmjs.org:443
|
|
raw.githubusercontent.com:443
|
|
nodejs.org:443
|
|
iojs.org:443
|
|
unofficial-builds.nodejs.org:443
|
|
dl-cdn.alpinelinux.org:443
|
|
dl-cdn.alpinelinux.org:80
|
|
registry-1.docker.io:443
|
|
auth.docker.io:443
|
|
production.cloudflare.docker.com:443
|
|
production.cloudfront.docker.com:443
|
|
- uses: actions/checkout@v6
|
|
id: checkout
|
|
continue-on-error: true
|
|
with:
|
|
submodules: true
|
|
- name: 'nvmrc submodule fallback (forks without their own nvmrc)'
|
|
if: steps.checkout.outcome == 'failure'
|
|
shell: bash
|
|
run: |
|
|
git submodule set-url test/fixtures/nvmrc https://github.com/nvm-sh/nvmrc.git
|
|
git submodule sync --recursive
|
|
git submodule update --init --recursive
|
|
- uses: ljharb/actions/node/install@main
|
|
name: 'npm install (on host; node_modules is mounted into the container)'
|
|
with:
|
|
node-version: 'lts/*'
|
|
skip-ls-check: true
|
|
- run: npm ls urchin
|
|
- name: 'Run fast tests on Alpine ${{ matrix.alpine }} (${{ matrix.arch }})'
|
|
run: |
|
|
for i in 1 2 3 4 5; do
|
|
docker pull alpine:${{ matrix.alpine }} && break
|
|
echo "docker pull failed, attempt $i/5"; sleep $((i * 5))
|
|
done
|
|
docker run --rm \
|
|
-v "${{ github.workspace }}:/workspace" \
|
|
-w /workspace \
|
|
-e "TEST_SHELL=${{ matrix.shell }}" \
|
|
-e "TERM=xterm-256color" \
|
|
-e "GITHUB_ACTIONS=true" \
|
|
alpine:${{ matrix.alpine }} \
|
|
sh -c '
|
|
set -ex
|
|
cat /etc/alpine-release; uname -m
|
|
for i in 1 2 3 4 5; do
|
|
apk add --no-cache \
|
|
make bash zsh dash \
|
|
grep sed gawk coreutils util-linux findutils ncurses \
|
|
curl wget ca-certificates openssl tar xz gzip git \
|
|
sudo su-exec libstdc++ libgcc && break
|
|
echo "apk add failed, attempt $i/5"; sleep $((i * 5))
|
|
done
|
|
# Mirror the ubuntu runner: run the suite as a non-root user with
|
|
# passwordless sudo and a PTY so the permission/terminal tests
|
|
# behave the same. The user takes the mounted checkout uid so
|
|
# files stay host-owned (no chown; post-checkout cleanup works).
|
|
# No node is installed, so no active version skews the output.
|
|
HOST_UID="$(stat -c %u /workspace)"
|
|
adduser -D -u "$HOST_UID" tester 2>/dev/null || adduser -D tester
|
|
echo "tester ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/tester
|
|
chmod 0440 /etc/sudoers.d/tester
|
|
export NVM_DIR=/workspace HOME=/home/tester
|
|
unset NVM_BIN NVM_INC NVM_CD_FLAGS
|
|
su-exec tester script -q -e -c "make TEST_SUITE=fast SHELL=$TEST_SHELL URCHIN=/workspace/node_modules/.bin/urchin test-$TEST_SHELL" /dev/null
|
|
'
|
|
|
|
musl-binary:
|
|
permissions:
|
|
contents: read
|
|
|
|
# Regression lock, same-era diagonal only: modern musl node needs a newer
|
|
# libstdc++ than old Alpine ships, and arm64-musl exists only from
|
|
# v20.20.1/v22.21.1/v24.9.0 (built on modern Alpine), so arm64 pins modern Alpine.
|
|
name: 'musl-binary ${{ matrix.arch }} (alpine ${{ matrix.alpine }}, node ${{ matrix.node }})'
|
|
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { arch: x64, alpine: '3.10', node: v8.17.0 }
|
|
- { arch: x64, alpine: '3.10', node: v10.24.1 }
|
|
- { arch: x64, alpine: '3.12', node: v12.22.12 }
|
|
- { arch: x64, alpine: '3.15', node: v14.21.3 }
|
|
- { arch: x64, alpine: '3.16', node: v16.20.2 }
|
|
- { arch: x64, alpine: '3.18', node: v18.20.4 }
|
|
- { arch: x64, alpine: '3.20', node: v20.18.1 }
|
|
- { arch: x64, alpine: '3', node: v22.12.0 }
|
|
- { arch: arm64, alpine: '3.20', node: v20.20.1 }
|
|
- { arch: arm64, alpine: '3', node: v22.21.1 }
|
|
- { arch: arm64, alpine: '3', node: v24.9.0 }
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@v2
|
|
with:
|
|
allowed-endpoints:
|
|
github.com:443
|
|
registry.npmjs.org:443
|
|
unofficial-builds.nodejs.org:443
|
|
dl-cdn.alpinelinux.org:443
|
|
dl-cdn.alpinelinux.org:80
|
|
registry-1.docker.io:443
|
|
auth.docker.io:443
|
|
production.cloudflare.docker.com:443
|
|
production.cloudfront.docker.com:443
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
submodules: false
|
|
- name: 'Install node ${{ matrix.node }} from a musl binary on Alpine ${{ matrix.alpine }}'
|
|
run: |
|
|
for i in 1 2 3 4 5; do
|
|
docker pull alpine:${{ matrix.alpine }} && break
|
|
echo "docker pull failed, attempt $i/5"; sleep $((i * 5))
|
|
done
|
|
docker run --rm \
|
|
-v "${{ github.workspace }}:/workspace" \
|
|
-w /workspace \
|
|
-e "NODE_VERSION=${{ matrix.node }}" \
|
|
-e "TERM=xterm-256color" \
|
|
alpine:${{ matrix.alpine }} \
|
|
sh -c '
|
|
set -ex
|
|
cat /etc/alpine-release; uname -m
|
|
# libstdc++/libgcc are load-bearing: the unofficial musl node
|
|
# binary dynamically links them. No build toolchain: -b forbids
|
|
# the source fallback, so a missing binary is a hard failure.
|
|
for i in 1 2 3 4 5; do
|
|
apk add --no-cache \
|
|
bash ca-certificates curl wget tar xz gzip \
|
|
grep sed coreutils libstdc++ libgcc && break
|
|
echo "apk add failed, attempt $i/5"; sleep $((i * 5))
|
|
done
|
|
export NVM_DIR=/workspace
|
|
unset NVM_BIN NVM_INC NVM_CD_FLAGS
|
|
# The default nodejs.org mirror serves no -musl artifacts; this one does.
|
|
export NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release
|
|
. /workspace/nvm.sh --no-use
|
|
nvm install -b --skip-default-packages "$NODE_VERSION"
|
|
nvm use "$NODE_VERSION"
|
|
[ "$(node -v)" = "$NODE_VERSION" ] || { echo "version mismatch: $(node -v)"; exit 1; }
|
|
node -e "process.exit(0)"
|
|
ldd "$(command -v node)" | grep -qi musl
|
|
'
|
|
|
|
all:
|
|
permissions:
|
|
contents: none
|
|
name: 'all alpine tests'
|
|
needs: [fast, musl-binary]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: true
|