Skip to content
This repository was archived by the owner on Jan 20, 2026. It is now read-only.

Commit 3404fdb

Browse files
authored
Breaking: [AEA-4433] - Parameterise NPM version (#17)
* Bump npm to version 20 * Use set e * NON-WORKING - saving progress (such as it is) * Handle multiple versions of node in the dockerfile and tests * Rename test data * Add tool versions back in * Revert dependabot changes so tests pass * Fix input * Fix docker asdf install * Actually fix path * REALLY actually fix the path issue * REALL ACTUALLY fix the path issue * this time, REALLY ACTUALLY fix the path issue * stupid github * Debugging * More debugging * More debugging * Try resetting asdf dir in action * poor mans debugging * copy asdf to where github expects it to be * copy asdf to where github expects it to be * Add docstring, and make checks proper * linting fix * Add node22 support * Fix path * Why did you break? * Why did you break? * Why did you break? * Why did you break? * fix typo * Rename python requirements files * Rename test files * Add some blank lines * Add empty lines
1 parent fe5838f commit 3404fdb

29 files changed

Lines changed: 19288 additions & 676 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ WORKDIR /workspaces/eps-action-sbom
3636
ADD .tool-versions /workspaces/eps-action-sbom/.tool-versions
3737
ADD .tool-versions /home/vscode/.tool-versions
3838

39-
RUN asdf install
39+
RUN asdf install

.devcontainer/devcontainer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@
4646
"github.vscode-github-actions"
4747
],
4848
"settings": {
49-
"cSpell.words": ["fhir", "Formik", "pino", "serialisation"],
49+
"cSpell.words": ["fhir", "Formik", "pino", "serialisation"]
5050
}
5151
}
5252
}
5353
}
54-

.github/dependabot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ updates:
3333
interval: "daily"
3434
versioning-strategy: increase
3535
commit-message:
36-
prefix: "Upgrade: [dependabot] - "
36+
prefix: "Upgrade: [dependabot] - "

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
node_modules
2-
*sbom*.json
2+
*sbom*.json

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ shellcheck 0.9.0
22
actionlint 1.6.26
33
nodejs 20.16.0
44
python 3.8.15
5-
poetry 1.6.1
5+
poetry 1.6.1

