Skip to content

Commit

Permalink
Sets node-start to optional
Browse files Browse the repository at this point in the history
Modifies buildpack.toml to have node-start optional in npm and yarn
build groups.

Adds integration test to cover various cases for npm and yarn.
  • Loading branch information
dalbar authored and ryanmoran committed Apr 8, 2022
1 parent 0946478 commit 30794e8
Show file tree
Hide file tree
Showing 21 changed files with 429 additions and 4 deletions.
2 changes: 2 additions & 0 deletions buildpack.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ api = "0.6"
[[order.group]]
id = "paketo-buildpacks/node-start"
version = "0.8.0"
optional = true

[[order.group]]
id = "paketo-buildpacks/yarn-start"
Expand Down Expand Up @@ -103,6 +104,7 @@ api = "0.6"
[[order.group]]
id = "paketo-buildpacks/node-start"
version = "0.8.0"
optional = true

[[order.group]]
id = "paketo-buildpacks/npm-start"
Expand Down
136 changes: 134 additions & 2 deletions integration/npm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,139 @@ func testNPM(t *testing.T, context spec.G, it spec.S) {
docker = occam.NewDocker()
})

context("when building a node app that uses npm", func() {
context("when building a node app that uses npm and has no start script", func() {
var (
image occam.Image
container occam.Container

name string
source string
)

it.Before(func() {
var err error
name, err = occam.RandomName()
Expect(err).NotTo(HaveOccurred())
source, err = occam.Source(filepath.Join("testdata", "npm_no_start_script"))
Expect(err).NotTo(HaveOccurred())
})

it.After(func() {
Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed())
Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed())
Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed())
Expect(os.RemoveAll(source)).To(Succeed())
})

it("builds a working OCI image for a simple app using node-start exclusively", func() {
var err error
var logs fmt.Stringer
image, logs, _ = pack.WithNoColor().Build.
WithBuildpacks(nodeBuildpack).
WithPullPolicy("never").
Execute(name, source)
Expect(err).NotTo(HaveOccurred())

Expect(logs).To(ContainLines(ContainSubstring("Node Engine Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("NPM Install Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("Node Module Bill of Materials Generator Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("Node Start Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("NPM Start Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Procfile Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Environment Variables Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Image Labels Buildpack")))

Expect(image.Buildpacks[3].Key).To(Equal("paketo-buildpacks/node-module-bom"))

container, err = docker.Container.Run.
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())

Eventually(container, "5s").Should(BeAvailable())

response, err := http.Get(fmt.Sprintf("http://localhost:%s/env", container.HostPort("8080")))
Expect(err).NotTo(HaveOccurred())
Expect(response.StatusCode).To(Equal(http.StatusOK))

var env struct {
NpmConfigLoglevel string `json:"NPM_CONFIG_LOGLEVEL"`
}
Expect(json.NewDecoder(response.Body).Decode(&env)).To(Succeed())
Expect(env.NpmConfigLoglevel).To(Equal("error"))

})
})

context("when building a node app that uses npm, has a start script and a src folder", func() {
var (
image occam.Image
container occam.Container

name string
source string
)

it.Before(func() {
var err error
name, err = occam.RandomName()
Expect(err).NotTo(HaveOccurred())
source, err = occam.Source(filepath.Join("testdata", "npm_with_src_dir"))
Expect(err).NotTo(HaveOccurred())
})

it.After(func() {
Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed())
Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed())
Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed())
Expect(os.RemoveAll(source)).To(Succeed())
})

it("builds a working OCI image for a simple app using npm-start exclusively", func() {
var err error
var logs fmt.Stringer
image, logs, _ = pack.WithNoColor().Build.
WithBuildpacks(nodeBuildpack).
WithPullPolicy("never").
Execute(name, source)
Expect(err).NotTo(HaveOccurred())

Expect(logs).To(ContainLines(ContainSubstring("Node Engine Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("NPM Install Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("Node Module Bill of Materials Generator Buildpack")))
Expect(logs).To(ContainLines(ContainSubstring("NPM Start Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Node Start Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Procfile Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Environment Variables Buildpack")))
Expect(logs).NotTo(ContainLines(ContainSubstring("Image Labels Buildpack")))

Expect(image.Buildpacks[3].Key).To(Equal("paketo-buildpacks/node-module-bom"))

container, err = docker.Container.Run.
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())

Eventually(container, "5s").Should(BeAvailable())

response, err := http.Get(fmt.Sprintf("http://localhost:%s/env", container.HostPort("8080")))
Expect(err).NotTo(HaveOccurred())
Expect(response.StatusCode).To(Equal(http.StatusOK))

var env struct {
NpmConfigLoglevel string `json:"NPM_CONFIG_LOGLEVEL"`
}
Expect(json.NewDecoder(response.Body).Decode(&env)).To(Succeed())
Expect(env.NpmConfigLoglevel).To(Equal("error"))

})
})

