├── .editorconfig
├── LICENSE
├── README.md
├── bin
├── compile
└── detect
├── buildpack.toml
└── lib
├── dependencies.sh
├── environment.sh
└── output.sh
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = tab
7 | indent_size = 4
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 | indent_style = space
15 | indent_size = 4
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Carloluis Rodríguez
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Heroku Buildpack for Node.js Build
2 |
3 | > Buildpack for Node.js apps with a build step defined on the package.json
4 |
5 | [](https://github.com/carloluis/heroku-bp-node-build/blob/master/LICENSE)
6 | [](https://github.com/carloluis/heroku-bp-node-build/releases)
7 |
8 | ## How it works?
9 |
10 | Inspect for a `package.json` file and a _build_ task defined within the _scripts_ section.
11 |
12 | ## Configure from `CLI`
13 |
14 | Use after nodejs buildpack:
15 |
16 | ```bash
17 | # create the app with nodejs buildpack
18 | heroku create my-app --buildpack heroku/nodejs
19 |
20 | # add heroku-bp-node-build
21 | heroku buildpacks:add --index 2 https://github.com/carloluis/heroku-bp-node-build
22 | ```
23 |
24 | ## Configure from _app.json_ manifest:
25 |
26 | ```json
27 | {
28 | "buildpacks": [
29 | {
30 | "url": "heroku/nodejs"
31 | },
32 | {
33 | "url": "https://github.com/carloluis/heroku-bp-node-build"
34 | }
35 | ]
36 | }
37 | ```
38 |
39 | ## Locking to a buildpack version
40 |
41 | Lock your buildpack to one specific version:
42 | * First, find the version you want from [buildpack versions](https://github.com/carloluis/heroku-bp-node-build/releases).
43 | * Then, specify that version with `buildpacks:set`
44 |
45 | ```bash
46 | heroku buildpacks:set https://github.com/carloluis/heroku-bp-node-build#v0.1.0 -a my-app
47 | ```
48 |
49 | ## More
50 |
51 | Read related info with buildpacks [here](https://devcenter.heroku.com/articles/buildpacks).
52 |
53 |
54 | Buildpack Registry
55 |
56 | This buildpack is available as `carloluis/node-build` on the [Heroku Buildpack Registry](https://devcenter.heroku.com/articles/buildpack-registry).
57 |
58 |
59 |
60 | ## License
61 |
62 | MIT © [Carloluis](https://github.com/carloluis)
63 |
--------------------------------------------------------------------------------
/bin/compile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # bin/compile
3 |
4 | ### Configure environment
5 | set -o errexit
6 | set -o pipefail
7 |
8 | ### Configure directories
9 |
10 | readonly BUILD_DIR="${1:-}"
11 | readonly CACHE_DIR="${2:-}"
12 | readonly ENV_DIR="${3:-}"
13 |
14 | readonly BP_DIR=$(cd "$(dirname "${0:-}")"; cd ..; pwd)
15 |
16 | ### Load dependencies
17 |
18 | # shellcheck source=$BP_DIR/lib/output.sh
19 | source "$BP_DIR"/lib/output.sh
20 | # shellcheck source=$BP_DIR/lib/environment.sh
21 | source "$BP_DIR"/lib/environment.sh
22 | # shellcheck source=$BP_DIR/lib/dependencies.sh
23 | source "$BP_DIR"/lib/dependencies.sh
24 |
25 | ### Runtime environment
26 |
27 | header "runtime environment"
28 |
29 | # can't pipe this because piping causes subshells, preventing exports
30 | export_env_dir "$ENV_DIR"
31 |
32 | ### Check initial state
33 |
34 | [[ -d "$BUILD_DIR/node_modules" ]] && PREBUILD=true || PREBUILD=false
35 | [[ -f "$BUILD_DIR/yarn.lock" ]] && YARN=true || YARN=false
36 |
37 | ### Set up development
38 |
39 | header "set up development"
40 |
41 | _NPM_CONFIG_PRODUCTION_="${NPM_CONFIG_PRODUCTION:-true}"
42 | _NODE_ENV_="${NODE_ENV:-production}"
43 |
44 | info "------ previous config.: ------"
45 | info "NPM_CONFIG_PRODUCTION=${_NPM_CONFIG_PRODUCTION_}"
46 | info "NODE_ENV=${_NODE_ENV_}"
47 |
48 | export NPM_CONFIG_PRODUCTION=false
49 | export NODE_ENV='development'
50 |
51 | ### Restore /node_modules/
52 |
53 | function restore_dependencies() {
54 | header "restore dependencies..."
55 |
56 | # save root project dependencies
57 | $PREBUILD && mv "$BUILD_DIR/node_modules" "$BUILD_DIR/.node_modules"
58 |
59 | # check subdirectories (first level) -> save dependencies copy for subprojects
60 | save_subprojects_dependencies "$BUILD_DIR"
61 |
62 | # install dependencies...
63 | if $YARN; then
64 | yarn_node_modules "$BUILD_DIR" | indent
65 | else
66 | npm_node_modules "$BUILD_DIR" | indent
67 | fi
68 |
69 | # check for dependencies in subprojects...
70 | check_subproject_dependencies "$BUILD_DIR"
71 | }
72 |
73 | restore_dependencies
74 |
75 | ### Build-step
76 |
77 | function build_step() {
78 | header "build step..."
79 |
80 | cd "$BUILD_DIR"
81 |
82 | info "set NODE_ENV=production"
83 | export NODE_ENV=production
84 |
85 | # execute build step
86 | info "npm run build"
87 | npm run build
88 |
89 | rm -r "$BUILD_DIR/node_modules" 2>/dev/null || true
90 | [[ -d "$BUILD_DIR/.node_modules" ]] && mv "$BUILD_DIR/.node_modules" "$BUILD_DIR/node_modules"
91 |
92 | # restore subprojects dependencies to initial state
93 | restore_subprojects "$BUILD_DIR"
94 | }
95 |
96 | build_step
97 |
98 | ### Restore environmet
99 |
100 | info "restore environment"
101 |
102 | export NPM_CONFIG_PRODUCTION="$_NPM_CONFIG_PRODUCTION_"
103 | export NODE_ENV="$_NODE_ENV_"
104 |
105 | header "build succeeded!"
106 |
--------------------------------------------------------------------------------
/bin/detect:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # bin/detect
3 |
4 | if [[ $(cat "$1/package.json" | grep '"build"') ]]; then
5 | echo "heroku-bp-node-build"
6 | exit 0
7 | else
8 | exit 1
9 | fi
10 |
--------------------------------------------------------------------------------
/buildpack.toml:
--------------------------------------------------------------------------------
1 | [buildpack]
2 | name = "node-build"
3 |
4 | [publish.Ignore]
5 | files = [
6 | ".editorconfig",
7 | ".gitignore"
8 | ]
9 |
--------------------------------------------------------------------------------
/lib/dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function yarn_node_modules() {
4 | local build_dir="${1:-}"
5 | echo "yarn install"
6 | cd "$build_dir"
7 | yarn install --pure-lockfile --ignore-engines 2>&1
8 | }
9 |
10 | function npm_node_modules() {
11 | local build_dir="${1:-}"
12 | if [ -e "$build_dir"/package.json ]; then
13 | echo "npm install"
14 | cd "$build_dir"
15 | npm install --unsafe-perm --userconfig "$build_dir"/.npmrc 2>&1
16 | else
17 | echo "Skipping (no package.json)"
18 | fi
19 | }
20 |
21 | function save_subprojects_dependencies() {
22 | local build_dir="${1:-}"
23 |
24 | for file in "$build_dir/"*; do
25 | if [[ -d "$file" && -f "$file/package.json" ]]; then
26 | if [[ -d "$file/node_modules" ]]; then
27 | mv "$file/node_modules" "$file/.node_modules"
28 | fi
29 | fi
30 | done
31 | }
32 |
33 | function check_subproject_dependencies() {
34 | local build_dir="${1:-}"
35 |
36 | for file in "$build_dir/"*; do
37 | if [[ -d "$file" && -d "$file/.node_modules" ]]; then
38 | if [[ ! -d "$file/node_modules" ]]; then
39 | mv "$file/.node_modules" "$file/node_modules"
40 | fi
41 | fi
42 | done
43 | }
44 |
45 | function restore_subprojects() {
46 | local build_dir="${1:-}"
47 |
48 | for file in "$build_dir/"*; do
49 | if [[ -d "$file" && -d "$file/.node_modules" ]]; then
50 | rm -r "$file/node_modules" 2>/dev/null || true
51 | mv "$file/.node_modules" "$file/node_modules"
52 | fi
53 | done
54 | }
55 |
--------------------------------------------------------------------------------
/lib/environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function export_env_dir() {
4 | local env_dir="$1"
5 | local blacklist_regex="${2:-'^(PATH|GIT_DIR|CPATH|CPPATH|LD_PRELOAD|LIBRARY_PATH|LANG)$'}"
6 |
7 | if [[ -d "$env_dir" ]]; then
8 | for e in $(ls "$env_dir"); do
9 | echo " $e=$(cat $env_dir/$e)"
10 | echo "$e" | grep -qvE "$blacklist_regex" && export "$e=$(cat $env_dir/$e)"
11 | :
12 | done
13 | fi
14 | }
15 |
--------------------------------------------------------------------------------
/lib/output.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function info() {
4 | echo " $*" || true
5 | }
6 |
7 | function header() {
8 | echo "" || true
9 | echo "-----> $*" || true
10 | }
11 |
12 | function indent() {
13 | sed -u 's/^/ /'
14 | }
15 |
16 | function print() {
17 | echo "$*" | indent
18 | }
19 |
--------------------------------------------------------------------------------