Dockerfile

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,72 @@
1-
# Use an official Python runtime as a parent image
2-
FROM python:3.10-slim
3-
4-
# Set environment variables for versions with default values
5-
ARG POETRY_VERSION=1.8.0
6-
ARG NODE_VERSION=18
7-
ARG CYCLONE_PYTHON_VERSION=4.5.0
8-
ARG CYCLONE_NPM_VERSION=1.19.3
9-
10-
# Install system dependencies and tools
11-
RUN apt-get update && \
12-
apt-get install -y \
13-
curl \
14-
gnupg \
15-
jq \
16-
&& rm -rf /var/lib/apt/lists/*
17-
18-
# Install Node.js
19-
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \
20-
apt-get install -y nodejs
21-
22-
# Install cyclonedx
23-
RUN pip install cyclonedx-bom==${CYCLONE_PYTHON_VERSION}
24-
RUN npm install -g @cyclonedx/cyclonedx-npm@${CYCLONEDX_VERSION}
1+
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
2+
3+
RUN apt-get update \
4+
&& export DEBIAN_FRONTEND=noninteractive \
5+
&& apt-get -y dist-upgrade \
6+
&& apt-get -y install --no-install-recommends htop vim curl git build-essential \
7+
libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev libbz2-dev \
8+
zlib1g-dev unixodbc unixodbc-dev libsecret-1-0 libsecret-1-dev libsqlite3-dev \
9+
jq apt-transport-https ca-certificates gnupg-agent \
10+
software-properties-common bash-completion python3-pip make libbz2-dev \
11+
libreadline-dev libsqlite3-dev wget llvm libncurses5-dev libncursesw5-dev \
12+
xz-utils tk-dev liblzma-dev libyaml-dev bats bats-support bats-assert bats-file \
13+
python3 python3-pip python3-dev
14+
15+
# Install ASDF
16+
RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1; \
17+
echo '. /root/.asdf/asdf.sh' >> ~/.bashrc; \
18+
echo '. /root/.asdf/completions/asdf.bash' >> ~/.bashrc; \
19+
echo 'PATH="$PATH:/root/.asdf/bin/"' >> ~/.bashrc;
20+
21+
ENV PATH="$PATH:/root/.asdf/bin/"
22+
23+
# Install ASDF plugins
24+
RUN asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git; \
25+
asdf plugin add actionlint; \
26+
asdf plugin add python; \
27+
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git; \
28+
asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git;
2529

2630
# Install Grype
2731
RUN curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
2832

29-
WORKDIR /github/workspace
33+
# For each supported npm version, asdf install, and install cyclonedx (latest versions)
34+
35+
ADD node18/.tool-versions /node_versions/node18/.tool-versions
36+
WORKDIR /node_versions/node18
37+
RUN asdf install
38+
RUN asdf exec npm install -g @cyclonedx/cyclonedx-npm
39+
RUN asdf exec python -m pip install cyclonedx-bom
40+
41+
42+
ADD node20/.tool-versions /node_versions/node20/.tool-versions
43+
WORKDIR /node_versions/node20
44+
RUN asdf install
45+
RUN asdf exec npm install -g @cyclonedx/cyclonedx-npm
46+
RUN asdf exec python -m pip install --no-cache-dir cyclonedx-bom
47+
48+
49+
ADD node22/.tool-versions /node_versions/node22/.tool-versions
50+
WORKDIR /node_versions/node22
51+
RUN asdf install
52+
RUN asdf exec npm install -g @cyclonedx/cyclonedx-npm
53+
RUN asdf exec python -m pip install --no-cache-dir cyclonedx-bom
54+
55+
56+
# Set the workdir to what we'll actually use
57+
WORKDIR /working
58+
59+
# And install cyclonedx in this asdf environment
60+
RUN echo "python 3.12.5" >> .tool-versions
61+
RUN asdf exec python -m pip install --no-cache-dir cyclonedx-bom
62+
RUN rm .tool-versions
63+
64+
# Files to execute when the docker container starts up
65+
ADD entrypoint.sh /entrypoint.sh
66+
ADD check-sbom-issues-against-ignores.sh /check-sbom-issues-against-ignores.sh
3067

31-
COPY entrypoint.sh /entrypoint.sh
32-
COPY check-sbom-issues-against-ignores.sh /check-sbom-issues-against-ignores.sh
68+
# Set the umask so that the files created by docker can be universally accessed.
69+
# Lets the tests successfully teardown.
70+
RUN echo "umask 000" >> /etc/profile
3371

34-
# Code file to execute when the docker container starts up
3572
ENTRYPOINT ["/entrypoint.sh"]

Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
test:
44
bats test/test.bats
55

6-
submodule_update:
7-
git submodule update
8-
96
lint:
107
shellcheck *.sh

README.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
# EPS SBOM scanning action
22

3-
This action generates a Software Bill Of Materials (SBOM) for Python and NPM in a project. It also scans these for security vulnerabilities, and reports an error if any are found.
3+
This action generates a Software Bill Of Materials (SBOM) for Python and NPM in a project. It also scans these for security vulnerabilities, and reports an error if any are found. For python, both `requirements.txt` and Poetry installations are supported.
44

5-
Specific vulnerabilities can be ignored by adding their ID to the ignore file in this repository: `ignored_security_issues.json`.
5+
Specific vulnerabilities can be ignored by adding their ID to the ignore file in this repository: `ignored_security_issues.json`, e.g.
6+
```
7+
[
8+
"GHSA-4jcv-vp96-94xr"
9+
]
10+
```
611

712
## Inputs
813

9-
None
14+
### "node_version"
15+
16+
Used to specify the version of nodeJS used in your project. Versions are mutually incompatible, so a project built with node 18 cannot be analysed using node 20, for example. Allowed versions are `["18", "20", "22"]`. Defaults to "20".
1017

1118
## Outputs
1219

@@ -15,8 +22,10 @@ None
1522
## Example usage
1623

1724
```
18-
- name: Create and scan SBOM
19-
uses: NHSDigital/eps-action-sbom@v1
25+
- name: Create and scan SBOM
26+
uses: NHSDigital/eps-action-sbom@v1
27+
with:
28+
node_version: "20"
2029
```
2130

2231
This can be used as a `makefile` target like so:
@@ -31,3 +40,13 @@ Note that this requires the `LOCAL_WORKSPACE_FOLDER` environment variable to be
3140
```
3241
"remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" },
3342
```
43+
In addition, if you are using a dev container, it must have the docker-in-docker feature installed. This is added to the `devcontainer.json` features field:
44+
```
45+
"features": {
46+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
47+
"version": "latest",
48+
"moby": "true",
49+
"installDockerBuildx": "true"
50+
}
51+
},
52+
```

action.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# action.yml
22
name: 'EPS SBOM'
33
description: 'Create SBOMs, and scan for security risks.'
4+
inputs:
5+
node_version:
6+
description: 'The version of NPM used in the project'
7+
required: false
8+
default: '20'
9+
410
runs:
511
using: 'docker'
612
image: 'Dockerfile'
13+
args:
14+
- ${{ inputs.node_version }}
15+
env:
16+
ASDF_DIR: ""
17+
ASDF_DATA_DIR: ""

entrypoint.sh

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
#!/bin/sh -l
22

3+
set -e
4+
5+
36
# Remove any existing SBOMs
47
rm -f ./sbom*.json
58

9+
# Get the .tool-versions for the correct node
10+
NODE_VERSION=${1:-'20'}
11+
cp /node_versions/node"${NODE_VERSION}"/.tool-versions .
12+
13+
# If the current github workflow has installed asdf, it will pass the ASDF_DIR and ASDF_DATA_DIR
14+
# environment variables in to the action, overriding this docker container's installation and leaving it
15+
# unable to find the scripts.
16+
# Here, we check if these variables are set, and if necessary we copy in our local installation of asdf.
17+
if [ -n "${ASDF_DIR}" ]; then
18+
echo "ASDF_DIR not set. Copying in local installation of asdf..."
19+
mkdir -p "${ASDF_DIR}"
20+
cp -r /root/.asdf/* "${ASDF_DIR}"/
21+
ls -lha "${ASDF_DIR}"
22+
fi
23+
asdf reshim
24+
625
# Scan the dependencies for NPM
726
if [ -f "package.json" ] && [ -f "package-lock.json" ]; then
827
echo "Generating SBOM for Node.js..."
9-
# The node_modules directory is not needed for generating the SBOM
10-
npm install
11-
cyclonedx-npm --output-format json --output-file sbom-node.json
28+
# The node_modules directory is needed for generating the SBOM
29+
asdf exec npm install
30+
asdf exec cyclonedx-npm --output-format json --output-file sbom-node.json
1231
echo "Done"
1332
else
1433
echo "package.json and package-lock.json not found. Cannot generate Node.js SBOM."
@@ -18,12 +37,12 @@ fi
1837
# Check if pyproject.toml (Poetry) or requirements.txt exists
1938
if [ -f "pyproject.toml" ]; then
2039
echo "Detected Poetry project. Generating SBOM using Poetry..."
21-
cyclonedx-py poetry > sbom-python-poetry.json
40+
asdf exec cyclonedx-py poetry > sbom-python-poetry.json
2241
fi
2342

2443
if [ -f "requirements.txt" ]; then
2544
echo "Detected requirements.txt. Generating SBOM using pip..."
26-
cyclonedx-py requirements > sbom-python-pip.json
45+
asdf exec cyclonedx-py requirements > sbom-python-pip.json
2746
fi
2847

2948
echo "Done"
@@ -37,6 +56,8 @@ for sbom in ./sbom*.json; do
3756
fi
3857
done
3958

59+
# Don't exit on failure until we check all files.
60+
set +e
4061
# Initialize an error flag
4162
error_occurred=false
4263

@@ -60,5 +81,4 @@ if [ "$error_occurred" = true ]; then
6081
exit 1
6182
else
6283
echo "All checks completed successfully."
63-
exit 0
64-
fi
84+
fi

0 commit comments

Comments
 (0)