nodejs 18 initial commit (#220)

Co-authored-by: Luke Roy <lukeroy@Lukes-MacBook-Pro.local>
diff --git a/.travis.yml b/.travis.yml
index 5c1b514..ffaa53c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -42,7 +42,7 @@
       all_branches: true
       repo: apache/openwhisk-runtime-nodejs
   - provider: script
-    script: "./tools/travis/publish.sh openwhisk nodejs14Action nightly && ./tools/travis/publish.sh openwhisk nodejs16Action nightly && ./tools/travis/publish.sh openwhisk typescript37Action nightly"
+    script: "./tools/travis/publish.sh openwhisk nodejs14Action nightly && ./tools/travis/publish.sh openwhisk nodejs16Action nightly && ./tools/travis/publish.sh openwhisk nodejs18Action nightly && ./tools/travis/publish.sh openwhisk typescript37Action nightly"
     on:
       branch: master
       repo: apache/openwhisk-runtime-nodejs
diff --git a/README.md b/README.md
index 5b3130a..065c832 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@
 
 - Node.js 14.19 (`nodejs:14` & `openwhisk/action-nodejs-v14`)
 - Node.js 16.15 (`nodejs:16` & `openwhisk/action-nodejs-v16`)
+- Node.js 18 (`nodejs:18` & `openwhisk/action-nodejs-v16`)
 
 This README documents the build, customisation and testing of these runtime images.
 
diff --git a/core/nodejs18Action/.dockerignore b/core/nodejs18Action/.dockerignore
new file mode 100644
index 0000000..a1d03cb
--- /dev/null
+++ b/core/nodejs18Action/.dockerignore
@@ -0,0 +1,13 @@
+*.*~
+*.yaml
+*.tmpl
+*.gradle
+.dockerignore
+.project
+.settings
+build.xml
+Dockerfile
+logs
+node_modules
+package-lock.json
+test.js
diff --git a/core/nodejs18Action/CHANGELOG.md b/core/nodejs18Action/CHANGELOG.md
new file mode 100644
index 0000000..78a7c15
--- /dev/null
+++ b/core/nodejs18Action/CHANGELOG.md
@@ -0,0 +1,26 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+# NodeJS 18 OpenWhisk Runtime Container
+
+# Next Release
+  - Initial release with support for Node.js v1.18
+
+Node.js version = [18.4.0](https://nodejs.org/en/blog/release/v18.4.0/)
+OpenWhisk version = [OpenWhisk v3.21.6](https://www.npmjs.com/package/openwhisk)
diff --git a/core/nodejs18Action/Dockerfile b/core/nodejs18Action/Dockerfile
new file mode 100644
index 0000000..f0e8c7e
--- /dev/null
+++ b/core/nodejs18Action/Dockerfile
@@ -0,0 +1,44 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+FROM node:18-bullseye
+
+# Initial update and some basics.
+#
+RUN apt-get update && apt-get install -y \
+    imagemagick \
+    graphicsmagick \
+    zip \
+    unzip \
+    && rm -rf /var/lib/apt/lists/*
+
+# Add sources and copy the package.json to root container,
+# so npm packages from user functions take precedence.
+#
+WORKDIR /nodejsAction
+ADD  . /nodejsAction/
+COPY package.json /
+
+# Customize runtime with additional packages.
+# Install package globally so user packages can override.
+#
+RUN cd / && npm install --no-package-lock --production \
+    && npm cache clean --force
+
+EXPOSE 8080
+
+CMD node --expose-gc app.js
diff --git a/core/nodejs18Action/build.gradle b/core/nodejs18Action/build.gradle
new file mode 100644
index 0000000..53c8e30
--- /dev/null
+++ b/core/nodejs18Action/build.gradle
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+apply plugin: 'eclipse'
+eclipse {
+    project {
+        natures 'org.eclipse.wst.jsdt.core.jsNature'
+        buildCommand 'org.eclipse.wst.jsdt.core.javascriptValidator'
+    }
+}
+
+ext.dockerImageName = 'action-nodejs-v18'
+apply from: '../../gradle/docker.gradle'
+
+distDocker.dependsOn 'copyPackageJson'
+distDocker.dependsOn 'copyProxy'
+distDocker.dependsOn 'copyRunner'
+distDocker.dependsOn 'copyService'
+distDocker.dependsOn 'copyPlatform'
+distDocker.dependsOn 'copyOpenWhisk'
+distDocker.dependsOn 'copyKnative'
+distDocker.dependsOn 'copyBuildTemplate'
+distDocker.finalizedBy('cleanup')
+
+task copyPackageJson(type: Copy) {
+    from '../nodejsActionBase/package.json'
+    into '.'
+}
+
+task copyProxy(type: Copy) {
+    from '../nodejsActionBase/app.js'
+    into '.'
+}
+
+task copyRunner(type: Copy) {
+    from '../nodejsActionBase/runner.js'
+    into '.'
+}
+
+task copyService(type: Copy) {
+    from '../nodejsActionBase/src/service.js'
+    into './src'
+}
+
+task copyPlatform(type: Copy) {
+    from '../nodejsActionBase/platform/platform.js'
+    into './platform'
+}
+
+task copyOpenWhisk(type: Copy) {
+    from '../nodejsActionBase/platform/openwhisk.js'
+    into './platform'
+}
+
+task copyKnative(type: Copy) {
+    from '../nodejsActionBase/platform/knative.js'
+    into './platform'
+}
+
+task copyBuildTemplate(type: Copy) {
+    from '../nodejsActionBase/buildtemplate.yaml'
+    into '.'
+}
+
+task cleanup(type: Delete) {
+    delete 'package.json'
+    delete 'app.js'
+    delete 'runner.js'
+    delete 'src'
+    delete 'platform'
+    delete 'buildtemplate.yaml'
+}
diff --git a/settings.gradle b/settings.gradle
index ac326ce..a55756b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -20,9 +20,11 @@
 include 'core:nodejsActionBase'
 include 'core:nodejs14Action'
 include 'core:nodejs16Action'
+include 'core:nodejs18Action'
 include 'core:typescript37Action'
 include 'tests:dat:docker:nodejs14docker'
 include 'tests:dat:docker:nodejs16docker'
+include 'tests:dat:docker:nodejs18docker'
 include 'tests:dat:docker:typescript37docker'
 
 rootProject.name = 'runtime-nodejs'
diff --git a/tests/dat/docker/nodejs18docker/Dockerfile b/tests/dat/docker/nodejs18docker/Dockerfile
new file mode 100644
index 0000000..68f8c73
--- /dev/null
+++ b/tests/dat/docker/nodejs18docker/Dockerfile
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+FROM action-nodejs-v18
+COPY package.json .
+RUN npm install --production
diff --git a/tests/dat/docker/nodejs18docker/build.gradle b/tests/dat/docker/nodejs18docker/build.gradle
new file mode 100644
index 0000000..2a7f8e8
--- /dev/null
+++ b/tests/dat/docker/nodejs18docker/build.gradle
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ext.dockerImageName = 'nodejs18docker'
+apply from: '../../../../gradle/docker.gradle'
diff --git a/tests/dat/docker/nodejs18docker/package.json b/tests/dat/docker/nodejs18docker/package.json
new file mode 100644
index 0000000..6822c09
--- /dev/null
+++ b/tests/dat/docker/nodejs18docker/package.json
@@ -0,0 +1,8 @@
+{
+  "name": "testdocker",
+  "version": "1.0.0",
+  "main": "index.js",
+  "dependencies": {
+    "openwhisk": "2.0.0"
+  }
+}
diff --git a/tests/src/test/scala/runtime/actionContainers/NodeJs18ActionContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/NodeJs18ActionContainerTests.scala
new file mode 100644
index 0000000..8271b60
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/NodeJs18ActionContainerTests.scala
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package runtime.actionContainers
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class NodeJs18ActionContainerTests extends NodeJsActionContainerTests {
+  override lazy val nodejsContainerImageName = "action-nodejs-v18"
+  override lazy val nodejsTestDockerImageName = "nodejs18docker"
+}
diff --git a/tests/src/test/scala/runtime/actionContainers/NodeJs18ConcurrentTests.scala b/tests/src/test/scala/runtime/actionContainers/NodeJs18ConcurrentTests.scala
new file mode 100644
index 0000000..d2b3a4c
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/NodeJs18ConcurrentTests.scala
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package runtime.actionContainers
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class NodeJs18ConcurrentTests extends NodeJsConcurrentTests {
+  override lazy val nodejsContainerImageName = "action-nodejs-v18"
+  override lazy val nodejsTestDockerImageName = "nodejs18docker"
+}