From 51245b6dd016c23940c8391f2b39ee82a4801ec5 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 14:04:59 +0100 Subject: [PATCH 01/14] bump cds-version --- pom.xml | 4 ++-- samples/bookshop/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 37f407c2..aef20252 100644 --- a/pom.xml +++ b/pom.xml @@ -70,12 +70,12 @@ - 3.10.5 + 4.5.1 8.9.8 - 4.4.0 + 4.5.1 9.3.2 true diff --git a/samples/bookshop/pom.xml b/samples/bookshop/pom.xml index f1860681..a88bd76c 100644 --- a/samples/bookshop/pom.xml +++ b/samples/bookshop/pom.xml @@ -17,7 +17,7 @@ 17 - 4.4.2 + 4.5.1 3.5.7 UTF-8 From e9a4bc650e59228e38a8e4815ab6e76615cb0941 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 14:08:54 +0100 Subject: [PATCH 02/14] bump cdsdk-version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index aef20252..c2ba3ea8 100644 --- a/pom.xml +++ b/pom.xml @@ -72,11 +72,11 @@ 4.5.1 - 8.9.8 + 9.5.0 4.5.1 - 9.3.2 + 9.5.0 true From d5f44372b0e202e31e34cd148969f50fe3e19b53 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 14:10:33 +0100 Subject: [PATCH 03/14] bump spring-boot-version --- integration-tests/pom.xml | 2 +- samples/bookshop/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index c3df8bc7..541c4336 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-dependencies - 3.5.7 + 3.5.8 pom import diff --git a/samples/bookshop/pom.xml b/samples/bookshop/pom.xml index a88bd76c..9065ae82 100644 --- a/samples/bookshop/pom.xml +++ b/samples/bookshop/pom.xml @@ -18,7 +18,7 @@ 17 4.5.1 - 3.5.7 + 3.5.8 UTF-8 From ba9f778b232a2bcd93e38dd622c5b4aa227cba1f Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 14:37:05 +0100 Subject: [PATCH 04/14] updated tests for more leniency --- ...aRequestValidationWithTestHandlerTest.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java index 8807bc41..93a18343 100644 --- a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java +++ b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java @@ -18,11 +18,15 @@ import java.util.concurrent.TimeUnit; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.test.context.ActiveProfiles; @ActiveProfiles(Profiles.TEST_HANDLER_ENABLED) class DraftOdataRequestValidationWithTestHandlerTest extends DraftOdataRequestValidationBase { + private static final Logger logger = LoggerFactory.getLogger(DraftOdataRequestValidationWithTestHandlerTest.class); + @Test void serviceHandlerIsNotEmpty() { assertThat(serviceHandler).isNotNull(); @@ -171,8 +175,20 @@ protected void verifyTwoCreateAndRevertedDeleteEvents() { private void awaitNumberOfExpectedEvents(int expectedEvents) { Awaitility.await() - .atMost(20, TimeUnit.SECONDS) - .until(() -> serviceHandler.getEventContext().size() == expectedEvents); + .atMost(30, TimeUnit.SECONDS) + .pollDelay(1, TimeUnit.SECONDS) + .until(() -> { + var eventCalls = serviceHandler.getEventContext().size(); + logger.info( + "Waiting for expected size '{}' in handler context, was '{}'", + expectedEvents, + eventCalls); + var numberMatch = eventCalls >= expectedEvents; + if (!numberMatch) { + serviceHandler.getEventContext().forEach(event -> logger.info("Event: {}", event)); + } + return numberMatch; + }); } private void verifyCreateEventFound(List createEvents, String newContent) { From 2b9bdbd8e69a27e27ee8ef1a831172b30052c438 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 14:38:22 +0100 Subject: [PATCH 05/14] formatting --- ...aRequestValidationWithTestHandlerTest.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java index 93a18343..c2bd887a 100644 --- a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java +++ b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java @@ -25,7 +25,8 @@ @ActiveProfiles(Profiles.TEST_HANDLER_ENABLED) class DraftOdataRequestValidationWithTestHandlerTest extends DraftOdataRequestValidationBase { - private static final Logger logger = LoggerFactory.getLogger(DraftOdataRequestValidationWithTestHandlerTest.class); + private static final Logger logger = + LoggerFactory.getLogger(DraftOdataRequestValidationWithTestHandlerTest.class); @Test void serviceHandlerIsNotEmpty() { @@ -177,18 +178,19 @@ private void awaitNumberOfExpectedEvents(int expectedEvents) { Awaitility.await() .atMost(30, TimeUnit.SECONDS) .pollDelay(1, TimeUnit.SECONDS) - .until(() -> { - var eventCalls = serviceHandler.getEventContext().size(); - logger.info( - "Waiting for expected size '{}' in handler context, was '{}'", - expectedEvents, - eventCalls); - var numberMatch = eventCalls >= expectedEvents; - if (!numberMatch) { - serviceHandler.getEventContext().forEach(event -> logger.info("Event: {}", event)); - } - return numberMatch; - }); + .until( + () -> { + var eventCalls = serviceHandler.getEventContext().size(); + logger.info( + "Waiting for expected size '{}' in handler context, was '{}'", + expectedEvents, + eventCalls); + var numberMatch = eventCalls >= expectedEvents; + if (!numberMatch) { + serviceHandler.getEventContext().forEach(event -> logger.info("Event: {}", event)); + } + return numberMatch; + }); } private void verifyCreateEventFound(List createEvents, String newContent) { From e7351c756b7cb8d0263d645e1c8d6e6b9e6f539f Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 15:00:06 +0100 Subject: [PATCH 06/14] update pipeline form ore consistency --- .github/workflows/ci.yml | 175 ++++++++++++++++-- .../workflows/main-build-and-deploy-oss.yml | 6 +- .mvn/maven.config | 16 ++ README.md | 48 ++--- doc/CONTRIBUTING.md | 111 +++++++++++ doc/Design.md | 42 +++-- pom.xml | 26 ++- 7 files changed, 361 insertions(+), 63 deletions(-) create mode 100644 .mvn/maven.config diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 358888ce..132885e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ name: CI env: - MAVEN_VERSION: '3.6.3' + MAVEN_VERSION: '3.9.9' # Cloud storage environment variables (available to all jobs that need them) AWS_S3_HOST: ${{ secrets.AWS_S3_HOST }} AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} @@ -27,27 +27,91 @@ on: pull_request: jobs: - build: - name: Build + # Run code quality checks once + quality-checks: + name: Quality Checks (Spotless) runs-on: ubuntu-latest - strategy: - matrix: - java-version: [ 17, 21 ] steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 + + - name: Set up Java 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: + maven-version: ${{ env.MAVEN_VERSION }} - name: Spotless check run: mvn spotless:check -Dspotless.check.skip=false + # Build once with Java 17, upload artifacts + build: + name: Build & Mutation Testing + runs-on: ubuntu-latest + needs: quality-checks + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build uses: ./.github/actions/build + with: + java-version: 17 + maven-version: ${{ env.MAVEN_VERSION }} + mutation-testing: 'true' + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: maven-build-artifacts + path: | + ~/.m2/repository/com/sap/cds/ + cds-feature-attachments/target/ + storage-targets/cds-feature-attachments-fs/target/ + storage-targets/cds-feature-attachments-oss/target/ + retention-days: 1 + + # Test with Java 17 and 21 + test-java-versions: + name: Test Java ${{ matrix.java-version }} + runs-on: ubuntu-latest + needs: build + strategy: + matrix: + java-version: [ 17, 21 ] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java ${{ matrix.java-version }} + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java-version }} + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: maven-version: ${{ env.MAVEN_VERSION }} - integration-tests: - name: Integration Tests (Java ${{ matrix.java-version }}) + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: maven-build-artifacts + + - name: Run tests + run: mvn test -ntp -B -pl cds-feature-attachments,storage-targets/cds-feature-attachments-fs,storage-targets/cds-feature-attachments-oss + + # Integration tests with current CAP version (Java 17 & 21) + integration-tests-current: + name: Integration Tests - Current CAP (Java ${{ matrix.java-version }}) runs-on: ubuntu-latest needs: build strategy: @@ -55,20 +119,99 @@ jobs: java-version: [ 17, 21 ] steps: - name: Checkout - uses: actions/checkout@v6 - - name: Integration Tests - uses: ./.github/actions/integration-tests + uses: actions/checkout@v4 + + - name: Set up Java ${{ matrix.java-version }} + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java-version }} + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: + maven-version: ${{ env.MAVEN_VERSION }} + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: maven-build-artifacts + + - name: Integration Tests with current CAP Java version + run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml + + # Integration tests with latest CAP version (Java 17 only) + integration-tests-latest: + name: Integration Tests - Latest CAP (Java 17) + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: maven-version: ${{ env.MAVEN_VERSION }} + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: maven-build-artifacts + + - name: Integration Tests with latest CAP Java version + run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml -P latest-test-version + + # Integration tests for Object Store Service (Java 17 only) + integration-tests-oss: + name: Integration Tests - OSS (Java 17) + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: + maven-version: ${{ env.MAVEN_VERSION }} + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: maven-build-artifacts + + - name: Integration Tests for Object Store Service + run: mvn clean verify -ntp -B -Pintegration-tests-oss + sonarqube-scan: name: SonarQube Scan runs-on: ubuntu-latest - needs: build + needs: [test-java-versions] steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: maven-build-artifacts + - name: SonarQube Scan uses: ./.github/actions/scan-with-sonar with: @@ -80,11 +223,11 @@ jobs: scan: name: Blackduck Scan runs-on: ubuntu-latest - needs: [integration-tests] + needs: [integration-tests-current, integration-tests-latest, integration-tests-oss] timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 - name: Scan uses: ./.github/actions/scan-with-blackduck diff --git a/.github/workflows/main-build-and-deploy-oss.yml b/.github/workflows/main-build-and-deploy-oss.yml index e85602c4..448e4dc6 100644 --- a/.github/workflows/main-build-and-deploy-oss.yml +++ b/.github/workflows/main-build-and-deploy-oss.yml @@ -2,7 +2,7 @@ name: Deploy to Maven Central env: JAVA_VERSION: '17' - MAVEN_VERSION: '3.6.3' + MAVEN_VERSION: '3.9.9' on: release: @@ -15,7 +15,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 - name: Scan With Black Duck uses: ./.github/actions/scan-with-blackduck @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 with: token: ${{ secrets.GH_TOKEN }} diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 00000000..e9ea0a8a --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1,16 @@ +# Maven configuration for consistent behavior across local and CI environments +# This file is automatically applied to all Maven commands + +# Batch mode: Run in non-interactive mode +-B + +# Suppress transfer progress +-ntp + +# Use UTF-8 encoding +-Dproject.build.sourceEncoding=UTF-8 +-Dproject.reporting.outputEncoding=UTF-8 + +# Enable Spotless formatting checks by default +# Developers can skip with: mvn -Dspotless.check.skip=true ... +-Dspotless.check.skip=false diff --git a/README.md b/README.md index 51e1677f..b8dccea2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Java Build with Maven](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build.yml/badge.svg)](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build.yml) [![Deploy new Version with Maven](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build.yml/badge.svg?branch=main)](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build.yml) [![REUSE status](https://api.reuse.software/badge/github.com/cap-java/cds-feature-attachments)](https://api.reuse.software/info/github.com/cap-java/cds-feature-attachments) +[![CI](https://github.com/cap-java/cds-feature-attachments/actions/workflows/ci.yml/badge.svg)](https://github.com/cap-java/cds-feature-attachments/actions/workflows/ci.yml) [![Deploy to Maven Central](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build-and-deploy-oss.yml/badge.svg)](https://github.com/cap-java/cds-feature-attachments/actions/workflows/main-build-and-deploy-oss.yml) [![REUSE status](https://api.reuse.software/badge/github.com/cap-java/cds-feature-attachments)](https://api.reuse.software/info/github.com/cap-java/cds-feature-attachments) # Attachments Plugin for SAP Cloud Application Programming Model (CAP) @@ -12,28 +12,30 @@ It supports the [AWS, Azure, and Google object stores](storage-targets/cds-featu -* [Quick Start](#quick-start) -* [Usage](#usage) - * [MVN Setup](#mvn-setup) - * [Changes in the CDS Models and for the UI](#changes-in-the-cds-models-and-for-the-UI) - * [Try the Bookshop Sample](#try-the-bookshop-sample) - * [Storage Targets](#storage-targets) - * [Malware Scanner](#malware-scanner) - * [Outbox](#outbox) - * [Restore Endpoint](#restore-endpoint) - * [Motivation](#motivation) - * [HTTP Endpoint](#http-endpoint) - * [Security](#security) -* [Releases: Maven Central and Artifactory](#releases-maven-central-and-artifactory) -* [Minimum UI5 and CAP Java Version](#minimum-ui5-and-cap-java-version) -* [Architecture Overview](#architecture-overview) - * [Design](#design) - * [Multitenancy](#multitenancy) - * [Object Stores](#object-stores) - * [Model Texts](#model-texts) -* [Monitoring \& Logging](#monitoring--logging) -* [Support, Feedback, Contributing](#support-feedback-contributing) -* [References \& Links](#references--links) +- [Attachments Plugin for SAP Cloud Application Programming Model (CAP)](#attachments-plugin-for-sap-cloud-application-programming-model-cap) + - [Table of Contents](#table-of-contents) + - [Quick Start](#quick-start) + - [Usage](#usage) + - [MVN Setup](#mvn-setup) + - [Changes in the CDS Models and for the UI](#changes-in-the-cds-models-and-for-the-ui) + - [Try the Bookshop Sample](#try-the-bookshop-sample) + - [Storage Targets](#storage-targets) + - [Malware Scanner](#malware-scanner) + - [Outbox](#outbox) + - [Restore Endpoint](#restore-endpoint) + - [Motivation](#motivation) + - [HTTP Endpoint](#http-endpoint) + - [Security](#security) + - [Releases: Maven Central and Artifactory](#releases-maven-central-and-artifactory) + - [Minimum UI5 and CAP Java Version](#minimum-ui5-and-cap-java-version) + - [Architecture Overview](#architecture-overview) + - [Design](#design) + - [Multitenancy](#multitenancy) + - [Object Stores](#object-stores) + - [Model Texts](#model-texts) + - [Monitoring \& Logging](#monitoring--logging) + - [Support, Feedback, Contributing](#support-feedback-contributing) + - [References \& Links](#references--links) ## Quick Start diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 422f0d03..4513aa39 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -39,6 +39,117 @@ The following rule governs code contributions: the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/). +## Development Environment Setup + +### Prerequisites + +* **Java**: JDK 17 or 21 (SAPMachine, OpenJDK, or similar) +* **Maven**: 3.9.0 or higher (required for consistent build behavior with CI) +* **Git**: For version control + +### Local Build Configuration + +The project includes a `.mvn/maven.config` file that ensures consistent behavior between local development and CI: +- Batch mode (`-B`) +- Suppressed transfer progress (`-ntp`) +- UTF-8 encoding +- Spotless formatting checks enabled by default + +### Code Formatting + +The project uses [Spotless](https://github.com/diffplug/spotless) with Google Java Format style. + +**Important:** Spotless checks are now enabled by default to ensure code quality. Before committing: + +```bash +# Check formatting +mvn spotless:check + +# Apply formatting +mvn spotless:apply +``` + +To skip formatting checks temporarily during development: +```bash +mvn clean install -Dspotless.check.skip=true +``` + +### Running Tests Locally + +#### Without Cloud Storage Credentials + +If you don't have AWS/Azure/Google Cloud credentials configured, use the `local-testing` profile: + +```bash +mvn clean verify -P local-testing +``` + +This skips cloud storage integration tests and uses filesystem storage targets instead. + +#### With Cloud Storage Credentials + +To run the full test suite including cloud storage integration tests, set these environment variables: + +```bash +# AWS S3 +export AWS_S3_HOST= +export AWS_S3_BUCKET= +export AWS_S3_REGION= +export AWS_S3_ACCESS_KEY_ID= +export AWS_S3_SECRET_ACCESS_KEY= + +# Azure Blob Storage +export AZURE_CONTAINER_URI= +export AZURE_SAS_TOKEN= + +# Google Cloud Storage +export GS_BASE_64_ENCODED_PRIVATE_KEY_DATA= +export GS_BUCKET= +export GS_PROJECT_ID= + +# Then run all tests +mvn clean verify +``` + +#### Running Mutation Testing + +Mutation testing with pitest provides deep test quality analysis but is slower: + +```bash +mvn org.pitest:pitest-maven:mutationCoverage -f cds-feature-attachments/pom.xml +``` + +### Common Build Commands + +```bash +# Build and run unit tests +mvn clean install + +# Run integration tests with current CAP version +mvn clean verify -f ./integration-tests/pom.xml + +# Run integration tests with latest CAP version +mvn clean verify -f ./integration-tests/pom.xml -P latest-test-version + +# Run OSS integration tests +mvn clean verify -P integration-tests-oss + +# Skip tests completely +mvn clean install -DskipTests +``` + +### CI/CD Pipeline + +The project uses an optimized CI pipeline (`.github/workflows/ci.yml`) that: +- Runs quality checks (Spotless) once +- Builds with Java 17 and runs mutation testing +- Tests compiled artifacts against Java 17 & 21 +- Runs integration tests in parallel (current CAP version, latest CAP version, OSS) +- Performs SonarQube and BlackDuck security scans +- Deploys snapshots to Artifactory + +For details, see [Design.md](Design.md#github-actions). + ## Issues and Planning * We use GitHub issues to track bugs and enhancement requests. diff --git a/doc/Design.md b/doc/Design.md index 24d49c46..0225cc3a 100644 --- a/doc/Design.md +++ b/doc/Design.md @@ -90,34 +90,38 @@ In folder `.github/workflows` are the GitHub Actions defined. The following tabl | File Name | Description | |----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `pull-requests-build.yaml` | Build the project and run unit tests, integration tests and mutation tests for Java 17 and 21 for new pull requests. Each pull request need to have green runs from this workflow to be able to be merged. | -| `main-build.yaml` | Build the project and run unit tests, integration tests and mutation tests for Java 17 and 21 once commits are merged to the master to get an indicator if everything works with the main branch. | -| `main-build-and-deploy.yaml` | Creates a new version for main, builds the project, run all tests and deploy it to maven or artifactory. See also [Build and Deploy](#build-and-deploy) | -| `main-build-and-deploy-oss.yaml` | Creates a new version for main, builds the project, run all tests and deploy it to Maven Central. See also [Build and Deploy](#build-and-deploy) | +| `ci.yml` | Main CI pipeline that builds the project, runs quality checks, unit tests, integration tests, and mutation testing for Java 17 and 21. Runs on pull requests and pushes to main branch. | +| `main-build-and-deploy-oss.yml` | Creates a new version for main, builds the project, runs all tests and deploys it to Maven Central. See also [Build and Deploy](#build-and-deploy) | +| `codeql.yml` | Security scanning workflow using GitHub CodeQL for vulnerability detection | +| `issue.yml` | Auto-labels new issues for triage | +| `prevent-issue-labeling.yml` | Prevents manual application of the "New" label | -### Build Action +### CI Pipeline -The build step is implemented in action `.github/actions/build/action.yaml` which is used in the workflows: -"Pull Requests Build", "Main Build" and "Build and Deploy". -As the build action does not only run a build of the project, but also the mutations tests this action is used in all -the mentioned workflows. +The `ci.yml` workflow is an optimized CI pipeline that eliminates redundant builds and runs tests efficiently. The workflow consists of these jobs: -### Pull Requests Build +1. **Quality Checks**: Runs Spotless code formatting check once (Java 17) +2. **Build & Mutation Testing**: Builds the project once with Java 17 and runs mutation testing with pitest +3. **Test Java Versions**: Tests the built artifacts against Java 17 and 21 in parallel +4. **Integration Tests**: Runs three parallel integration test suites: + - Current CAP Java version (Java 17 & 21) + - Latest CAP Java version (Java 17 only) + - Object Store Service tests (Java 17 only) +5. **SonarQube Scan**: Code quality analysis (runs after unit tests complete) +6. **BlackDuck Scan**: Security scanning (runs after all integration tests) +7. **Deploy Snapshot**: Deploys snapshot versions to Artifactory (on main branch only) -The `pull-requests-build.yaml` starts a workflow to build the project and run all unit and Spring Boot tests for the -coding in the new branch including the changes in the pull request. +The pipeline uses artifact caching to avoid rebuilding dependencies multiple times, significantly reducing build time compared to the previous approach. #### Trigger -This workflow is triggered if a new pull request is created or updated in GitHub. - -### Main Build - -The `main-build.yaml` starts a workflow to build the project and run all unit and Spring Boot tests for the main branch. +This workflow is triggered when: +- A pull request is created or updated +- Code is pushed to the `main` branch -#### Trigger +### Build Action -This workflow is triggered if a new commit is pushed to the main branch. +The build step is implemented in action `.github/actions/build/action.yml` which handles the Maven build using SAP's project-piper-action. It optionally runs mutation testing with pitest. ### Build and Deploy diff --git a/pom.xml b/pom.xml index c2ba3ea8..dbf05b87 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 4.5.1 9.5.0 - true + false @@ -340,7 +340,7 @@ - 3.6.3 + 3.9.0 ${java.version} @@ -387,6 +387,28 @@ + + + local-testing + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + true + + + + + + + deploy-release From 50972c373ada0b64b3256cebbf17af02a5b4a1b4 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 15:10:49 +0100 Subject: [PATCH 07/14] repository wasn't stored --- .github/workflows/ci.yml | 42 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 132885e6..a119fa98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,12 +66,18 @@ jobs: maven-version: ${{ env.MAVEN_VERSION }} mutation-testing: 'true' - - name: Upload build artifacts + - name: Upload Maven local repository artifacts uses: actions/upload-artifact@v4 with: - name: maven-build-artifacts + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ + retention-days: 1 + + - name: Upload build targets + uses: actions/upload-artifact@v4 + with: + name: build-targets path: | - ~/.m2/repository/com/sap/cds/ cds-feature-attachments/target/ storage-targets/cds-feature-attachments-fs/target/ storage-targets/cds-feature-attachments-oss/target/ @@ -101,10 +107,11 @@ jobs: with: maven-version: ${{ env.MAVEN_VERSION }} - - name: Download build artifacts + - name: Download Maven repository uses: actions/download-artifact@v4 with: - name: maven-build-artifacts + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ - name: Run tests run: mvn test -ntp -B -pl cds-feature-attachments,storage-targets/cds-feature-attachments-fs,storage-targets/cds-feature-attachments-oss @@ -133,10 +140,11 @@ jobs: with: maven-version: ${{ env.MAVEN_VERSION }} - - name: Download build artifacts + - name: Download Maven repository uses: actions/download-artifact@v4 with: - name: maven-build-artifacts + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ - name: Integration Tests with current CAP Java version run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml @@ -162,10 +170,11 @@ jobs: with: maven-version: ${{ env.MAVEN_VERSION }} - - name: Download build artifacts + - name: Download Maven repository uses: actions/download-artifact@v4 with: - name: maven-build-artifacts + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ - name: Integration Tests with latest CAP Java version run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml -P latest-test-version @@ -191,10 +200,11 @@ jobs: with: maven-version: ${{ env.MAVEN_VERSION }} - - name: Download build artifacts + - name: Download Maven repository uses: actions/download-artifact@v4 with: - name: maven-build-artifacts + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ - name: Integration Tests for Object Store Service run: mvn clean verify -ntp -B -Pintegration-tests-oss @@ -207,10 +217,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Download build artifacts + - name: Download Maven repository + uses: actions/download-artifact@v4 + with: + name: maven-repository + path: ~/.m2/repository/com/sap/cds/ + + - name: Download build targets uses: actions/download-artifact@v4 with: - name: maven-build-artifacts + name: build-targets - name: SonarQube Scan uses: ./.github/actions/scan-with-sonar From 35eb11ab9b257b7ad15d6ad33eea16e84b267c60 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 15:23:13 +0100 Subject: [PATCH 08/14] removed integration-tests during build --- .github/workflows/ci.yml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a119fa98..db4637cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,12 +59,26 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Build - uses: ./.github/actions/build + - name: Set up Java 17 + uses: actions/setup-java@v4 with: java-version: 17 + distribution: sapmachine + cache: maven + + - name: Set up Maven ${{ env.MAVEN_VERSION }} + uses: stCarolas/setup-maven@v5 + with: maven-version: ${{ env.MAVEN_VERSION }} - mutation-testing: 'true' + + - name: Build and install artifacts (skip tests) + run: | + mvn clean install -DskipTests \ + -pl cds-feature-attachments,storage-targets/cds-feature-attachments-fs,storage-targets/cds-feature-attachments-oss \ + -am + + - name: Mutation Testing + run: mvn org.pitest:pitest-maven:mutationCoverage -f cds-feature-attachments/pom.xml - name: Upload Maven local repository artifacts uses: actions/upload-artifact@v4 From 9255996f08ada3ca6f6f03f7c89b624fecd031fc Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 15:57:13 +0100 Subject: [PATCH 09/14] adapt await --- .../DraftOdataRequestValidationWithTestHandlerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java index c2bd887a..25624583 100644 --- a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java +++ b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java @@ -176,8 +176,9 @@ protected void verifyTwoCreateAndRevertedDeleteEvents() { private void awaitNumberOfExpectedEvents(int expectedEvents) { Awaitility.await() - .atMost(30, TimeUnit.SECONDS) + .atMost(60, TimeUnit.SECONDS) .pollDelay(1, TimeUnit.SECONDS) + .pollInterval(2, TimeUnit.SECONDS) .until( () -> { var eventCalls = serviceHandler.getEventContext().size(); From 0fd68a9bda854b3d88d04874e22a66ad4e61b6c2 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 16:10:23 +0100 Subject: [PATCH 10/14] update pipeline --- .github/workflows/ci.yml | 34 +------------ doc/Design.md | 103 +++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 84 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db4637cc..8dc5d0d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,7 +132,7 @@ jobs: # Integration tests with current CAP version (Java 17 & 21) integration-tests-current: - name: Integration Tests - Current CAP (Java ${{ matrix.java-version }}) + name: Integration Tests - CAP (Java ${{ matrix.java-version }}) runs-on: ubuntu-latest needs: build strategy: @@ -163,36 +163,6 @@ jobs: - name: Integration Tests with current CAP Java version run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml - # Integration tests with latest CAP version (Java 17 only) - integration-tests-latest: - name: Integration Tests - Latest CAP (Java 17) - runs-on: ubuntu-latest - needs: build - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Java 17 - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: sapmachine - cache: maven - - - name: Set up Maven ${{ env.MAVEN_VERSION }} - uses: stCarolas/setup-maven@v5 - with: - maven-version: ${{ env.MAVEN_VERSION }} - - - name: Download Maven repository - uses: actions/download-artifact@v4 - with: - name: maven-repository - path: ~/.m2/repository/com/sap/cds/ - - - name: Integration Tests with latest CAP Java version - run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml -P latest-test-version - # Integration tests for Object Store Service (Java 17 only) integration-tests-oss: name: Integration Tests - OSS (Java 17) @@ -253,7 +223,7 @@ jobs: scan: name: Blackduck Scan runs-on: ubuntu-latest - needs: [integration-tests-current, integration-tests-latest, integration-tests-oss] + needs: [integration-tests-current, integration-tests-oss] timeout-minutes: 15 steps: - name: Checkout diff --git a/doc/Design.md b/doc/Design.md index 0225cc3a..1913674f 100644 --- a/doc/Design.md +++ b/doc/Design.md @@ -3,56 +3,56 @@ ## Table of Contents -* [Links for Design, Processes and Readme](#links-for-design-processes-and-readme) -* [Folder Structure](#folder-structure) -* [GitHub Actions](#github-actions) - * [Build Action](#build-action) - * [Pull Requests Build](#pull-requests-build) - * [Trigger](#trigger) - * [Main Build](#main-build) - * [Trigger](#trigger-1) - * [Build and Deploy](#build-and-deploy) - * [Trigger](#trigger-2) - * [Repository for Deploy](#repository-for-deploy) - * [Update Version](#update-version) - * [Token for Version Update](#token-for-version-update) - * [BlackDuck](#blackduck) - * [Pull Requests](#pull-requests) - * [BlackDuck Links](#blackduck-links) - * [Secrets](#secrets) -* [Feature](#feature) - * [CDS Model](#cds-model) - * [ETag](#etag) - * [Usage of the CDS Model](#usage-of-the-cds-model) - * [Configuration](#configuration) - * [Handler](#handler) - * [Events](#events) - * [Draft Activate and Deep Updates](#draft-activate-and-deep-updates) - * [Content for new Draft](#content-for-new-draft) - * [Delete](#delete) - * [Draft Keys](#draft-keys) - * [Sibling Entity (Draft or Active)](#sibling-entity-draft-or-active) - * [Readonly Fields](#readonly-fields) - * [Optimistic Concurrency Control](#optimistic-concurrency-control) - * [Service](#service) - * [Service Interface](#service-interface) - * [Multi-Tenancy](#multi-tenancy) - * [Default Implementation](#default-implementation) - * [Internal Stored](#internal-stored) - * [Content ID](#content-id) - * [Malware Scan](#malware-scan) - * [Implementation](#implementation) - * [Read Data](#read-data) - * [Scan Content](#scan-content) - * [Store Scan Result](#store-scan-result) - * [Read Attachment calls Malware Scan](#read-attachment-calls-malware-scan) - * [Status](#status) - * [Texts](#texts) -* [Tests](#tests) - * [Unit Tests](#unit-tests) - * [Mutation Tests](#mutation-tests) - * [Integration Tests](#integration-tests) -* [Quality Tools](#quality-tools) +- [Implementation Details](#implementation-details) + - [Table of Contents](#table-of-contents) + - [Links for Design, Processes and Readme](#links-for-design-processes-and-readme) + - [Folder Structure](#folder-structure) + - [GitHub Actions](#github-actions) + - [CI Pipeline](#ci-pipeline) + - [Trigger](#trigger) + - [Build Action](#build-action) + - [Build and Deploy](#build-and-deploy) + - [Trigger](#trigger-1) + - [Repository for Deploy](#repository-for-deploy) + - [Update Version](#update-version) + - [Token for Version Update](#token-for-version-update) + - [BlackDuck](#blackduck) + - [Pull Requests](#pull-requests) + - [BlackDuck Links](#blackduck-links) + - [Secrets](#secrets) + - [Feature](#feature) + - [CDS Model](#cds-model) + - [ETag](#etag) + - [Usage of the CDS Model](#usage-of-the-cds-model) + - [Configuration](#configuration) + - [Handler](#handler) + - [Events](#events) + - [Draft Activate and Deep Updates](#draft-activate-and-deep-updates) + - [Content for new Draft](#content-for-new-draft) + - [Delete](#delete) + - [Draft Keys](#draft-keys) + - [Sibling Entity (Draft or Active)](#sibling-entity-draft-or-active) + - [Readonly Fields](#readonly-fields) + - [Optimistic Concurrency Control](#optimistic-concurrency-control) + - [Service](#service) + - [Service Interface](#service-interface) + - [Multi-Tenancy](#multi-tenancy) + - [Default Implementation](#default-implementation) + - [Internal Stored](#internal-stored) + - [Content ID](#content-id) + - [Malware Scan](#malware-scan) + - [Implementation](#implementation) + - [Read Data](#read-data) + - [Scan Content](#scan-content) + - [Store Scan Result](#store-scan-result) + - [Read Attachment calls Malware Scan](#read-attachment-calls-malware-scan) + - [Status](#status) + - [Texts](#texts) + - [Tests](#tests) + - [Unit Tests](#unit-tests) + - [Mutation Tests](#mutation-tests) + - [Integration Tests](#integration-tests) + - [Quality Tools](#quality-tools) ## Links for Design, Processes and Readme @@ -104,8 +104,7 @@ The `ci.yml` workflow is an optimized CI pipeline that eliminates redundant buil 2. **Build & Mutation Testing**: Builds the project once with Java 17 and runs mutation testing with pitest 3. **Test Java Versions**: Tests the built artifacts against Java 17 and 21 in parallel 4. **Integration Tests**: Runs three parallel integration test suites: - - Current CAP Java version (Java 17 & 21) - - Latest CAP Java version (Java 17 only) + - Java 17 & 21 - Object Store Service tests (Java 17 only) 5. **SonarQube Scan**: Code quality analysis (runs after unit tests complete) 6. **BlackDuck Scan**: Security scanning (runs after all integration tests) From ff3b5b46b54642566facfe790f120f3a9f9b89cf Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 17:51:51 +0100 Subject: [PATCH 11/14] simplify statement --- ...tOdataRequestValidationWithTestHandlerTest.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java index 25624583..0195ad93 100644 --- a/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java +++ b/integration-tests/srv/src/test/java/com/sap/cds/feature/attachments/integrationtests/draftservice/DraftOdataRequestValidationWithTestHandlerTest.java @@ -179,19 +179,7 @@ private void awaitNumberOfExpectedEvents(int expectedEvents) { .atMost(60, TimeUnit.SECONDS) .pollDelay(1, TimeUnit.SECONDS) .pollInterval(2, TimeUnit.SECONDS) - .until( - () -> { - var eventCalls = serviceHandler.getEventContext().size(); - logger.info( - "Waiting for expected size '{}' in handler context, was '{}'", - expectedEvents, - eventCalls); - var numberMatch = eventCalls >= expectedEvents; - if (!numberMatch) { - serviceHandler.getEventContext().forEach(event -> logger.info("Event: {}", event)); - } - return numberMatch; - }); + .until(() -> serviceHandler.getEventContext().size() >= expectedEvents); } private void verifyCreateEventFound(List createEvents, String newContent) { From efe8f1e06a0b1ff4e29e30db213b9fe806ef822c Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Sun, 14 Dec 2025 19:35:58 +0100 Subject: [PATCH 12/14] exclude sample --- .github/workflows/ci.yml | 4 ++-- .pipeline/config.yml | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8dc5d0d6..dfd48b4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,7 +161,7 @@ jobs: path: ~/.m2/repository/com/sap/cds/ - name: Integration Tests with current CAP Java version - run: mvn clean verify -ntp -B -f ./integration-tests/pom.xml + run: mvn verify -ntp -B -P integration-tests-current # Integration tests for Object Store Service (Java 17 only) integration-tests-oss: @@ -191,7 +191,7 @@ jobs: path: ~/.m2/repository/com/sap/cds/ - name: Integration Tests for Object Store Service - run: mvn clean verify -ntp -B -Pintegration-tests-oss + run: mvn verify -ntp -B -P integration-tests-oss sonarqube-scan: name: SonarQube Scan diff --git a/.pipeline/config.yml b/.pipeline/config.yml index 1fed9446..11a74c20 100644 --- a/.pipeline/config.yml +++ b/.pipeline/config.yml @@ -17,12 +17,14 @@ steps: versioningModel: "major-minor" detectTools: [ 'DETECTOR', 'BINARY_SCAN' ] installArtifacts: true + installArtifactsExcludes: + - samples/** repository: '/cap-java/cds-feature-attachments' verbose: true scanProperties: - --detect.included.detector.types=MAVEN - - --detect.excluded.directories='**/node_modules,**/*test*,**/localrepo,**/target/site,**/*-site.jar' - - --detect.maven.excluded.modules=integration-tests,integration-tests/db,integration-tests/srv + - --detect.excluded.directories='**/node_modules,**/*test*,**/localrepo,**/target/site,**/*-site.jar,**/samples' + - --detect.maven.excluded.modules=integration-tests,integration-tests/db,integration-tests/srv,samples/bookshop,samples/bookshop/srv - --detect.maven.build.command='-pl com.sap.cds:cds-feature-attachments' # https://www.project-piper.io/steps/detectExecuteScan/#dockerimage # If empty, Docker is not used and the command is executed directly on the Jenkins system. From 54f77a122ce79536bf1ae9316db47614d8a5658c Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Mon, 15 Dec 2025 11:17:28 +0100 Subject: [PATCH 13/14] remove token --- .github/workflows/ci.yml | 5 ++--- .github/workflows/main-build-and-deploy-oss.yml | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfd48b4a..8f4390a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,6 @@ env: GS_PROJECT_ID: ${{ secrets.GS_PROJECT_ID }} # Tokens SONARQ_TOKEN: ${{ secrets.SONARQ_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} BLACK_DUCK_TOKEN: ${{ secrets.BLACK_DUCK_TOKEN }} # Other DEPLOYMENT_USER: ${{ secrets.DEPLOYMENT_USER }} @@ -218,7 +217,7 @@ jobs: java-version: 17 maven-version: ${{ env.MAVEN_VERSION }} sonarq-token: ${{ env.SONARQ_TOKEN }} - github-token: ${{ env.GITHUB_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} scan: name: Blackduck Scan @@ -233,7 +232,7 @@ jobs: uses: ./.github/actions/scan-with-blackduck with: blackduck_token: ${{ env.BLACK_DUCK_TOKEN }} - github_token: ${{ env.GITHUB_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} maven-version: ${{ env.MAVEN_VERSION }} deploy-snapshot: diff --git a/.github/workflows/main-build-and-deploy-oss.yml b/.github/workflows/main-build-and-deploy-oss.yml index 448e4dc6..2bcc5246 100644 --- a/.github/workflows/main-build-and-deploy-oss.yml +++ b/.github/workflows/main-build-and-deploy-oss.yml @@ -30,8 +30,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - token: ${{ secrets.GH_TOKEN }} - name: Update version uses: ./.github/actions/newrelease From 54ba6a3accd6cb3bdb62c8e9a132a1106b6bd254 Mon Sep 17 00:00:00 2001 From: Marvin Lindner Date: Mon, 15 Dec 2025 11:29:24 +0100 Subject: [PATCH 14/14] parallelize jobs --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f4390a8..316c9df8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -195,7 +195,7 @@ jobs: sonarqube-scan: name: SonarQube Scan runs-on: ubuntu-latest - needs: [test-java-versions] + needs: [build] steps: - name: Checkout uses: actions/checkout@v4 @@ -222,7 +222,7 @@ jobs: scan: name: Blackduck Scan runs-on: ubuntu-latest - needs: [integration-tests-current, integration-tests-oss] + needs: [build] timeout-minutes: 15 steps: - name: Checkout