context("when building a node app that uses npm, has a start script and flat working directory", func() {
var (
image occam.Image
container occam.Container
Expand All @@ -56,7 +188,7 @@ func testNPM(t *testing.T, context spec.G, it spec.S) {
Expect(os.RemoveAll(source)).To(Succeed())
})

it("builds a working OCI image for a simple app", func() {
it("builds a working OCI image for a simple app using node-start and npm-start", func() {
var err error
var logs fmt.Stringer
image, logs, err = pack.WithNoColor().Build.
Expand Down
1 change: 1 addition & 0 deletions integration/testdata/npm_no_start_script/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
1 change: 1 addition & 0 deletions integration/testdata/npm_no_start_script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file here to suppress "npm WARN package.json [email protected] No README data"
21 changes: 21 additions & 0 deletions integration/testdata/npm_no_start_script/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "simple_app_no_start_script",
"version": "0.0.0",
"description": "some app",
"scripts": {
"some-script": "echo \"npm scripts running!\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "",
"dependencies": {
"leftpad": "~0.0.1"
},
"repository": {
"type": "git",
"url": ""
},
"engines": {
"node": "~14"
}
}
16 changes: 16 additions & 0 deletions integration/testdata/npm_no_start_script/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const http = require('http');
const leftpad = require('leftpad');

const port = process.env.PORT || 8080;

const server = http.createServer((request, response) => {
response.end(JSON.stringify(process.env))
});

server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err);
}

console.log(`NOT vendored server is listening on ${port}`);
});
1 change: 1 addition & 0 deletions integration/testdata/npm_with_src_dir/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
1 change: 1 addition & 0 deletions integration/testdata/npm_with_src_dir/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file here to suppress "npm WARN package.json [email protected] No README data"
22 changes: 22 additions & 0 deletions integration/testdata/npm_with_src_dir/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "simple_app_with_src_dir",
"version": "0.0.0",
"description": "some app",
"scripts": {
"start": "node src/server.js",
"some-script": "echo \"npm scripts running!\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "",
"dependencies": {
"leftpad": "~0.0.1"
},
"repository": {
"type": "git",
"url": ""
},
"engines": {
"node": "~14"
}
}
16 changes: 16 additions & 0 deletions integration/testdata/npm_with_src_dir/src/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const http = require('http');
const leftpad = require('leftpad');

const port = process.env.PORT || 8080;

const server = http.createServer((request, response) => {
response.end(JSON.stringify(process.env))
});

server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err);
}

console.log(`NOT vendored server is listening on ${port}`);
});
1 change: 1 addition & 0 deletions integration/testdata/yarn_no_start_script/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
1 change: 1 addition & 0 deletions integration/testdata/yarn_no_start_script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file here to suppress "npm WARN package.json [email protected] No README data"
18 changes: 18 additions & 0 deletions integration/testdata/yarn_no_start_script/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "simple",
"version": "0.0.0",
"description": "some app",
"scripts": {
"some-script": "echo \"yarn scripts running!\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"leftpad": "~0.0.1"
},
"repository": {
"type": "git",
"url": ""
}
}
17 changes: 17 additions & 0 deletions integration/testdata/yarn_no_start_script/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const http = require('http')
const leftpad = require('leftpad')
const port = process.env.PORT || 8080

const requestHandler = (request, response) => {
response.end("Hello, World!")
}

const server = http.createServer(requestHandler)

server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}

console.log(`server is listening on ${port}`)
})
8 changes: 8 additions & 0 deletions integration/testdata/yarn_no_start_script/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


leftpad@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/leftpad/-/leftpad-0.0.1.tgz#86b1a4de4face180ac545a83f1503523d8fed115"
integrity sha1-hrGk3k+s4YCsVFqD8VA1I9j+0RU=
1 change: 1 addition & 0 deletions integration/testdata/yarn_with_src_dir/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
1 change: 1 addition & 0 deletions integration/testdata/yarn_with_src_dir/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file here to suppress "npm WARN package.json [email protected] No README data"
19 changes: 19 additions & 0 deletions integration/testdata/yarn_with_src_dir/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "simple_app",
"version": "0.0.0",
"description": "some app",
"scripts": {
"start": "node src/server.js",
"some-script": "echo \"yarn scripts running!\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"leftpad": "~0.0.1"
},
"repository": {
"type": "git",
"url": ""
}
}
17 changes: 17 additions & 0 deletions integration/testdata/yarn_with_src_dir/src/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const http = require('http')
const leftpad = require('leftpad')
const port = process.env.PORT || 8080

const requestHandler = (request, response) => {
response.end("Hello, World!")
}

const server = http.createServer(requestHandler)

server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}

console.log(`server is listening on ${port}`)
})
8 changes: 8 additions & 0 deletions integration/testdata/yarn_with_src_dir/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


leftpad@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/leftpad/-/leftpad-0.0.1.tgz#86b1a4de4face180ac545a83f1503523d8fed115"
integrity sha1-hrGk3k+s4YCsVFqD8VA1I9j+0RU=
Loading

0 comments on commit 30794e8

Please sign in to comment.