diff --git a/.github/workflows/build-test-and-publish.yml b/.github/workflows/build-test-and-publish.yml index 070153f..fdf1de2 100644 --- a/.github/workflows/build-test-and-publish.yml +++ b/.github/workflows/build-test-and-publish.yml @@ -19,6 +19,15 @@ on: - '["amd64"]' - '["arm64"]' - '["amd64", "arm64"]' + java_version: + description: 'The Java versions to build' + required: true + default: '["17", "21", "25"]' + options: + - '["17"]' + - '["21"]' + - '["25"]' + - '["17", "21", "25"]' version: description: 'The version to build (e.g. 1.1.0)' required: false @@ -40,6 +49,7 @@ jobs: matrix: DISTRO: ${{ fromJson(github.event.inputs.distribution || '["run", "tomcat"]') }} PLATFORM: ${{ fromJson(github.event.inputs.platform || '["amd64", "arm64"]') }} + JAVA_VERSION: ${{ fromJson(github.event.inputs.java_version || '["17", "21", "25"]') }} steps: - name: Checkout uses: actions/checkout@v4 @@ -65,6 +75,7 @@ jobs: env: DISTRO: ${{ matrix.DISTRO }} PLATFORM: ${{ matrix.PLATFORM }} + JAVA_VERSION: ${{ matrix.JAVA_VERSION }} VERSION: ${{ github.event.inputs.version || '' }} SNAPSHOT: ${{ github.event.inputs.snapshot || '' }} IMAGE_REPO_OPERATON: ${{ vars.IMAGE_REPO_OPERATON }} @@ -76,6 +87,7 @@ jobs: env: DISTRO: ${{ matrix.DISTRO }} PLATFORM: ${{ matrix.PLATFORM }} + JAVA_VERSION: ${{ matrix.JAVA_VERSION }} VERSION: ${{ github.event.inputs.version || '' }} SNAPSHOT: ${{ github.event.inputs.snapshot || '' }} IMAGE_REPO_OPERATON: ${{ vars.IMAGE_REPO_OPERATON }} @@ -87,6 +99,7 @@ jobs: strategy: matrix: DISTRO: [run, tomcat, wildfly] + JAVA_VERSION: ${{ fromJson(github.event.inputs.java_version || '["17", "21", "25"]') }} steps: - name: Checkout uses: actions/checkout@v4 @@ -111,6 +124,7 @@ jobs: env: DISTRO: ${{ matrix.DISTRO }} PLATFORMS: linux/arm64,linux/amd64 + JAVA_VERSION: ${{ matrix.JAVA_VERSION }} VERSION: ${{ github.event.inputs.version || '' }} SNAPSHOT: ${{ github.event.inputs.snapshot || '' }} SNAPSHOT_TAG_BRANCH: ${{ github.event.release.target_commitish || github.ref_name }} diff --git a/.github/workflows/pull-request-build-test.yml b/.github/workflows/pull-request-build-test.yml index 5dac012..a05d5f2 100644 --- a/.github/workflows/pull-request-build-test.yml +++ b/.github/workflows/pull-request-build-test.yml @@ -11,9 +11,11 @@ jobs: matrix: DISTRO: ["run", "tomcat", "wildfly"] PLATFORM: ["amd64"] + JAVA_VERSION: ["17", "21", "25"] env: DISTRO: ${{ matrix.DISTRO }} PLATFORM: ${{ matrix.PLATFORM }} + JAVA_VERSION: ${{ matrix.JAVA_VERSION }} VERSION: 1.1.0 SNAPSHOT: true IMAGE_REPO_OPERATON: operaton/operaton diff --git a/Dockerfile b/Dockerfile index 3d261af..0cb2390 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,8 @@ FROM alpine:3.23 ARG VERSION=7.23.0 ARG DISTRO +# Alpine package suffix, e.g. 17, 21 or 25 +ARG JAVA_VERSION=17 ENV OPERATON_DB_VERSION=${VERSION} ENV DB_DRIVER= @@ -46,7 +48,7 @@ ENV WAIT_FOR_TIMEOUT=30 ENV TZ=UTC ENV DEBUG=false ENV JAVA_OPTS="" -ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk ENV JMX_PROMETHEUS=false ENV JMX_PROMETHEUS_CONF=/operaton/javaagent/prometheus-jmx.yml ENV JMX_PROMETHEUS_PORT=9404 @@ -59,7 +61,7 @@ RUN apk add -q --no-cache \ bash \ ca-certificates \ curl \ - openjdk17-jre-headless \ + openjdk${JAVA_VERSION}-jre-headless \ tzdata \ tini \ xmlstarlet \ diff --git a/README.md b/README.md index ba55bb5..4ca3d8f 100644 --- a/README.md +++ b/README.md @@ -142,8 +142,13 @@ Operaton. This currently means: - Operaton 1.0 or later will be based on OpenJDK 17. -While all the OpenJDK versions supported by Operaton will work with the exceptions specified above, -we will not provide ready to use images for them. +Images for OpenJDK 21 and 25 carry a `-jdk21` or `-jdk25` tag suffix (e.g. `1.1.0-jdk21`). +OpenJDK 17 images are also tagged with `-jdk17`, identical to the tag without suffix. +To build one yourself, pass the build argument `JAVA_VERSION` (default `17`): + +``` +docker build --build-arg DISTRO=run --build-arg JAVA_VERSION=21 -t operaton/operaton:jdk21 . +``` #### Java options diff --git a/pipeline.sh b/pipeline.sh index e5052f2..0125c31 100755 --- a/pipeline.sh +++ b/pipeline.sh @@ -12,6 +12,20 @@ else VERSION_ARGUMENT="--build-arg VERSION=${VERSION}" fi +JAVA_VERSION=${JAVA_VERSION:-17} +if [ "$JAVA_VERSION" == "17" ]; then + JAVA_TAG_SUFFIX="" +else + JAVA_TAG_SUFFIX="-jdk${JAVA_VERSION}" +fi + +# The gha cache only works inside GitHub Actions +if [ "$GITHUB_ACTIONS" == "true" ]; then + CACHE_ARGUMENTS="--cache-to type=gha,scope=$GITHUB_REF_NAME-$DISTRO-jdk$JAVA_VERSION-image --cache-from type=gha,scope=$GITHUB_REF_NAME-$DISTRO-jdk$JAVA_VERSION-image" +else + CACHE_ARGUMENTS="" +fi + if [ -z "$IMAGE_REPO_OPERATON" ]; then IMAGE_REPO_OPERATON="operaton/operaton" fi @@ -23,21 +37,21 @@ if [ -z "$IMAGE_REPO_WILDFLY" ]; then fi if [ "$DISTRO" == "run" ]; then - IMAGE_NAME=${IMAGE_REPO_OPERATON}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_OPERATON}:${PLATFORM}${JAVA_TAG_SUFFIX} elif [ "$DISTRO" == "tomcat" ]; then - IMAGE_NAME=${IMAGE_REPO_TOMCAT}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_TOMCAT}:${PLATFORM}${JAVA_TAG_SUFFIX} elif [ "$DISTRO" == "wildfly" ]; then - IMAGE_NAME=${IMAGE_REPO_WILDFLY}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_WILDFLY}:${PLATFORM}${JAVA_TAG_SUFFIX} fi docker buildx build . \ -t "${IMAGE_NAME}" \ --platform linux/${PLATFORM} \ --build-arg DISTRO=${DISTRO} \ + --build-arg JAVA_VERSION=${JAVA_VERSION} \ ${VERSION_ARGUMENT} \ ${SNAPSHOT_ARGUMENT} \ - --cache-to type=gha,scope="$GITHUB_REF_NAME-$DISTRO-image" \ - --cache-from type=gha,scope="$GITHUB_REF_NAME-$DISTRO-image" \ + ${CACHE_ARGUMENTS} \ --load docker inspect "${IMAGE_NAME}" | grep "Architecture" -A2 diff --git a/release.sh b/release.sh index 7aa3983..f5d7049 100755 --- a/release.sh +++ b/release.sh @@ -15,6 +15,13 @@ fi PLATFORMS=${PLATFORMS:-linux/amd64} +JAVA_VERSION=${JAVA_VERSION:-17} +if [ "$JAVA_VERSION" == "17" ]; then + JAVA_TAG_SUFFIX="" +else + JAVA_TAG_SUFFIX="-jdk${JAVA_VERSION}" +fi + if [ "$DISTRO" == "run" ]; then IMAGE=${IMAGE_REPO_OPERATON} elif [ "$DISTRO" == "tomcat" ]; then @@ -24,14 +31,22 @@ elif [ "$DISTRO" == "wildfly" ]; then fi function build_and_push { - local tags=("$@") + local tag tags=() + for tag in "$@"; do + tags+=("${tag}${JAVA_TAG_SUFFIX}") + # The default Java version is also published with an explicit suffix + if [ "$JAVA_VERSION" == "17" ]; then + tags+=("${tag}-jdk17") + fi + done printf -v tag_arguments -- "--tag $IMAGE:%s " "${tags[@]}" docker buildx build . \ $tag_arguments \ --build-arg DISTRO=${DISTRO} \ --build-arg VERSION=${VERSION} \ --build-arg SNAPSHOT=${SNAPSHOT} \ - --cache-from type=gha,scope="$GITHUB_REF_NAME-$DISTRO-image" \ + --build-arg JAVA_VERSION=${JAVA_VERSION} \ + --cache-from type=gha,scope="$GITHUB_REF_NAME-$DISTRO-jdk$JAVA_VERSION-image" \ --platform $PLATFORMS \ --push @@ -58,12 +73,14 @@ function get_highest_release_version { highest_version="${candidate}" fi done < <( + # Only tags of the same Java version count, printed without their suffix printf '%s' "${response}" | python3 -c 'import json, re, sys data = json.load(sys.stdin) for result in data.get("results", []): name = result.get("name", "") - if re.fullmatch(r"\d+\.\d+\.\d+", name): - print(name)' + match = re.fullmatch(r"(\d+\.\d+\.\d+)" + re.escape(sys.argv[1]), name) + if match: + print(match.group(1))' "${JAVA_TAG_SUFFIX}" ) next_url="$( @@ -96,7 +113,7 @@ function should_tag_latest { } # check whether the image for distro was already released and exit in that case -if [ $(docker manifest inspect $IMAGE:${VERSION} > /dev/null ; echo $?) == '0' ]; then +if [ $(docker manifest inspect $IMAGE:${VERSION}${JAVA_TAG_SUFFIX} > /dev/null ; echo $?) == '0' ]; then echo "Not pushing already released image" exit 0 fi diff --git a/test/test-release-tags.sh b/test/test-release-tags.sh index 9fabf65..f315b27 100755 --- a/test/test-release-tags.sh +++ b/test/test-release-tags.sh @@ -37,6 +37,7 @@ run_release() { local snapshot_tag_branch="$1" local version="$2" local snapshot="$3" + local java_version="${4:-17}" : > "${MOCK_DOCKER_CALLS}" : > "${MOCK_CURL_CALLS}" PATH="${MOCK_DIR}:${PATH}" \ @@ -47,6 +48,7 @@ run_release() { DISTRO="run" \ VERSION="${version}" \ SNAPSHOT="${snapshot}" \ + JAVA_VERSION="${java_version}" \ SNAPSHOT_TAG_BRANCH="${snapshot_tag_branch}" \ DOCKERHUB_USERNAME="user" \ DOCKERHUB_PASSWORD="pass" \ @@ -94,6 +96,8 @@ run_release "main" "2.1.1" "false" grep -q -- "--tag operaton/operaton:2.1.1" "${MOCK_DOCKER_CALLS}" grep -q -- "--tag operaton/operaton:latest" "${MOCK_DOCKER_CALLS}" grep -q -- "page=2" "${MOCK_CURL_CALLS}" +grep -q -- "--tag operaton/operaton:2.1.1-jdk17 " "${MOCK_DOCKER_CALLS}" +grep -q -- "--tag operaton/operaton:latest-jdk17 " "${MOCK_DOCKER_CALLS}" run_release "main" "2.1.1-M1" "false" grep -q -- "--tag operaton/operaton:2.1.1-M1" "${MOCK_DOCKER_CALLS}" @@ -105,3 +109,26 @@ if [ -s "${MOCK_CURL_CALLS}" ]; then echo "curl must not be called for pre-releases" exit 1 fi + +run_release "main" "2.1.1" "false" "21" +grep -q -- "--tag operaton/operaton:2.1.1-jdk21" "${MOCK_DOCKER_CALLS}" +grep -q -- "--tag operaton/operaton:latest-jdk21" "${MOCK_DOCKER_CALLS}" +grep -q -- "--build-arg JAVA_VERSION=21" "${MOCK_DOCKER_CALLS}" +if grep -q -- "jdk17" "${MOCK_DOCKER_CALLS}"; then + echo "jdk17 tags must only be added for Java 17" + exit 1 +fi +grep -q -- "manifest inspect operaton/operaton:2.1.1-jdk21" "${MOCK_DOCKER_CALLS}" + +# Java 17 job already pushed 2.2.0, the Java 21 job must still get latest-jdk21 +cat > "${MOCK_CURL_PAGE_1}" <<'JSON' +{"results":[{"name":"2.2.0"},{"name":"2.2.0-jdk17"},{"name":"2.1.0-jdk21"},{"name":"3.0.0-jdk25"}],"next":null} +JSON +run_release "main" "2.2.0" "false" "21" +grep -q -- "--tag operaton/operaton:latest-jdk21" "${MOCK_DOCKER_CALLS}" + +run_release "main" "2.0.5" "false" "21" +if grep -q -- "--tag operaton/operaton:latest-jdk21" "${MOCK_DOCKER_CALLS}"; then + echo "latest-jdk21 must not be added when a higher jdk21 release already exists" + exit 1 +fi diff --git a/test/test.sh b/test/test.sh index 82acc59..809de38 100755 --- a/test/test.sh +++ b/test/test.sh @@ -10,12 +10,19 @@ if [ -z "$IMAGE_REPO_WILDFLY" ]; then IMAGE_REPO_WILDFLY="operaton/operaton-wildfly" fi +JAVA_VERSION=${JAVA_VERSION:-17} +if [ "$JAVA_VERSION" == "17" ]; then + JAVA_TAG_SUFFIX="" +else + JAVA_TAG_SUFFIX="-jdk${JAVA_VERSION}" +fi + if [ "$DISTRO" == "run" ]; then - IMAGE_NAME=${IMAGE_REPO_OPERATON}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_OPERATON}:${PLATFORM}${JAVA_TAG_SUFFIX} elif [ "$DISTRO" == "tomcat" ]; then - IMAGE_NAME=${IMAGE_REPO_TOMCAT}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_TOMCAT}:${PLATFORM}${JAVA_TAG_SUFFIX} elif [ "$DISTRO" == "wildfly" ]; then - IMAGE_NAME=${IMAGE_REPO_WILDFLY}:${PLATFORM} + IMAGE_NAME=${IMAGE_REPO_WILDFLY}:${PLATFORM}${JAVA_TAG_SUFFIX} fi export IMAGE_NAME