From fffcc329d8524ab035301fb38c6ecccd72549f44 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Sat, 3 Oct 2026 21:04:26 +0200 Subject: [PATCH 1/2] feat: Add GitHub workflow for integration tests on multiple Java versions --- .github/workflows/ci-java.yml | 6 +++ .github/workflows/integration-test.yml | 60 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 .github/workflows/integration-test.yml diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index b1cf12b2a4..dacd390020 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -41,3 +41,9 @@ jobs: name: Check style with Spotless run: ./mvnw spotless:check -Pintegration-test + integration-test: + needs: build + uses: ./.github/workflows/integration-test.yml + with: + java-versions: '[8, 11, 17, 21]' + diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml new file mode 100644 index 0000000000..34915a7fe7 --- /dev/null +++ b/.github/workflows/integration-test.yml @@ -0,0 +1,60 @@ +name: Integration Tests + +on: + workflow_dispatch: + inputs: + java-versions: + description: 'JSON array of Java versions to test' + required: false + default: '[8, 11, 17, 21]' + workflow_call: + inputs: + java-versions: + description: 'JSON array of Java versions to test' + type: string + required: false + default: '[8, 11, 17, 21]' + schedule: + - cron: '0 3 * * 1-5' + +jobs: + integration-test: + runs-on: ubuntu-latest + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + java: ${{ fromJSON(inputs.java-versions || '[8, 11, 17, 21]') }} + name: Java ${{ matrix.java }} integration test + steps: + - uses: actions/checkout@v7 + - name: Prepare multi-module build + run: git submodule update --init --recursive + # Every job gets its own Cloud Foundry on KinD, so the matrix can run in parallel. + # The action deploys the kind-deployment ref given in `ref`, so keep both on the same commit. + - name: Set up Cloud Foundry + uses: cloudfoundry/kind-deployment/.github/actions/setup-cf@8f0e3947abd716fc73d4787ce83e74ab73fb86a9 + with: + ref: 8f0e3947abd716fc73d4787ce83e74ab73fb86a9 + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: liberica + java-version: ${{ matrix.java }} + - name: Cache Maven packages + uses: actions/cache@v6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Run integration tests + # CC_ADMIN_PASSWORD and UAA_ADMIN_SECRET are exported by setup-cf + env: + TEST_APIHOST: api.cf.127-0-0-1.nip.io + TEST_ADMIN_USERNAME: ccadmin + TEST_ADMIN_PASSWORD: ${{ env.CC_ADMIN_PASSWORD }} + TEST_ADMIN_CLIENTID: admin + TEST_ADMIN_CLIENTSECRET: ${{ env.UAA_ADMIN_SECRET }} + TEST_SKIPSSLVALIDATION: 'true' + TEST_QUOTAS_ROUTES_RESERVEDPORTS: '50' + run: ./mvnw -B -Pintegration-test test -Dgpg.skip From 4984b4af4420be35575ed30bdf4f8d85c34d2a72 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Tue, 6 Oct 2026 08:06:58 +0200 Subject: [PATCH 2/2] feat: Update the GH workflow --- .github/scripts/resolve-capi-version.sh | 48 +++++++++++++++++++++++++ .github/workflows/ci-java.yml | 2 +- .github/workflows/integration-test.yml | 29 ++++++++++++--- 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100755 .github/scripts/resolve-capi-version.sh diff --git a/.github/scripts/resolve-capi-version.sh b/.github/scripts/resolve-capi-version.sh new file mode 100755 index 0000000000..bfaaba2818 --- /dev/null +++ b/.github/scripts/resolve-capi-version.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Prints the newest capi-release version whose CC API (v2) version equals SUPPORTED_API_VERSION +# from CloudFoundryClient.java. Needs only git and curl, no GitHub API and so no token. +# +# A capi-release tag pins cloud_controller_ng as a submodule, and that repo records its v2 API +# version in config/version_v2. The release notes aren't reliable for this. The v2 version only +# grows with the tags, so a binary search over the sorted tags is enough. +set -euo pipefail + +source_file="$(dirname "$0")/../../cloudfoundry-client/src/main/java/org/cloudfoundry/client/CloudFoundryClient.java" +target="$(sed -n 's/.*String SUPPORTED_API_VERSION = "\([0-9.]*\)";.*/\1/p' "$source_file")" +[ -n "$target" ] || { echo "SUPPORTED_API_VERSION not found in $source_file" >&2; exit 1; } + +workdir="$(mktemp -d)" +trap 'rm -rf "$workdir"' EXIT +# commits and trees only, which is all it takes to read the submodule commit of a tag +git clone --quiet --bare --filter=blob:none https://github.com/cloudfoundry/capi-release.git "$workdir/capi-release" + +mapfile -t tags < <(git -C "$workdir/capi-release" tag -l | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V) + +v2_version() { + local sha + sha="$(git -C "$workdir/capi-release" ls-tree "$1" src/cloud_controller_ng | awk '{print $3}')" + curl -fsSL "https://raw.githubusercontent.com/cloudfoundry/cloud_controller_ng/$sha/config/version_v2" | tr -d '[:space:]' +} + +# highest index whose v2 version is <= target +lo=0 +hi=$((${#tags[@]} - 1)) +found=-1 +while [ "$lo" -le "$hi" ]; do + mid=$(((lo + hi) / 2)) + v="$(v2_version "${tags[$mid]}")" + if [ "$(printf '%s\n%s\n' "$v" "$target" | sort -V | tail -1)" = "$target" ]; then + found=$mid + lo=$((mid + 1)) + else + hi=$((mid - 1)) + fi +done + +if [ "$found" -lt 0 ] || [ "$(v2_version "${tags[$found]}")" != "$target" ]; then + echo "No capi-release found for CC API version $target" >&2 + exit 1 +fi + +echo "CC API $target -> capi-release ${tags[$found]}" >&2 +echo "${tags[$found]}" diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index dacd390020..3d05984149 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -45,5 +45,5 @@ jobs: needs: build uses: ./.github/workflows/integration-test.yml with: - java-versions: '[8, 11, 17, 21]' + java-versions: '[21]' diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 34915a7fe7..116d12ee12 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -7,6 +7,14 @@ on: description: 'JSON array of Java versions to test' required: false default: '[8, 11, 17, 21]' + preview: + description: 'Deploy the latest cf-deployment versions instead of the default ones' + type: boolean + required: false + default: false + schedule: + # preview run: latest versions (including CAPI) on the latest JDK only + - cron: '0 3 * * 1-5' workflow_call: inputs: java-versions: @@ -14,8 +22,11 @@ on: type: string required: false default: '[8, 11, 17, 21]' - schedule: - - cron: '0 3 * * 1-5' + preview: + description: 'Deploy the latest cf-deployment versions instead of the default ones' + type: boolean + required: false + default: false jobs: integration-test: @@ -24,18 +35,28 @@ jobs: strategy: fail-fast: false matrix: - java: ${{ fromJSON(inputs.java-versions || '[8, 11, 17, 21]') }} - name: Java ${{ matrix.java }} integration test + java: ${{ fromJSON(inputs.java-versions || (github.event_name == 'schedule' && '[21]' || '[8, 11, 17, 21]')) }} + name: Java ${{ matrix.java }} integration test${{ (inputs.preview || github.event_name == 'schedule') && ' (preview)' || '' }} steps: - uses: actions/checkout@v7 - name: Prepare multi-module build run: git submodule update --init --recursive + # Validation runs deploy the capi-release that matches SUPPORTED_API_VERSION. Preview runs + # (scheduled, or started by hand with `preview`) keep the latest versions. + - name: Resolve CAPI version + id: capi + if: ${{ !(inputs.preview || github.event_name == 'schedule') }} + run: echo "version=$(.github/scripts/resolve-capi-version.sh)" >> "$GITHUB_OUTPUT" # Every job gets its own Cloud Foundry on KinD, so the matrix can run in parallel. # The action deploys the kind-deployment ref given in `ref`, so keep both on the same commit. - name: Set up Cloud Foundry uses: cloudfoundry/kind-deployment/.github/actions/setup-cf@8f0e3947abd716fc73d4787ce83e74ab73fb86a9 with: ref: 8f0e3947abd716fc73d4787ce83e74ab73fb86a9 + use-latest-versions: ${{ (inputs.preview || github.event_name == 'schedule') }} + github-token: ${{ github.token }} + # TODO: needs the action commit that includes kind-deployment#514, older ones ignore it + capi-version: ${{ steps.capi.outputs.version }} - name: Set up Java uses: actions/setup-java@v5 with: