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

pipelines: add npm-install pipeline #763

Merged
merged 1 commit into from
Oct 30, 2023
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
33 changes: 33 additions & 0 deletions examples/npm-install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# SPDX-FileCopyrightText: 2023 Chainguard, Inc
# SPDX-License-Identifier: Apache-2.0
#
# This is a sample configuration file to demonstrate how to build a software
# project using melange's built-in npm/install pipeline.

package:
name: cowsay
version: 1.5.0
epoch: 0
description: "cowsay is a configurable talking cow, originally written in Perl by Tony Monroe"
checks:
disabled:
- usrlocal
dependencies:
runtime:
- nodejs

environment:
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
repositories:
- https://packages.wolfi.dev/os
pipeline:
- uses: npm/install
with:
package: ${{package.name}}
version: ${{package.version}}
overrides: |
yargs@^17.0.0 # If yargs had a CVE fixed in ^17.0.0
get-stdin@^9.0.0 # If get-stdin had a CVE fixed in ^9.0.0
74 changes: 74 additions & 0 deletions pkg/build/pipelines/npm/install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Install a portable npm package.

needs:
packages:
- nodejs
- busybox

inputs:
package:
description: |
The name of the package to npm install.
required: true

version:
description: |
The version of the package to npm install.
required: true

prefix:
description: |
The -prefix argument to pass to npm install; where /bin and /lib will be copied to.
default: "${{targets.destdir}}/usr/local/"

overrides:
description: |
Space, comma or newline-separated list of package@version to use in npm overrides, e.g. "yargs@^17.0.0 get-stdin@^9.0.0".

pipeline:
- runs: |
# Portable global install of the package.
# Simplest way to get both bin and lib directories installed.
# Does not support overrides; to be fixed below if needed.
npm install -g "${{inputs.package}}@${{inputs.version}}" -prefix "${{inputs.prefix}}"

if [ ! "${{inputs.overrides}}" == "" ]; then
# Move to /lib, which contains the node_modules folder.
cd "${{inputs.prefix}}/lib"

# Create a package.json with the dependency installed above, at which point
# `npm i --install-strategy=shallow .` will output the exact same content the install above did.
echo "{
\"dependencies\": {
\"${{inputs.package}}\": \"${{inputs.version}}\"
}
}" > package.json

# However, we also add `overrides`, to override specific vulnerable libraries.
node -e "
julienv3 marked this conversation as resolved.
Show resolved Hide resolved
const packageJson = require('./package.json');
const overrides = process.argv[1];
packageJson.overrides = overrides
// Remove comments
.replace(/\s*#.*/g, '')
// Space/Newline/Comma-separate value
.split(/,|\s/g)
// Split package & version
.map(override => override.split('@'))
// Set override values
.reduce((acc, [package, version]) => {
acc[package] = version;
return acc;
}, {});
fs.writeFileSync('./package.json', JSON.stringify(packageJson));
" "${{inputs.overrides}}"

# Delete vulnerable node_modules...
rm -rf node_modules

# ... to reinstall non-vulnerable node_modules.
npm i --install-strategy=shallow .

# Delete artifacts used for & generated from the override install.
rm -rf package.json package-lock.json node_modules/.package-lock.json
fi
Loading