Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fnm to switch between node version #253

Merged
merged 8 commits into from
Sep 6, 2024
Merged
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

- Include fnm and Nodejs 18, 20 and 22 in the kitchen sink image
([#253](https://github.com/pulumi/pulumi-docker-containers/pull/253)

## 3.131.0

- Add per-language versions of the `pulumi/pulumi-dotnet` image
Expand Down
26 changes: 13 additions & 13 deletions docker/pulumi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,6 @@ RUN \
kubectl && \
rm -rf /var/lib/apt/lists/*

# Install nodejs and associated tools
RUN \
# Add yarn repo
curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
# Add nodejs repo
curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
# Install packages
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
nodejs \
yarn && \
rm -rf /var/lib/apt/lists/*

# Install Go
RUN curl -fsSLo /tmp/go.tgz https://golang.org/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz && \
echo "${GOLANG_SHA256} /tmp/go.tgz" | sha256sum -c - && \
Expand Down Expand Up @@ -132,6 +119,19 @@ RUN ln -s /usr/local/share/pypoetry/bin/poetry /usr/local/bin/
# poetry will create virtual environments using the python version used by poetry itself.
RUN poetry config virtualenvs.prefer-active-python true

# Install default nodejs versions and associated tools
RUN curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir "/usr/local/share/fnm" --skip-shell && \
ln -s /usr/local/share/fnm/fnm /usr/local/bin/fnm
ENV FNM_COREPACK_ENABLED="true"
ENV FNM_VERSION_FILE_STRATEGY="recursive"
ENV FNM_DIR=/usr/local/share/fnm
RUN fnm install 18 && \
fnm install 20 && \
fnm install 22 && \
fnm alias 18 default
ENV PATH=/usr/local/share/fnm/aliases/default/bin:$PATH
RUN corepack install --global pnpm yarn

# Passing --build-arg PULUMI_VERSION=vX.Y.Z will use that version
# of the SDK. Otherwise, we use whatever get.pulumi.com thinks is
# the latest
Expand Down
55 changes: 47 additions & 8 deletions tests/containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,34 +122,73 @@ func TestPulumiTemplateTests(t *testing.T) {
example := base.With(integration.ProgramTestOptions{
Dir: e.RootPath,
Config: test.config,
// `pulumi new` already runs `pulumi install for us, don't attempt to `yarn link`
// the SDK into the test.
PrepareProject: func(info *engine.Projinfo) error {
return nil
},
})

integration.ProgramTest(t, &example)
})
}
}

func TestKitchenSinkPythonVersions(t *testing.T) {
func TestKitchenSinkLanguageVersions(t *testing.T) {
if !isKitchenSink(t) {
t.Skip("Only running python version tests on kitchen sink")
t.Skip("Only language version tests on kitchen sink")
}
t.Parallel()

dirs, err := testdata.ReadDir("testdata")
require.NoError(t, err)

t.Run("node-default", func(t *testing.T) {
// We need to run the `node-default` test first, before the other tests which modify
// the container's default node version.
p := filepath.Join("testdata", "node-default")
copyTestData(t, p)
integration.ProgramTest(t, &integration.ProgramTestOptions{
NoParallel: true,
Dir: p,
Quick: true,
SkipRefresh: true,
PrepareProject: func(info *engine.Projinfo) error {
cmd := exec.Command("pulumi", "install", "--use-language-version-tools")
cmd.Dir = info.Root
out, err := cmd.CombinedOutput()
if err != nil {
t.Logf("install failed: %s: %s", err, out)
}
return err
},
})
})

for _, dir := range dirs {
dir := dir
t.Run(dir.Name(), func(t *testing.T) {
if dir.Name() == "node-default" {
// The `node-default` test is run first, so we skip it here.
t.Skip()
}
p := filepath.Join("testdata", dir.Name())
copyTestData(t, p)
integration.ProgramTest(t, &integration.ProgramTestOptions{
// We can't run the node tests in parallel because setting the node version is a
// global for the container.
NoParallel: strings.HasPrefix(dir.Name(), "node-"),
Dir: p,
Quick: true,
SkipRefresh: true,
PrepareProject: func(info *engine.Projinfo) error {
cmd := exec.Command("pulumi", "install", "--use-language-version-tools")
cmd.Dir = info.Root
return cmd.Run()
out, err := cmd.CombinedOutput()
if err != nil {
t.Logf("install failed: %s: %s", err, out)
}
return err
},
})
})
Expand Down Expand Up @@ -283,26 +322,26 @@ func TestEnvironment(t *testing.T) {
name: "node",
expectedDebian: "/usr/local/bin/node",
expectedUbi: "/usr/bin/node",
expectedKitchen: "/usr/bin/node",
expectedKitchen: "/usr/local/share/fnm/aliases/default/bin/node",
},
{
name: "npm",
expectedDebian: "/usr/local/bin/npm",
expectedUbi: "/usr/local/bin/npm",
expectedKitchen: "/usr/bin/npm",
expectedKitchen: "/usr/local/share/fnm/aliases/default/bin/npm",
},

{
name: "yarn",
expectedDebian: "/usr/local/bin/yarn",
expectedUbi: "/usr/local/bin/yarn",
expectedKitchen: "/usr/bin/yarn",
expectedKitchen: "/usr/local/share/fnm/aliases/default/bin/yarn",
},
{
name: "corepack",
expectedDebian: "/usr/local/bin/corepack",
expectedUbi: "/usr/bin/corepack",
expectedKitchen: "/usr/bin/corepack",
expectedKitchen: "/usr/local/share/fnm/aliases/default/bin/corepack",
},
} {
testCase := testCase
Expand All @@ -328,7 +367,7 @@ func TestEnvironment(t *testing.T) {
// Install scripts for various tools can sometimes modify PATH, usually by adding entries
// to ~/.bashrc. This test ensures that we notice such modifications.
expectedPaths := map[string]string{
"pulumi": "/usr/local/share/pyenv/shims:/usr/local/share/pyenv/bin:/usr/share/dotnet:/pulumi/bin:/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"pulumi": "/usr/local/share/fnm/aliases/default/bin:/usr/local/share/pyenv/shims:/usr/local/share/pyenv/bin:/usr/share/dotnet:/pulumi/bin:/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"pulumi-debian-dotnet": "/root/.dotnet:/pulumi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"pulumi-debian-go": "/pulumi/bin:/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"pulumi-debian-java": "/pulumi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
Expand Down
1 change: 1 addition & 0 deletions tests/testdata/node-18/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
10 changes: 10 additions & 0 deletions tests/testdata/node-18/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: node-default
runtime:
name: nodejs
options:
packagemanager: npm
description: A minimal TypeScript Pulumi program
config:
pulumi:tags:
value:
pulumi:template: typescript
10 changes: 10 additions & 0 deletions tests/testdata/node-18/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as process from "node:process";
import * as semver from "semver";

const version = semver.parse(process.version, {
loose: true
});

if (version?.major != 18) {
throw new Error(`Expected node version 18.x.x, got ${process.version}`);
}
12 changes: 12 additions & 0 deletions tests/testdata/node-18/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "node-default",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/pulumi": "^3.113.0",
"semver": "^7.6.3"
}
}
18 changes: 18 additions & 0 deletions tests/testdata/node-18/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}
1 change: 1 addition & 0 deletions tests/testdata/node-20/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
10 changes: 10 additions & 0 deletions tests/testdata/node-20/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: node-default
runtime:
name: nodejs
options:
packagemanager: npm
description: A minimal TypeScript Pulumi program
config:
pulumi:tags:
value:
pulumi:template: typescript
10 changes: 10 additions & 0 deletions tests/testdata/node-20/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as process from "node:process";
import * as semver from "semver";

const version = semver.parse(process.version, {
loose: true
});

if (version?.major != 20) {
throw new Error(`Expected node version 20.x.x, got ${process.version}`);
}
12 changes: 12 additions & 0 deletions tests/testdata/node-20/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "node-default",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/pulumi": "^3.113.0",
"semver": "^7.6.3"
}
}
18 changes: 18 additions & 0 deletions tests/testdata/node-20/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}
1 change: 1 addition & 0 deletions tests/testdata/node-22.5.1/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.5.1
10 changes: 10 additions & 0 deletions tests/testdata/node-22.5.1/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: node-default
runtime:
name: nodejs
options:
packagemanager: npm
description: A minimal TypeScript Pulumi program
config:
pulumi:tags:
value:
pulumi:template: typescript
5 changes: 5 additions & 0 deletions tests/testdata/node-22.5.1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as process from "node:process";

if (process.version != "v22.5.1") {
throw new Error(`Expected node version 22.5.1 got ${process.version}`);
}
12 changes: 12 additions & 0 deletions tests/testdata/node-22.5.1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "node-default",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/pulumi": "^3.113.0",
"semver": "^7.6.3"
}
}
18 changes: 18 additions & 0 deletions tests/testdata/node-22.5.1/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}
1 change: 1 addition & 0 deletions tests/testdata/node-22/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
10 changes: 10 additions & 0 deletions tests/testdata/node-22/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: node-default
runtime:
name: nodejs
options:
packagemanager: npm
description: A minimal TypeScript Pulumi program
config:
pulumi:tags:
value:
pulumi:template: typescript
10 changes: 10 additions & 0 deletions tests/testdata/node-22/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as process from "node:process";
import * as semver from "semver";

const version = semver.parse(process.version, {
loose: true
});

if (version?.major != 22) {
throw new Error(`Expected node version 22.x.x, got ${process.version}`);
}
12 changes: 12 additions & 0 deletions tests/testdata/node-22/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "node-default",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/pulumi": "^3.113.0",
"semver": "^7.6.3"
}
}
18 changes: 18 additions & 0 deletions tests/testdata/node-22/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}
10 changes: 10 additions & 0 deletions tests/testdata/node-default/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: node-default
runtime:
name: nodejs
options:
packagemanager: npm
description: A minimal TypeScript Pulumi program
config:
pulumi:tags:
value:
pulumi:template: typescript
Loading