Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
22 changes: 17 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
FROM alpine:3.23.3 AS build
ARG TARGETARCH
RUN apk add --no-cache cosign bash curl jq
COPY src/base/.devcontainer/scripts/install_trivy.sh /tmp/install_trivy.sh
RUN case "${TARGETARCH}" in \
x86_64|amd64) TRIVY_ARCH=64bit ;; \
aarch64|arm64) TRIVY_ARCH=ARM64 ;; \
*) echo "Unsupported TARGETARCH: ${TARGETARCH}" && exit 1 ;; \
esac \
&& INSTALL_DIR=/tmp/trivy/ ARCH="${TRIVY_ARCH}" /tmp/install_trivy.sh
Comment thread
anthony-nhs marked this conversation as resolved.
Comment on lines +1 to +10
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stage executes /tmp/install_trivy.sh directly, but the preceding COPY doesn’t set executable permissions. Consider using COPY --chmod=755 ... (or calling bash /tmp/install_trivy.sh) so the build doesn’t rely on the script’s executable bit in git.

Copilot uses AI. Check for mistakes.


FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04
ARG TARGETARCH
ENV TARGETARCH=${TARGETARCH}
Expand Down Expand Up @@ -64,11 +76,13 @@ RUN git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets && \
chmod 755 /usr/share/secrets-scanner && \
curl -L https://raw.githubusercontent.com/NHSDigital/software-engineering-quality-framework/main/tools/nhsd-git-secrets/nhsd-rules-deny.txt -o /usr/share/secrets-scanner/nhsd-rules-deny.txt

COPY --from=build /tmp/trivy/trivy /usr/local/bin/trivy

USER vscode

ENV PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"
ENV PATH="/home/vscode/.asdf/shims:/home/vscode/.local/bin:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"
RUN \
echo 'PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"' >> ~/.bashrc; \
echo 'PATH="/home/vscode/.asdf/shims:/home/vscode/.local/bin:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"' >> ~/.bashrc; \
echo '. <(asdf completion bash)' >> ~/.bashrc; \
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc; \
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc; \
Expand All @@ -82,9 +96,7 @@ RUN asdf plugin add python; \
asdf plugin add direnv; \
asdf plugin add actionlint; \
asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git; \
asdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git; \
asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git

asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git;

WORKDIR /workspaces/eps-devcontainers
COPY .tool-versions /workspaces/eps-devcontainers/.tool-versions
Expand Down
3 changes: 2 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind",
"source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind",
"source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind",
"source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind"
"source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind",
"source=${env:HOME}${env:USERPROFILE}/.gitconfig,target=/home/vscode/.gitconfig,type=bind"
],
"runArgs": [
"--network=host"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build_all_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
echo "node_24_languages=$node_24_language_folders"
echo "projects=$project_folders"
} >> "$GITHUB_OUTPUT"

package_base_docker_image:
uses: ./.github/workflows/build_multi_arch_image.yml
with:
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/build_multi_arch_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ jobs:
with:
fetch-depth: 0
- name: setup trivy
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514
with:
version: v0.69.3
run: |
docker build --output=/usr/local/bin/ -f "src/base/.devcontainer/Dockerfile.trivy.${ARCH}" .
Comment thread
anthony-nhs marked this conversation as resolved.
Outdated
env:
ARCH: '${{ matrix.arch }}'
- name: setup node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ src/base/.devcontainer/language_versions/
.trivyignore_combined.yaml
.out/
.envrc
.trivy_out/
1 change: 0 additions & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ shellcheck 0.11.0
direnv 2.37.1
actionlint 1.7.10
ruby 3.3.0
trivy 0.69.3
yq 4.52.2
7 changes: 3 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ guard-%:
exit 1; \
fi

.PHONY: install install-python install-node install-hooks build-base-image build-node-24-image build-node-24-python-3-10-image build-node-24-python-3-12-image build-node-24-python-3-13-image build-node-24-python-3-14-image \
build-eps-storage-terraform-image build-fhir-facade-image build-node-24-python-3-14-golang-1-24-image build-node-24-python-3-14-java-24-image \
build-regression-tests-image build-all build-image build-githubactions-image scan-image scan-image-json shell-image lint test lint-githubactions lint-githubaction-scripts clean
install: install-python install-node install-hooks

