diff --git a/.devcontainer/post_create_command.sh b/.devcontainer/post_create_command.sh index 493879d..e815ef0 100755 --- a/.devcontainer/post_create_command.sh +++ b/.devcontainer/post_create_command.sh @@ -17,6 +17,6 @@ npm install -g @devcontainers/cli pre-commit install -scripts/create_builder.sh +# scripts/create_builder.sh sudo apt-get update && sudo apt-get install -y shellcheck diff --git a/scripts/build.sh b/scripts/build.sh index d60bf62..3b225ae 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -41,19 +41,32 @@ done echo "Building all labels (" "${LABELS[@]}" ") for architecture: ${ARCH}" -# Prepare image names with tags (each tag includes a label and the architecture) -IMAGES=() -for LABEL in "${LABELS[@]}"; do - IMAGES+=("--image-name \"ghcr.io/eclipse-score/devcontainer:${LABEL}-${ARCH}\"") -done +function build_container() { + local name="$1" -# Prepare devcontainer build command -DEVCONTAINER_CALL="devcontainer build --workspace-folder src/s-core-devcontainer --cache-from ghcr.io/eclipse-score/devcontainer" + # Prepare image names with tags (each tag includes a label and the architecture) + IMAGES=() + for LABEL in "${LABELS[@]}"; do + IMAGES+=("--image-name \"ghcr.io/eclipse-score/${name}:${LABEL}-${ARCH}\"") + done -# Append image names to the build command -for IMAGE in "${IMAGES[@]}"; do - DEVCONTAINER_CALL+=" ${IMAGE}" -done + # Prepare devcontainer build command + DEVCONTAINER_CALL="devcontainer build --workspace-folder src/s-core-${name} --cache-from ghcr.io/eclipse-score/${name}" + # DEVCONTAINER_CALL+=" --output=type=docker,push=true,platform=linux/${ARCH}" + + # Append image names to the build command + for IMAGE in "${IMAGES[@]}"; do + DEVCONTAINER_CALL+=" ${IMAGE}" + done + + # Execute the build for the specific architecture + eval "${DEVCONTAINER_CALL} --platform linux/${ARCH}" +} + +# TODO: this is a workaround so that the devcontainer build can use the buildcontainer image +# but it reverts any action done in scripts/create_builder.sh and cannot be merged to main +# docker buildx use default -# Execute the build for the specific architecture -eval "${DEVCONTAINER_CALL} --platform linux/${ARCH}" +# Build the containers +build_container "buildcontainer" +build_container "devcontainer" diff --git a/scripts/merge.sh b/scripts/merge.sh index 6f0aff2..1cb9c53 100755 --- a/scripts/merge.sh +++ b/scripts/merge.sh @@ -16,6 +16,9 @@ set -euxo pipefail +SCRIPT_PATH=$(readlink -f "$0") +SCRIPT_DIR=$(dirname -- "${SCRIPT_PATH}") + if [ "$#" -eq 0 ]; then echo "Error: At least one parameter (label) must be provided." exit 1 @@ -29,22 +32,32 @@ done # Define target architectures ARCHITECTURES=("amd64" "arm64") -# Pull all architecture-specific images for each label -for LABEL in "${LABELS[@]}"; do - for ARCH in "${ARCHITECTURES[@]}"; do - docker pull --platform "linux/${ARCH}" "ghcr.io/eclipse-score/devcontainer:${LABEL}-${ARCH}" +"${SCRIPT_DIR}/create_builder.sh" + +function merge_containers() { + local name="$1" + + # Pull all architecture-specific images for each label + for LABEL in "${LABELS[@]}"; do + for ARCH in "${ARCHITECTURES[@]}"; do + docker pull --platform "linux/${ARCH}" "ghcr.io/eclipse-score/${name}:${LABEL}-${ARCH}" + done done -done -# Create and push the merged multiarch manifest for each tag; each tag combines all architecture-specific tags into one tag -for LABEL in "${LABELS[@]}"; do - echo "Merging all architectures (" "${ARCHITECTURES[@]}" ") into single tag: ${LABEL}" + # Create and push the merged multiarch manifest for each tag; each tag combines all architecture-specific tags into one tag + for LABEL in "${LABELS[@]}"; do + echo "Merging all architectures (" "${ARCHITECTURES[@]}" ") into single tag: ${LABEL}" + + MANIFEST_MERGE_CALL="docker buildx imagetools create -t ghcr.io/eclipse-score/${name}:${LABEL}" - MANIFEST_MERGE_CALL="docker buildx imagetools create -t ghcr.io/eclipse-score/devcontainer:${LABEL}" + for ARCH in "${ARCHITECTURES[@]}"; do + MANIFEST_MERGE_CALL+=" ghcr.io/eclipse-score/${name}:${LABEL}-${ARCH}" + done - for ARCH in "${ARCHITECTURES[@]}"; do - MANIFEST_MERGE_CALL+=" ghcr.io/eclipse-score/devcontainer:${LABEL}-${ARCH}" + eval "${MANIFEST_MERGE_CALL}" done +} - eval "${MANIFEST_MERGE_CALL}" -done +# Merge containers +merge_containers buildcontainer +merge_containers devcontainer diff --git a/scripts/publish.sh b/scripts/publish.sh index 210368a..b728792 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -39,20 +39,29 @@ for LABEL in "$@"; do LABELS+=("${LABEL}") done -echo "Building all tags (" "${LABELS[@]}" ") for architecture: ${ARCH}" -# Prepare image names with tags (each tag includes a label and an architecture) -IMAGES=() -for LABEL in "${LABELS[@]}"; do - IMAGES+=("--image-name \"ghcr.io/eclipse-score/devcontainer:${LABEL}-${ARCH}\"") -done +echo "Pushing all tags (" "${LABELS[@]}" ") for architecture: ${ARCH}" -# Prepare devcontainer build command -DEVCONTAINER_CALL="devcontainer build --push --workspace-folder src/s-core-devcontainer --cache-from ghcr.io/eclipse-score/devcontainer" +push_container() { + local name="$1" -# Append image names to the build command -for IMAGE in "${IMAGES[@]}"; do - DEVCONTAINER_CALL+=" ${IMAGE}" -done + # Prepare image names with tags (each tag includes a label and an architecture) + IMAGES=() + for LABEL in "${LABELS[@]}"; do + IMAGES+=("--image-name \"ghcr.io/eclipse-score/${name}:${LABEL}-${ARCH}\"") + done + + # Prepare devcontainer build command + DEVCONTAINER_CALL="devcontainer build --push --workspace-folder src/s-core-${name} --cache-from ghcr.io/eclipse-score/${name}" + + # Append image names to the build command + for IMAGE in "${IMAGES[@]}"; do + DEVCONTAINER_CALL+=" ${IMAGE}" + done + + # Execute the build and push all tags for the specific architecture + eval "${DEVCONTAINER_CALL} --platform linux/${ARCH}" +} -# Execute the build and push all tags for the specific architecture -eval "${DEVCONTAINER_CALL} --platform linux/${ARCH}" +# Push the containers +push_container "buildcontainer" +push_container "devcontainer" diff --git a/scripts/test.sh b/scripts/test.sh index 4ab7f21..a633a38 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -16,22 +16,30 @@ set -euxo pipefail -IMAGE="s-core-devcontainer" - export DOCKER_BUILDKIT=1 SCRIPT_PATH=$(readlink -f "$0") SCRIPT_DIR=$(dirname -- "${SCRIPT_PATH}") PROJECT_DIR=$(dirname -- "${SCRIPT_DIR}") -ID_LABEL="test-container=${IMAGE}" - -devcontainer up \ - --id-label "${ID_LABEL}" \ - --workspace-folder "${PROJECT_DIR}/src/${IMAGE}/" \ - --remove-existing-container - -# Run actual test -echo "(*) Running test..." -devcontainer exec --workspace-folder "${PROJECT_DIR}/src/${IMAGE}" --id-label "${ID_LABEL}" \ - /bin/sh -c 'set -e && cd test-project && \ - ./test.sh' + +function test_container() { + local name="$1" + + local IMAGE="s-core-${name}" + local ID_LABEL="test-container=${IMAGE}" + + devcontainer up \ + --id-label "${ID_LABEL}" \ + --workspace-folder "${PROJECT_DIR}/src/${IMAGE}/" \ + --remove-existing-container + + # Run actual test + echo "(*) Running test..." + devcontainer exec --workspace-folder "${PROJECT_DIR}/src/${IMAGE}" --id-label "${ID_LABEL}" \ + /bin/sh -c 'set -e && cd test-project && \ + ./test.sh' +} + +# Test the containers +test_container "buildcontainer" +test_container "devcontainer" diff --git a/src/s-core-devcontainer/.devcontainer/Dockerfile b/src/s-core-buildcontainer/.devcontainer/Dockerfile similarity index 100% rename from src/s-core-devcontainer/.devcontainer/Dockerfile rename to src/s-core-buildcontainer/.devcontainer/Dockerfile diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/devcontainer-feature.json b/src/s-core-buildcontainer/.devcontainer/bazel-feature/devcontainer-feature.json similarity index 92% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/devcontainer-feature.json rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/devcontainer-feature.json index d60e94f..c522ac8 100644 --- a/src/s-core-devcontainer/.devcontainer/bazel-feature/devcontainer-feature.json +++ b/src/s-core-buildcontainer/.devcontainer/bazel-feature/devcontainer-feature.json @@ -4,7 +4,7 @@ "version": "1.0.0", "description": "Bazel and supplimentary tools for working with Bazel-based projects.", "dependsOn": { - "./s-core-local": {} // needed for extracting versions (versions.sh) + "./s-core-build": {} // needed for extracting versions (versions.sh) }, "onCreateCommand": "/devcontainer/features/bazel/on_create_command.sh", "postCreateCommand": { diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/devcontainer-feature.json.license b/src/s-core-buildcontainer/.devcontainer/bazel-feature/devcontainer-feature.json.license similarity index 100% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/devcontainer-feature.json.license rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/devcontainer-feature.json.license diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/install.sh b/src/s-core-buildcontainer/.devcontainer/bazel-feature/install.sh similarity index 98% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/install.sh rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/install.sh index eb6c0f0..801af38 100755 --- a/src/s-core-devcontainer/.devcontainer/bazel-feature/install.sh +++ b/src/s-core-buildcontainer/.devcontainer/bazel-feature/install.sh @@ -30,7 +30,7 @@ rm -f "${COPY_TARGET}/devcontainer-features.env" "${COPY_TARGET}/devcontainer-fe DEBIAN_FRONTEND=noninteractive # Read tool versions + metadata into environment variables -. /devcontainer/features/s-core-local/versions.sh /devcontainer/features/bazel/versions.yaml +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/bazel/versions.yaml ARCHITECTURE=$(dpkg --print-architecture) diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/install_matching_bazel_version.sh b/src/s-core-buildcontainer/.devcontainer/bazel-feature/install_matching_bazel_version.sh similarity index 100% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/install_matching_bazel_version.sh rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/install_matching_bazel_version.sh diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/on_create_command.sh b/src/s-core-buildcontainer/.devcontainer/bazel-feature/on_create_command.sh similarity index 100% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/on_create_command.sh rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/on_create_command.sh diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/tests/test_default.sh b/src/s-core-buildcontainer/.devcontainer/bazel-feature/tests/test_default.sh similarity index 96% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/tests/test_default.sh rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/tests/test_default.sh index b1e1bc2..f72de4a 100755 --- a/src/s-core-devcontainer/.devcontainer/bazel-feature/tests/test_default.sh +++ b/src/s-core-buildcontainer/.devcontainer/bazel-feature/tests/test_default.sh @@ -17,7 +17,7 @@ set -euo pipefail # Read tool versions + metadata into environment variables -. /devcontainer/features/s-core-local/versions.sh /devcontainer/features/bazel/versions.yaml +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/bazel/versions.yaml # Bazel-related tools ## This is the bazel version preinstalled in the devcontainer. diff --git a/src/s-core-devcontainer/.devcontainer/bazel-feature/versions.yaml b/src/s-core-buildcontainer/.devcontainer/bazel-feature/versions.yaml similarity index 100% rename from src/s-core-devcontainer/.devcontainer/bazel-feature/versions.yaml rename to src/s-core-buildcontainer/.devcontainer/bazel-feature/versions.yaml diff --git a/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json b/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json new file mode 100644 index 0000000..46ea787 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json @@ -0,0 +1,14 @@ +{ + "features": { + "ghcr.io/devcontainers-extra/features/pre-commit:2": { + "version": "2.0.18", + "resolved": "ghcr.io/devcontainers-extra/features/pre-commit@sha256:6e0bb2ce80caca1d94f44dab5d0653d88a1c00984e590adb7c6bce012d0ade6e", + "integrity": "sha256:6e0bb2ce80caca1d94f44dab5d0653d88a1c00984e590adb7c6bce012d0ade6e" + }, + "ghcr.io/devcontainers/features/common-utils": { + "version": "2.5.4", + "resolved": "ghcr.io/devcontainers/features/common-utils@sha256:00fd45550f578d9d515044d9e2226e908dbc3d7aa6fcb9dee4d8bdb60be114cf", + "integrity": "sha256:00fd45550f578d9d515044d9e2226e908dbc3d7aa6fcb9dee4d8bdb60be114cf" + } + } +} \ No newline at end of file diff --git a/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json.license b/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json.license new file mode 100644 index 0000000..1db4fe4 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/devcontainer-lock.json.license @@ -0,0 +1,13 @@ +******************************************************************************* +Copyright (c) 2026 Contributors to the Eclipse Foundation + +See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. + +This program and the accompanying materials are made available under the +terms of the Apache License Version 2.0 which is available at +https://www.apache.org/licenses/LICENSE-2.0 + +SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +SPDX-License-Identifier: Apache-2.0 +******************************************************************************* diff --git a/src/s-core-buildcontainer/.devcontainer/devcontainer.json b/src/s-core-buildcontainer/.devcontainer/devcontainer.json new file mode 100644 index 0000000..d799c31 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/devcontainer.json @@ -0,0 +1,35 @@ +{ + "build": { + // Installs latest version from the Distribution + "dockerfile": "./Dockerfile", + "context": ".", + "args": { + "HTTP_PROXY": "${localEnv:HTTP_PROXY}", + "HTTPS_PROXY": "${localEnv:HTTPS_PROXY}", + "http_proxy": "${localEnv:http_proxy}", + "https_proxy": "${localEnv:https_proxy}", + "NO_PROXY": "${localEnv:NO_PROXY}", + "no_proxy": "${localEnv:no_proxy}" + } + }, + "features": { + "ghcr.io/devcontainers/features/common-utils": { + // Installs latest version from the Distribution + "installZsh": "false", + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": "false" // WARNING: do *not* enable; this would include packages also from other features, which may have been pinned to a specific version + }, + "./s-core-build": {}, + "./bazel-feature": {} + }, + "overrideFeatureInstallOrder": [ + // this order makes it more convenient to develop the local features, since they will be installed last + // which means changes to it will be applied without needing to rebuild all other features + "ghcr.io/devcontainers/features/common-utils", + "./s-core-build", + "./bazel-feature" + ], + "remoteUser": "vscode" +} diff --git a/src/s-core-buildcontainer/.devcontainer/devcontainer.json.license b/src/s-core-buildcontainer/.devcontainer/devcontainer.json.license new file mode 100644 index 0000000..1db4fe4 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/devcontainer.json.license @@ -0,0 +1,13 @@ +******************************************************************************* +Copyright (c) 2026 Contributors to the Eclipse Foundation + +See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. + +This program and the accompanying materials are made available under the +terms of the Apache License Version 2.0 which is available at +https://www.apache.org/licenses/LICENSE-2.0 + +SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +SPDX-License-Identifier: Apache-2.0 +******************************************************************************* diff --git a/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json b/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json new file mode 100644 index 0000000..a44c3a4 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json @@ -0,0 +1,14 @@ +{ + "name": "Eclipse S-CORE-specific essential build tools", + "id": "s-core-build", + "version": "1.0.0", + "description": "Tools which are required for building and are not available as already existing development container feature", + "dependsOn": { + "ghcr.io/devcontainers-extra/features/pre-commit:2": { + "version": "4.5.1" + } + }, + "postCreateCommand": { + "Enable pre-commit hooks": "bash /devcontainer/features/s-core-build/enable_pre_commit_hooks.sh" + } +} diff --git a/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json.license b/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json.license new file mode 100644 index 0000000..1db4fe4 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/s-core-build/devcontainer-feature.json.license @@ -0,0 +1,13 @@ +******************************************************************************* +Copyright (c) 2026 Contributors to the Eclipse Foundation + +See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. + +This program and the accompanying materials are made available under the +terms of the Apache License Version 2.0 which is available at +https://www.apache.org/licenses/LICENSE-2.0 + +SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +SPDX-License-Identifier: Apache-2.0 +******************************************************************************* diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/enable_pre_commit_hooks.sh b/src/s-core-buildcontainer/.devcontainer/s-core-build/enable_pre_commit_hooks.sh similarity index 100% rename from src/s-core-devcontainer/.devcontainer/s-core-local/enable_pre_commit_hooks.sh rename to src/s-core-buildcontainer/.devcontainer/s-core-build/enable_pre_commit_hooks.sh diff --git a/src/s-core-buildcontainer/.devcontainer/s-core-build/install.sh b/src/s-core-buildcontainer/.devcontainer/s-core-build/install.sh new file mode 100755 index 0000000..5cf019a --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/s-core-build/install.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +set -euo pipefail + +# Copy feature sources and tests to expected location +FEATURES_DIR="/devcontainer/features" +SCRIPT_PATH=$(readlink -f "$0") +SCRIPT_DIR=$(dirname -- "${SCRIPT_PATH}") +mkdir -p "${FEATURES_DIR}" +COPY_TARGET="${FEATURES_DIR}/$(basename "${SCRIPT_DIR%%_*}")" +cp -R "${SCRIPT_DIR}" "${COPY_TARGET}" +rm -f "${COPY_TARGET}/devcontainer-features.env" "${COPY_TARGET}/devcontainer-features-install.sh" + +# shellcheck disable=SC2034 +# used by apt-get only inside this script +DEBIAN_FRONTEND=noninteractive + +# Read tool versions + metadata into environment variables +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/s-core-build/versions.yaml + +apt-get update + +# INSTALL CONTAINER BUILD DEPENDENCIES +# Container build dependencies are not pinned, since they are removed anyway after container creation. +apt-get install apt-transport-https -y + +# GraphViz +# The Ubuntu Noble package of GraphViz +apt-get install -y graphviz="${graphviz_version}*" + +# Protobuf compiler, via APT (needed by FEO) +apt-get install -y protobuf-compiler="${protobuf_compiler_version}*" + +# Python, via APT +apt-get install -y "python${python_version}" python3-pip python3-venv +# The following packages correspond to the list of packages installed by the +# devcontainer feature "python" (cf. https://github.com/devcontainers/features/tree/main/src/python ) +apt-get install -y flake8 python3-autopep8 black python3-yapf mypy pydocstyle pycodestyle bandit pipenv virtualenv python3-pytest pylint + +# OpenJDK 21, via APT +# Set JAVA_HOME environment variable system-wide, since some tools rely on it (e.g., Bazel's rules_java) +apt-get install -y ca-certificates-java openjdk-21-jdk-headless="${openjdk_21_version}*" +JAVA_HOME="$(dirname $(dirname $(realpath $(command -v javac))))" +export JAVA_HOME +echo -e "JAVA_HOME=${JAVA_HOME}\nexport JAVA_HOME" > /etc/profile.d/java_home.sh + +# qemu-system-arm +apt-get install -y --no-install-recommends --fix-broken qemu-system-arm="${qemu_system_arm_version}*" + +# sshpass +apt-get install -y sshpass="${sshpass_version}*" + +# Cleanup +# REMOVE CONTAINER BUILD DEPENDENCIES +apt-get remove --purge -y apt-transport-https +apt-get autoremove -y +apt-get clean +rm -rf /var/lib/apt/lists/* diff --git a/src/s-core-buildcontainer/.devcontainer/s-core-build/tests/test_default.sh b/src/s-core-buildcontainer/.devcontainer/s-core-build/tests/test_default.sh new file mode 100755 index 0000000..d21ed18 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/s-core-build/tests/test_default.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +set -euo pipefail + +# Read tool versions + metadata into environment variables +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/s-core-build/versions.yaml + +# pre-commit, it is available via $PATH in login shells, but not in non-login shells +check "validate pre-commit is working and has the correct version" bash -c "${PIPX_BIN_DIR}/pre-commit --version | grep '4.5.1'" + +# For an unknown reason, dot -V reports on Ubuntu Noble a version 2.43.0, while the package has a different version. +# Hence, we have to work around that. +check "validate graphviz is working" bash -c "dot -V" +check "validate graphviz has the correct version" bash -c "dpkg -s graphviz | grep 'Version: ${graphviz_version}'" + +# Other build-related tools +check "validate protoc is working and has the correct version" bash -c "protoc --version | grep 'libprotoc ${protobuf_compiler_version}'" + +# Python-related tools (a selected sub-set; others may be added later) +check "validate python3 is working and has the correct version" bash -c "python3 --version | grep '${python_version}'" +check "validate pip3 is working and has the correct version" bash -c "pip3 --version | grep '${python_version}'" +check "validate black is working and has the correct version" bash -c "black --version | grep '${python_version}'" +# cannot grep versions as they do not match the Python version +check "validate virtualenv is working" bash -c "virtualenv --version" +check "validate flake8 is working" bash -c "flake8 --version" +check "validate pytest is working" bash -c "pytest --version" +check "validate pylint is working" bash -c "pylint --version" + +# OpenJDK +check "validate java is working and has the correct version" bash -c "java -version 2>&1 | grep '${openjdk_21_version}'" +check "validate JAVA_HOME is set correctly" bash -c "echo ${JAVA_HOME} | xargs readlink -f | grep \"java-21-openjdk\"" + +# Qemu target-related tools +check "validate qemu-system-aarch64 is working and has the correct version" bash -c "qemu-system-aarch64 --version | grep '${qemu_system_arm_version}'" +check "validate sshpass is working and has the correct version" bash -c "sshpass -V | grep '${sshpass_version}'" diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/versions.sh b/src/s-core-buildcontainer/.devcontainer/s-core-build/versions.sh similarity index 100% rename from src/s-core-devcontainer/.devcontainer/s-core-local/versions.sh rename to src/s-core-buildcontainer/.devcontainer/s-core-build/versions.sh diff --git a/src/s-core-buildcontainer/.devcontainer/s-core-build/versions.yaml b/src/s-core-buildcontainer/.devcontainer/s-core-build/versions.yaml new file mode 100644 index 0000000..0bdb454 --- /dev/null +++ b/src/s-core-buildcontainer/.devcontainer/s-core-build/versions.yaml @@ -0,0 +1,32 @@ +--- +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +graphviz: + version: 2.42.2 + +protobuf_compiler: + version: 3.21.12 + +qemu_system_arm: + version: 1:8.2.2 + +sshpass: + version: 1.09 + +python: + version: '3.12' + +openjdk_21: + version: 21.0.10 diff --git a/src/s-core-devcontainer/.devcontainer/unset-proxy.sh b/src/s-core-buildcontainer/.devcontainer/unset-proxy.sh similarity index 100% rename from src/s-core-devcontainer/.devcontainer/unset-proxy.sh rename to src/s-core-buildcontainer/.devcontainer/unset-proxy.sh diff --git a/src/s-core-buildcontainer/manifest.json b/src/s-core-buildcontainer/manifest.json new file mode 100644 index 0000000..820269c --- /dev/null +++ b/src/s-core-buildcontainer/manifest.json @@ -0,0 +1,5 @@ +{ + "version": "1.0.0", + "image_name": "ghcr.io/eclipse-score/buildcontainer", + "description": "Build the Eclipse S-CORE project" +} diff --git a/src/s-core-buildcontainer/manifest.json.license b/src/s-core-buildcontainer/manifest.json.license new file mode 100644 index 0000000..1db4fe4 --- /dev/null +++ b/src/s-core-buildcontainer/manifest.json.license @@ -0,0 +1,13 @@ +******************************************************************************* +Copyright (c) 2026 Contributors to the Eclipse Foundation + +See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. + +This program and the accompanying materials are made available under the +terms of the Apache License Version 2.0 which is available at +https://www.apache.org/licenses/LICENSE-2.0 + +SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +SPDX-License-Identifier: Apache-2.0 +******************************************************************************* diff --git a/src/s-core-buildcontainer/test-project/test-utils.sh b/src/s-core-buildcontainer/test-project/test-utils.sh new file mode 100755 index 0000000..8d312b3 --- /dev/null +++ b/src/s-core-buildcontainer/test-project/test-utils.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +set -eo pipefail + +if [[ -z ${HOME} ]]; then + HOME="/root" +fi + +FAILED=() + +echoStderr() +{ + echo "$@" 1>&2 +} + +check() { + LABEL=$1 + shift + echo -e "\n🧪 Testing ${LABEL}" + if "$@"; then + echo "✅ Passed!" + return 0 + else + echoStderr "❌ ${LABEL} check failed." + FAILED+=("${LABEL}") + return 1 + fi +} + +reportResults() { + if [[ ${#FAILED[@]} -ne 0 ]]; then + echoStderr -e "\n💥 Failed tests:" "${FAILED[@]}" + exit 1 + else + echo -e "\n💯 All passed!" + exit 0 + fi +} diff --git a/src/s-core-buildcontainer/test-project/test.sh b/src/s-core-buildcontainer/test-project/test.sh new file mode 100755 index 0000000..33b930a --- /dev/null +++ b/src/s-core-buildcontainer/test-project/test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +set -euo pipefail + +source "test-utils.sh" vscode + +# Tests from the local s-core-build feature +source /devcontainer/features/s-core-build/tests/test_default.sh + +# Tests from the local bazel feature +source /devcontainer/features/bazel/tests/test_default.sh + +# Report result +reportResults diff --git a/src/s-core-devcontainer/.devcontainer/devcontainer-lock.json b/src/s-core-devcontainer/.devcontainer/devcontainer-lock.json index 7e98f7e..9b3e0c6 100644 --- a/src/s-core-devcontainer/.devcontainer/devcontainer-lock.json +++ b/src/s-core-devcontainer/.devcontainer/devcontainer-lock.json @@ -5,16 +5,6 @@ "resolved": "ghcr.io/devcontainers-community/features/llvm@sha256:4f464ab97a59439286a55490b55ba9851616f6f76ac3025e134127ac08ad79e2", "integrity": "sha256:4f464ab97a59439286a55490b55ba9851616f6f76ac3025e134127ac08ad79e2" }, - "ghcr.io/devcontainers-extra/features/pre-commit:2": { - "version": "2.0.18", - "resolved": "ghcr.io/devcontainers-extra/features/pre-commit@sha256:6e0bb2ce80caca1d94f44dab5d0653d88a1c00984e590adb7c6bce012d0ade6e", - "integrity": "sha256:6e0bb2ce80caca1d94f44dab5d0653d88a1c00984e590adb7c6bce012d0ade6e" - }, - "ghcr.io/devcontainers/features/common-utils": { - "version": "2.5.4", - "resolved": "ghcr.io/devcontainers/features/common-utils@sha256:00fd45550f578d9d515044d9e2226e908dbc3d7aa6fcb9dee4d8bdb60be114cf", - "integrity": "sha256:00fd45550f578d9d515044d9e2226e908dbc3d7aa6fcb9dee4d8bdb60be114cf" - }, "ghcr.io/devcontainers/features/rust": { "version": "1.5.0", "resolved": "ghcr.io/devcontainers/features/rust@sha256:0c55e65f2e3df736e478f26ee4d5ed41bae6b54dac1318c443e31444c8ed283c", diff --git a/src/s-core-devcontainer/.devcontainer/devcontainer.json b/src/s-core-devcontainer/.devcontainer/devcontainer.json index 93380d1..2c67ce1 100644 --- a/src/s-core-devcontainer/.devcontainer/devcontainer.json +++ b/src/s-core-devcontainer/.devcontainer/devcontainer.json @@ -1,26 +1,6 @@ { - "build": { - // Installs latest version from the Distribution - "dockerfile": "./Dockerfile", - "context": ".", - "args": { - "HTTP_PROXY": "${localEnv:HTTP_PROXY}", - "HTTPS_PROXY": "${localEnv:HTTPS_PROXY}", - "http_proxy": "${localEnv:http_proxy}", - "https_proxy": "${localEnv:https_proxy}", - "NO_PROXY": "${localEnv:NO_PROXY}", - "no_proxy": "${localEnv:no_proxy}" - } - }, + "image": "ghcr.io/eclipse-score/buildcontainer:local-amd64", "features": { - "ghcr.io/devcontainers/features/common-utils": { - // Installs latest version from the Distribution - "installZsh": "false", - "username": "vscode", - "userUid": "1000", - "userGid": "1000", - "upgradePackages": "false" // WARNING: do *not* enable; this would include packages also from other features, which may have been pinned to a specific version - }, "ghcr.io/devcontainers-community/features/llvm": { // Full semantic version pinning does not work with this feature. // In case we want this, the feature needs to be replaced with a custom installation script. @@ -37,17 +17,14 @@ "rustfmt" ] }, - "./s-core-local": {}, - "./bazel-feature": {} + "./s-core-local": {} }, "overrideFeatureInstallOrder": [ // this order makes it more convenient to develop the local features, since they will be installed last // which means changes to it will be applied without needing to rebuild all other features - "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers-community/features/llvm", "ghcr.io/devcontainers/features/rust", - "./s-core-local", - "./bazel-feature" + "./s-core-local" ], "remoteUser": "vscode", "customizations": { diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/devcontainer-feature.json b/src/s-core-devcontainer/.devcontainer/s-core-local/devcontainer-feature.json index c6e0d0f..96522f9 100644 --- a/src/s-core-devcontainer/.devcontainer/s-core-local/devcontainer-feature.json +++ b/src/s-core-devcontainer/.devcontainer/s-core-local/devcontainer-feature.json @@ -3,15 +3,9 @@ "id": "s-core-local", "version": "1.0.0", "description": "Tools which are not available as already existing development container feature", - "dependsOn": { - "ghcr.io/devcontainers-extra/features/pre-commit:2": { - "version": "4.5.1" - } - }, "onCreateCommand": "/devcontainer/features/s-core-local/on_create_command.sh", "postCreateCommand": { - "Setup persistent bash history": "bash /devcontainer/features/s-core-local/setup_command_history.sh", - "Enable pre-commit hooks": "bash /devcontainer/features/s-core-local/enable_pre_commit_hooks.sh" + "Setup persistent bash history": "bash /devcontainer/features/s-core-local/setup_command_history.sh" }, "mounts": [ { diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh b/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh index 13820db..0d97087 100755 --- a/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh +++ b/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh @@ -30,7 +30,7 @@ rm -f "${COPY_TARGET}/devcontainer-features.env" "${COPY_TARGET}/devcontainer-fe DEBIAN_FRONTEND=noninteractive # Read tool versions + metadata into environment variables -. /devcontainer/features/s-core-local/versions.sh /devcontainer/features/s-core-local/versions.yaml +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/s-core-local/versions.yaml ARCHITECTURE=$(dpkg --print-architecture) KERNEL=$(uname -s) @@ -48,37 +48,11 @@ apt-get install apt-transport-https -y # static code anylysis for shell scripts apt-get install -y shellcheck="${shellcheck_version}*" -# GraphViz -# The Ubuntu Noble package of GraphViz -apt-get install -y graphviz="${graphviz_version}*" - -# Protobuf compiler, via APT (needed by FEO) -apt-get install -y protobuf-compiler="${protobuf_compiler_version}*" - # Git and Git LFS, via APT apt-get install -y git apt-get install -y git-lfs apt-get install -y gh -# Python, via APT -apt-get install -y "python${python_version}" python3-pip python3-venv -# The following packages correspond to the list of packages installed by the -# devcontainer feature "python" (cf. https://github.com/devcontainers/features/tree/main/src/python ) -apt-get install -y flake8 python3-autopep8 black python3-yapf mypy pydocstyle pycodestyle bandit pipenv virtualenv python3-pytest pylint - -# OpenJDK 21, via APT -# Set JAVA_HOME environment variable system-wide, since some tools rely on it (e.g., Bazel's rules_java) -apt-get install -y ca-certificates-java openjdk-21-jdk-headless="${openjdk_21_version}*" -JAVA_HOME="$(dirname $(dirname $(realpath $(command -v javac))))" -export JAVA_HOME -echo -e "JAVA_HOME=${JAVA_HOME}\nexport JAVA_HOME" > /etc/profile.d/java_home.sh - -# qemu-system-arm -apt-get install -y --no-install-recommends --fix-broken qemu-system-arm="${qemu_system_arm_version}*" - -# sshpass -apt-get install -y sshpass="${sshpass_version}*" - # additional developer tools apt-get install -y gdb="${gdb_version}*" diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/tests/test_default.sh b/src/s-core-devcontainer/.devcontainer/s-core-local/tests/test_default.sh index f911892..15ccb3c 100755 --- a/src/s-core-devcontainer/.devcontainer/s-core-local/tests/test_default.sh +++ b/src/s-core-devcontainer/.devcontainer/s-core-local/tests/test_default.sh @@ -20,40 +20,15 @@ ARCHITECTURE=$(dpkg --print-architecture) KERNEL=$(uname -s) # Read tool versions + metadata into environment variables -. /devcontainer/features/s-core-local/versions.sh /devcontainer/features/s-core-local/versions.yaml - -# pre-commit, it is available via $PATH in login shells, but not in non-login shells -check "validate pre-commit is working and has the correct version" bash -c "${PIPX_BIN_DIR}/pre-commit --version | grep '4.5.1'" +. /devcontainer/features/s-core-build/versions.sh /devcontainer/features/s-core-local/versions.yaml # Common tooling check "validate shellcheck is working and has the correct version" bash -c "shellcheck --version | grep '${shellcheck_version}'" -# For an unknown reason, dot -V reports on Ubuntu Noble a version 2.43.0, while the package has a different version. -# Hence, we have to work around that. -check "validate graphviz is working" bash -c "dot -V" -check "validate graphviz has the correct version" bash -c "dpkg -s graphviz | grep 'Version: ${graphviz_version}'" - -# Other build-related tools -check "validate protoc is working and has the correct version" bash -c "protoc --version | grep 'libprotoc ${protobuf_compiler_version}'" - # Common tooling check "validate git is working and has the correct version" bash -c "git --version | grep '${git_version}'" check "validate git-lfs is working and has the correct version" bash -c "git lfs version | grep '${git_lfs_version}'" -# Python-related tools (a selected sub-set; others may be added later) -check "validate python3 is working and has the correct version" bash -c "python3 --version | grep '${python_version}'" -check "validate pip3 is working and has the correct version" bash -c "pip3 --version | grep '${python_version}'" -check "validate black is working and has the correct version" bash -c "black --version | grep '${python_version}'" -# cannot grep versions as they do not match the Python version -check "validate virtualenv is working" bash -c "virtualenv --version" -check "validate flake8 is working" bash -c "flake8 --version" -check "validate pytest is working" bash -c "pytest --version" -check "validate pylint is working" bash -c "pylint --version" - -# OpenJDK -check "validate java is working and has the correct version" bash -c "java -version 2>&1 | grep '${openjdk_21_version}'" -check "validate JAVA_HOME is set correctly" bash -c "echo ${JAVA_HOME} | xargs readlink -f | grep \"java-21-openjdk\"" - # additional developer tools check "validate gdb is working and has the correct version" bash -c "gdb --version | grep '${gdb_version}'" check "validate gh is working and has the correct version" bash -c "gh --version | grep '${gh_version}'" @@ -61,7 +36,3 @@ check "validate valgrind is working and has the correct version" bash -c "valgri if [ "${ARCHITECTURE}" = "amd64" ] || { [ "${ARCHITECTURE}" = "arm64" ] && [ "${KERNEL}" = "Darwin" ]; }; then check "validate codeql is working and has the correct version" bash -c "codeql --version | grep '${codeql_version}'" fi - -# Qemu target-related tools -check "validate qemu-system-aarch64 is working and has the correct version" bash -c "qemu-system-aarch64 --version | grep '${qemu_system_arm_version}'" -check "validate sshpass is working and has the correct version" bash -c "sshpass -V | grep '${sshpass_version}'" diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/versions.yaml b/src/s-core-devcontainer/.devcontainer/s-core-local/versions.yaml index 044c6c4..c525721 100644 --- a/src/s-core-devcontainer/.devcontainer/s-core-local/versions.yaml +++ b/src/s-core-devcontainer/.devcontainer/s-core-local/versions.yaml @@ -13,18 +13,6 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -graphviz: - version: 2.42.2 - -protobuf_compiler: - version: 3.21.12 - -qemu_system_arm: - version: 1:8.2.2 - -sshpass: - version: 1.09 - gdb: version: 15.0.50 @@ -34,15 +22,9 @@ git: git_lfs: version: 3.4.1 -python: - version: '3.12' - gh: version: 2.45.0 -openjdk_21: - version: 21.0.10 - shellcheck: version: 0.9.0 diff --git a/src/s-core-devcontainer/test-project/test.sh b/src/s-core-devcontainer/test-project/test.sh index c590310..b2016d9 100755 --- a/src/s-core-devcontainer/test-project/test.sh +++ b/src/s-core-devcontainer/test-project/test.sh @@ -34,8 +34,5 @@ check "validate rust-analyzer is working and has the correct version" bash -c "r # Tests from the local s-core-local feature source /devcontainer/features/s-core-local/tests/test_default.sh -# Tests from the local bazel feature -source /devcontainer/features/bazel/tests/test_default.sh - # Report result reportResults