From 0bb0463f0fb5e0d17d1015c4ed20f9b06d071904 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 6 May 2026 15:56:49 +0000 Subject: [PATCH 1/6] ci: Test devcontainer image with repos I am always afraid that devcontainer internal tests do not catch everything. With these tests it is assured that bazel build and test for selected repos and revisions works and stays working. --- .github/workflows/ci.yaml | 4 +++ scripts/test_external_repo.sh | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100755 scripts/test_external_repo.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9df46a6..586d062 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,6 +71,10 @@ jobs: # Test ./scripts/test.sh + # Test external repository + ./scripts/test_external_repo.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" + ./scripts/test_external_repo.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" + # Optionally: Publish # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. # Instead, we use the publish script which pushes the correct container (residing in src/s-core-devcontainer). diff --git a/scripts/test_external_repo.sh b/scripts/test_external_repo.sh new file mode 100755 index 0000000..f169252 --- /dev/null +++ b/scripts/test_external_repo.sh @@ -0,0 +1,60 @@ +#!/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-License-Identifier: Apache-2.0 +# ******************************************************************************* + +set -euxo pipefail + +# Usage: test-external-repo.sh [revision] [devcontainer-image] +# Parameters: +# repo-url : Git URL of the external repository +# revision : Git branch/tag/commit (default: main) + +REPO_URL="${1:?Repository URL is required}" +REVISION="${2:-main}" + +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}" + +. "${SCRIPT_DIR}/functions.sh" +set_dockerfile_name + +devcontainer up \ + --id-label "${ID_LABEL}" \ + --workspace-folder "${PROJECT_DIR}/src/${IMAGE}/" \ + --remove-existing-container + +# Extract repo name from URL +REPO_NAME=$(basename "${REPO_URL}" .git) +REPO_WORKSPACE="/tmp/${REPO_NAME}" + +echo "(*) Cloning repository..." +# --revision not supported by older git versions, so we clone first and then checkout the revision +# devcontainer exec --id-label "${ID_LABEL}" git clone --depth 1 --revision "${REVISION}" "${REPO_URL}" "${REPO_WORKSPACE}" +devcontainer exec --id-label "${ID_LABEL}" git clone "${REPO_URL}" "${REPO_WORKSPACE}" +devcontainer exec --id-label "${ID_LABEL}" git -C "${REPO_WORKSPACE}" checkout "${REVISION}" + +# Run build and test with Bazel using docker exec +echo "(*) Running Bazel build in devcontainer..." +devcontainer exec --id-label="${ID_LABEL}" /bin/sh -c "set -e && cd \"${REPO_WORKSPACE}\" && bazel build //..." + +echo "(*) Running Bazel test in devcontainer..." +devcontainer exec --id-label="${ID_LABEL}" /bin/sh -c "set -e && cd \"${REPO_WORKSPACE}\" && bazel test //..." + +echo "(*) Bazel build and test completed successfully for ${REPO_NAME}" From 2c68e27fceb086617e725be633ae2c2493e39179 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 6 May 2026 16:15:54 +0000 Subject: [PATCH 2/6] skip external repo test for ARM64 --- .github/workflows/ci.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 586d062..9406127 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,9 +71,11 @@ jobs: # Test ./scripts/test.sh - # Test external repository - ./scripts/test_external_repo.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" - ./scripts/test_external_repo.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" + # Test external repository, arm64 is skipped because not all bazel dependencies are available for arm64 + if [ "${{ matrix.os }}" = "amd64" ] && ( [ "${{ github.event_name }}" != "pull_request" ] || echo "${{ toJSON(github.event.pull_request.labels) }}" | grep -q "test-external-repos" ); then + ./scripts/test_external_repo.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" + ./scripts/test_external_repo.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" + fi # Optionally: Publish # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. From a120f9b89dd5ade9a77a5b8ec116e3f9d92bfd26 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 6 May 2026 16:25:48 +0000 Subject: [PATCH 3/6] trigger workflow after label added --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9406127..cd56328 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,6 +14,7 @@ name: Validate DevContainer description: This workflow is checking that updates do not break stuff. If on main branch, publish to "latest" tag. on: pull_request: + -types: [opened, synchronize, reopened, labeled] push: branches: - main @@ -72,6 +73,7 @@ jobs: ./scripts/test.sh # Test external repository, arm64 is skipped because not all bazel dependencies are available for arm64 + # By default this is skipped in pull requests, unless the label "test-external-repos" is added if [ "${{ matrix.os }}" = "amd64" ] && ( [ "${{ github.event_name }}" != "pull_request" ] || echo "${{ toJSON(github.event.pull_request.labels) }}" | grep -q "test-external-repos" ); then ./scripts/test_external_repo.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" ./scripts/test_external_repo.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" From c403a7d3973587b30430830c2e0829074da73354 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Thu, 7 May 2026 09:54:04 +0000 Subject: [PATCH 4/6] rename test_external_repos to test_consumer --- .github/workflows/ci.yaml | 10 +++++----- scripts/{test_external_repo.sh => test_consumer.sh} | 8 ++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) rename scripts/{test_external_repo.sh => test_consumer.sh} (87%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cd56328..9e6f0ed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -72,11 +72,11 @@ jobs: # Test ./scripts/test.sh - # Test external repository, arm64 is skipped because not all bazel dependencies are available for arm64 - # By default this is skipped in pull requests, unless the label "test-external-repos" is added - if [ "${{ matrix.os }}" = "amd64" ] && ( [ "${{ github.event_name }}" != "pull_request" ] || echo "${{ toJSON(github.event.pull_request.labels) }}" | grep -q "test-external-repos" ); then - ./scripts/test_external_repo.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" - ./scripts/test_external_repo.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" + # Test consumer repository, arm64 is skipped because not all bazel dependencies are available for arm64 + # By default this is skipped in pull requests, unless the label "test-consumer" is added + if [ "${{ matrix.os }}" = "amd64" ] && ( [ "${{ github.event_name }}" != "pull_request" ] || echo "${{ toJSON(github.event.pull_request.labels) }}" | grep -q "test-consumer" ); then + ./scripts/test_consumer.sh "https://github.com/eclipse-score/inc_someip_gateway.git" "14a733a1f3d5f6fa76ac13365d57c8df30b62a86" + ./scripts/test_consumer.sh "https://github.com/eclipse-score/score.git" "7cbb86d54dced80e33a6405bc92f8abe62200ad4" fi # Optionally: Publish diff --git a/scripts/test_external_repo.sh b/scripts/test_consumer.sh similarity index 87% rename from scripts/test_external_repo.sh rename to scripts/test_consumer.sh index f169252..7006ea2 100755 --- a/scripts/test_external_repo.sh +++ b/scripts/test_consumer.sh @@ -15,9 +15,13 @@ set -euxo pipefail -# Usage: test-external-repo.sh [revision] [devcontainer-image] +# Usage: test_consumer.sh [revision] [devcontainer-image] +# Tests that a consumer repository can be built and tested using the devcontainer. +# It is checked that these commands work without errors: +# - bazel build //... +# - bazel test //... # Parameters: -# repo-url : Git URL of the external repository +# repo-url : Git URL of the consumer repository # revision : Git branch/tag/commit (default: main) REPO_URL="${1:?Repository URL is required}" From 9e363b749d9a9b52bad7717689ea744e283fed17 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Thu, 7 May 2026 10:27:59 +0000 Subject: [PATCH 5/6] Some CI documentation --- README.md | 6 +++++- docs/README.md | 11 ----------- docs/ci.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 docs/ci.md diff --git a/README.md b/README.md index a06ae29..3584f0c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 This repository contains the common [development container](https://containers.dev) for [Eclipse S-CORE](https://github.com/eclipse-score). It contains all tools required to develop (modify, build, ...) Eclipse S-CORE. All tool version are well-defined, and all tools are pre-configured to work as expected for Eclipse S-CORE development. -The container is [pre-built](https://containers.dev/guide/prebuild) in GitHub Actions as part of this repository, tested, published, and ready for use. +The container is [pre-built](https://containers.dev/guide/prebuild) in GitHub Actions as part of this repository, [tested, published](./docs/ci.md), and ready for use. Using the pre-built container in an Eclipse S-CORE repository is described in the [Usage](#usage) section. @@ -312,6 +312,10 @@ The Visual Studio Code instance related to the targeted S-CORE module will now a If not, press Ctrl + Shift + p and run from there "Dev Containers: Rebuilt Container Without Cache". Do so, and you have a running instance of `S-CORE DevContainer` related to the targeted S-CORE module. +### Consumer tests + +To enable consumer tests in the pull request, read the [ci.md](./docs/ci.md) document. + ### Version Pinning The `S-CORE DevContainer` pins feature and tool versions. diff --git a/docs/README.md b/docs/README.md index bb91971..20f8a09 100644 --- a/docs/README.md +++ b/docs/README.md @@ -98,14 +98,3 @@ It strengthens the supply chain by pinning versions and hashes, sourcing feature Pre-built images have a higer availability than the set of all tools which are installed (one download from a location controlled by S-CORE vs. many downloads from "everywhere"). Pre-built images can be easily archived anywhere, e.g. for reproducibility of builds in real production use-cases. It also enforces a clear separation of concerns: general tooling is delivered through reusable features, S-CORE–specific logic lives in a dedicated feature, and image composition plus publishing are centralized. - -## Release Automation - -Releases are cut automatically once per week from `main`, but only if commits were added since the latest `v..` tag. -The scheduled workflow creates the git tag and GitHub release, and the existing tag-triggered release workflow then builds, tests and publishes the matching container image. - -The next semantic version is derived from commit messages since the previous release: - -* breaking changes (`!` in the conventional commit header or `BREAKING CHANGE:` in the body) increment the major version -* `feat` commits increment the minor version -* every other commit increments the patch version so maintenance-only weeks still publish a new immutable image diff --git a/docs/ci.md b/docs/ci.md new file mode 100644 index 0000000..fe01f91 --- /dev/null +++ b/docs/ci.md @@ -0,0 +1,51 @@ + + +# Continuous Integration + +The CI workflow (`.github/workflows/ci.yaml`) validates the devcontainer on every pull request, push to `main`, and merge group event. + +Builds run on two architectures in parallel: + +- **AMD64** +- **ARM64** + +The S-CORE devcontainer is build using this repo's `.devcontainer` to ensure consistent behavior at developer and CI. + +## Merge Job (main only) + +Each architecture is built and tested individually. +After both architecture builds succeed, a merge job creates a multi-arch manifest and pushes it to `ghcr.io`. +It would have been ideal if the multi-arch image could have been build in one go, but that did not work. + +## Consumer Tests + +At consumer tests, repos using the devcontainer are build and tested using the newly created devcontainer image. +This is done to detect breaking changes before releasing a new devcontainer image and to reduce manual testing efforts. + +By default these are not run in pull requests, but in the merge queue and pushes to main to save time. +If these shall be run in the pull request add the **`test-consumer`** label to a pull request. + +## Release Automation + +Releases are cut automatically once per week from `main`, but only if commits were added since the latest `v..` tag. +The scheduled workflow creates the git tag and GitHub release, and the existing tag-triggered release workflow then builds, tests and publishes the matching container image. + +The next semantic version is derived from commit messages since the previous release: + +* breaking changes (`!` in the conventional commit header or `BREAKING CHANGE:` in the body) increment the major version +* `feat` commits increment the minor version +* every other commit increments the patch version so maintenance-only weeks still publish a new immutable image From 76781f69479dead7ed74d0c150662af490143c22 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Thu, 7 May 2026 11:09:06 +0000 Subject: [PATCH 6/6] WTF adding labels does not retrigger the workflow --- docs/ci.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ci.md b/docs/ci.md index fe01f91..29a5615 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -39,6 +39,10 @@ This is done to detect breaking changes before releasing a new devcontainer imag By default these are not run in pull requests, but in the merge queue and pushes to main to save time. If these shall be run in the pull request add the **`test-consumer`** label to a pull request. +> [!NOTE] +> Github may not trigger a new workflow run after the label is set. +> You need to push another commit for that. + ## Release Automation Releases are cut automatically once per week from `main`, but only if commits were added since the latest `v..` tag.