install-python:
Expand Down Expand Up @@ -129,13 +132,9 @@ test:
lint-githubactions:
actionlint

github-login:
gh auth login --scopes read:packages

lint-githubaction-scripts:
shellcheck .github/scripts/*.sh
Comment thread
anthony-nhs marked this conversation as resolved.

clean:
rm -rf .out
find . -type f -name '.trivyignore_combined.yaml' -delete

1 change: 0 additions & 1 deletion src/base/.devcontainer/.tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ shellcheck 0.11.0
direnv 2.37.1
actionlint 1.7.11
ruby 3.3.0
trivy 0.69.3
yq 4.52.4
13 changes: 13 additions & 0 deletions src/base/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
FROM alpine:3.23.3 AS build
ARG TARGETARCH
RUN apk add --no-cache cosign bash curl jq
COPY scripts/install_trivy.sh /tmp/install_trivy.sh
RUN case "${TARGETARCH}" in \
x86_64|amd64) TRIVY_ARCH=64bit ;; \
aarch64|arm64) TRIVY_ARCH=ARM64 ;; \
*) echo "Unsupported TARGETARCH: ${TARGETARCH}" && exit 1 ;; \
esac \
&& INSTALL_DIR=/tmp/trivy/ ARCH="${TRIVY_ARCH}" /tmp/install_trivy.sh
Comment on lines +1 to +10
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stage executes /tmp/install_trivy.sh directly, but the preceding COPY doesn’t set executable permissions. Consider using COPY --chmod=755 ... (or calling bash /tmp/install_trivy.sh) so the build doesn’t rely on the script’s executable bit in git.

Copilot uses AI. Check for mistakes.

FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04

ARG SCRIPTS_DIR=/usr/local/share/eps
Expand All @@ -16,6 +27,8 @@ COPY --chmod=755 Mk ${SCRIPTS_DIR}/Mk
WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME}
RUN ./root_install.sh

COPY --from=build /tmp/trivy/trivy /usr/local/bin/trivy

COPY --chmod=755 scripts/vscode_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/vscode_install.sh
USER vscode
COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf
Expand Down
9 changes: 9 additions & 0 deletions src/base/.devcontainer/Dockerfile.trivy.amd64
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM alpine:3.23.3 AS build
ARG TARGETARCH
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARG TARGETARCH is declared but never used in this Dockerfile. Consider removing it to avoid confusion/warnings, or use it to validate the expected architecture for the downloaded Trivy binary.

Suggested change
ARG TARGETARCH

Copilot uses AI. Check for mistakes.
RUN apk add --no-cache cosign bash curl jq
COPY src/base/.devcontainer/scripts/install_trivy.sh /tmp/install_trivy.sh
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This build stage runs /tmp/install_trivy.sh directly, but the preceding COPY doesn’t set executable permissions. To make the build independent of the git file mode, either copy it with --chmod=755 or invoke it via bash /tmp/install_trivy.sh.

Suggested change
COPY src/base/.devcontainer/scripts/install_trivy.sh /tmp/install_trivy.sh
COPY --chmod=755 src/base/.devcontainer/scripts/install_trivy.sh /tmp/install_trivy.sh

Copilot uses AI. Check for mistakes.
RUN INSTALL_DIR=/tmp/trivy/ ARCH=64bit /tmp/install_trivy.sh

FROM scratch
COPY --from=build /tmp/trivy/trivy /
ENTRYPOINT ["/trivy"]
9 changes: 9 additions & 0 deletions src/base/.devcontainer/Dockerfile.trivy.arm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM alpine:3.23.3 AS build
ARG TARGETARCH
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARG TARGETARCH is declared but never used in this Dockerfile. Consider removing it to avoid confusion/warnings, or use it to validate the expected architecture for the downloaded Trivy binary.

Suggested change
ARG TARGETARCH

Copilot uses AI. Check for mistakes.
RUN apk add --no-cache cosign bash curl jq
COPY src/base/.devcontainer/scripts/install_trivy.sh /tmp/install_trivy.sh
RUN INSTALL_DIR=/tmp/trivy/ ARCH=ARM64 /tmp/install_trivy.sh
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This build stage runs /tmp/install_trivy.sh directly, but the preceding COPY doesn’t set executable permissions. To make the build independent of the git file mode, either copy it with --chmod=755 or invoke it via bash /tmp/install_trivy.sh.

Suggested change
RUN INSTALL_DIR=/tmp/trivy/ ARCH=ARM64 /tmp/install_trivy.sh
RUN INSTALL_DIR=/tmp/trivy/ ARCH=ARM64 bash /tmp/install_trivy.sh

Copilot uses AI. Check for mistakes.

FROM scratch
COPY --from=build /tmp/trivy/trivy /
ENTRYPOINT ["/trivy"]
62 changes: 62 additions & 0 deletions src/base/.devcontainer/scripts/install_trivy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail

DEFAULT_INSTALL_DIR="/usr/local/bin"
INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}"
VERSION="v0.69.3"
Comment thread
anthony-nhs marked this conversation as resolved.
Outdated
DEFAULT_ARCH="64bit"
ARCH="${ARCH:-$DEFAULT_ARCH}"
RELEASE_NUMBER="${VERSION#v}"
BASE_URL="https://github.com/aquasecurity/trivy/releases/download/${VERSION}"
ARCHIVE="trivy_${RELEASE_NUMBER}_Linux-${ARCH}.tar.gz"
BUNDLE="${ARCHIVE}.sigstore.json"
CERT_IDENTITY="https://github.com/aquasecurity/trivy/.github/workflows/reusable-release.yaml@refs/tags/${VERSION}"

usage() {
cat <<'EOF'
Usage: install_trivy.sh [output_dir]

Downloads Trivy, its sigstore bundle, and checksum into output_dir (default: current directory),
then verifies the checksum and the sigstore bundle, following
https://github.com/aquasecurity/trivy/blob/main/docs/getting-started/signature-verification.md.
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help/usage text claims the script accepts an output_dir argument and downloads + verifies checksums, but the implementation ignores positional args and does not download or verify a checksum file. Either implement the documented behaviour (incl. checksum handling) or update the usage text/arg parsing to match what the script actually does.

Suggested change
Usage: install_trivy.sh [output_dir]
Downloads Trivy, its sigstore bundle, and checksum into output_dir (default: current directory),
then verifies the checksum and the sigstore bundle, following
https://github.com/aquasecurity/trivy/blob/main/docs/getting-started/signature-verification.md.
Usage: install_trivy.sh
Downloads the Trivy archive and its sigstore bundle to a temporary directory,
verifies the sigstore bundle following
https://github.com/aquasecurity/trivy/blob/main/docs/getting-started/signature-verification.md,
and installs the trivy binary into INSTALL_DIR (default: /usr/local/bin).
Environment variables:
INSTALL_DIR Directory to install the trivy binary into (default: /usr/local/bin)
VERSION Trivy version tag to install (default: v0.69.3)
ARCH Architecture suffix used in the download (default: 64bit)

Copilot uses AI. Check for mistakes.
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi

for cmd in curl cosign sha256sum; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Error: $cmd is required but not found in PATH" >&2
exit 1
fi
done
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sha256sum is checked as a required dependency, but the script never uses it. This makes the installer fail unnecessarily on minimal images; either remove it from the dependency check or add the missing checksum verification step.

Copilot uses AI. Check for mistakes.

TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

download() {
local url="${1}" dest="${2}"
echo "Downloading ${dest} ..."
curl -fsSL "${url}" -o "${dest}"
}
ARCHIVE_PATH="${TMP_DIR}/${ARCHIVE}"
BUNDLE_PATH="${TMP_DIR}/${BUNDLE}"
download "${BASE_URL}/${ARCHIVE}" "${ARCHIVE_PATH}"
download "${BASE_URL}/${BUNDLE}" "${BUNDLE_PATH}"


cosign verify-blob-attestation "${ARCHIVE_PATH}" \
--bundle "${BUNDLE_PATH}" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
--certificate-identity "${CERT_IDENTITY}"

echo "Sigstore verification passed"
tar -xzf "${ARCHIVE_PATH}" -C "${TMP_DIR}"

mkdir -p "$INSTALL_DIR"
install -m 0755 "$TMP_DIR/trivy" "${INSTALL_DIR}/trivy"

echo "trivy ${VERSION} installed to ${INSTALL_DIR}"
Loading