Skip to content

Build OS and EE image #1415

Build OS and EE image

Build OS and EE image #1415

name: Build OS and EE image
on:
workflow_dispatch:
inputs:
SOURCE_REF:
description: 'The hazelcast-docker branch to build the image from'
required: true
RELEASE_TYPE:
description: 'What should be built'
required: false
default: 'EE'
type: choice
options:
- ALL
- OSS
- EE
HZ_REVISION:
description: 'Commit id of Hazelcast snapshot jar'
required: false
ENVIRONMENT:
description: 'Environment to use'
required: true
type: environment
workflow_call:
inputs:
SOURCE_REF:
description: 'The hazelcast-docker branch to build the image from'
required: true
type: string
RELEASE_TYPE:
description: 'What should be built'
required: false
default: 'EE'
type: string
HZ_REVISION:
description: 'Commit id of Hazelcast snapshot jar'
required: false
type: string
ENVIRONMENT:
description: 'Environment to use'
required: true
type: string
jobs:
prepare:
environment: ${{ inputs.ENVIRONMENT }}
runs-on: ubuntu-latest
env:
RELEASE_TYPE: ${{ inputs.RELEASE_TYPE }}
outputs:
distribution-types: ${{ steps.distribution-type-matrix.outputs.matrix }}
HZ_VERSION: ${{ steps.get_hz_versions.outputs.HZ_VERSION }}
jdks: ${{ steps.jdks.outputs.jdks }}
default-jdk: ${{ steps.jdks.outputs.default-jdk }}
should-build-ee: ${{ steps.resolve-editions.outputs.should_build_ee }}
distribution-classifiers: ${{ steps.distribution-classifiers.outputs.classifiers }}
steps:
- name: Checkout Code
uses: actions/checkout@v6
with:
ref: ${{ inputs.SOURCE_REF }}
- id: resolve-editions
uses: hazelcast/docker-actions/resolve-editions@master
with:
release-type: ${{ inputs.RELEASE_TYPE }}
- name: Get HZ versions
id: get_hz_versions
uses: hazelcast/docker-actions/get-hz-versions@master
- name: Get supported JDKs
id: jdks
uses: hazelcast/docker-actions/get-supported-jdks@master
with:
HZ_VERSION: '${{ steps.get_hz_versions.outputs.HZ_VERSION }}'
- name: Compute distribution type matrix
id: distribution-type-matrix
run: |
# We expect at least _one_ output distribution type, otherwise will produce an empty array that will break GitHub matrixes
entries=()
if [ "${{ steps.resolve-editions.outputs.should_build_oss }}" = "true" ]; then
entries+=('{"label":"oss","docker-dir":"hazelcast-oss","image-name":"${{ vars.DOCKERHUB_OSS_IMAGE_NAME }}","distribution":"hazelcast"}')
fi
if [ "${{ steps.resolve-editions.outputs.should_build_ee }}" = "true" ]; then
entries+=('{"label":"ee","docker-dir":"hazelcast-enterprise","image-name":"${{ vars.DOCKERHUB_EE_IMAGE_NAME }}","distribution":"hazelcast-enterprise"}')
fi
json="[$(IFS=,; echo "${entries[*]}")]"
echo "matrix=$json" >> "${GITHUB_OUTPUT}"
- id: distribution-classifiers
uses: hazelcast/docker-actions/get-distribution-classifiers@master
push:
environment: ${{ inputs.ENVIRONMENT }}
runs-on: ubuntu-latest
needs:
- prepare
strategy:
matrix:
jdk: ${{ fromJSON(needs.prepare.outputs.jdks) }}
classifier: ${{ fromJSON(needs.prepare.outputs.distribution-classifiers) }}
distribution-type: ${{ fromJSON(needs.prepare.outputs.distribution-types) }}
env:
LOCAL_REGISTRY: localhost:5000
HZ_VERSION: ${{ needs.prepare.outputs.HZ_VERSION }}
TEST_CONTAINER_NAME: hazelcast-test
outputs:
is_latest_lts: ${{ steps.is_latest_lts.outputs.is_latest_lts }}
services:
registry:
image: registry:latest
ports:
- 5000:5000
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/checkout@v6
with:
ref: ${{ inputs.SOURCE_REF }}
path: source_path
sparse-checkout: ${{ matrix.distribution-type.docker-dir }}
- name: Get supported platforms
id: platforms
uses: hazelcast/docker-actions/get-supported-platforms@master
with:
dockerfile: ${{ matrix.distribution-type.docker-dir }}/Dockerfile
jdk: ${{ matrix.jdk }}
- name: Setup Docker
uses: ./.github/actions/setup-docker
with:
platforms: ${{ steps.platforms.outputs.platforms }}
- uses: s4u/maven-settings-action@894661b3ddae382f1ae8edbeab60987e08cf0788 # v4.0.0
with:
servers: |
[{
"id": "snapshot-internal",
"username": "${{ secrets.HZ_SNAPSHOT_INTERNAL_USERNAME }}",
"password": "${{ secrets.HZ_SNAPSHOT_INTERNAL_PASSWORD }}"
}]
- name: Download the distribution file
uses: hazelcast/docker-actions/download-hz-dist@master
id: download-hz-dist
with:
repo-vars-as-json: ${{ toJSON(vars) }}
distribution: ${{ matrix.distribution-type.distribution }}
hz_version: ${{ env.HZ_VERSION }}
classifier: ${{ matrix.classifier }}
packaging: "zip"
output_file: "source_path/${{ matrix.distribution-type.docker-dir }}/${{ matrix.distribution-type.distribution }}-distribution.zip"
- name: Check if latest EE LTS release
# OSS has no LTS releases
if: matrix.distribution-type.label == 'ee'
id: is_latest_lts
uses: hazelcast/docker-actions/check-if-latest-lts-release@master
with:
hz_version: ${{ env.HZ_VERSION }}
- name: Calculate tags
id: tags
run: |
. .github/scripts/get-tags-to-push.sh
LOCAL_IMAGE_NAME=${LOCAL_REGISTRY}/${{ matrix.distribution-type.image-name }}
echo "LOCAL_IMAGE_NAME=${LOCAL_IMAGE_NAME}" >> ${GITHUB_ENV}
if [[ "${HZ_VERSION}" =~ SNAPSHOT ]]; then
VERSIONS=("$HZ_VERSION")
if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
VERSIONS+=(latest-snapshot)
fi
TAGS_TO_PUSH=$(augment_with_classifier_tags "${VERSIONS[*]}" "${{ matrix.classifier }}" "${{ matrix.jdk }}" "${{ needs.prepare.outputs.default-jdk }}")
else
TAGS_TO_PUSH=$(get_tags_to_push "${HZ_VERSION}" "${{ matrix.classifier }}" "${{ matrix.jdk }}" "${{ needs.prepare.outputs.default-jdk }}" "${{ steps.is_latest_lts.outputs.is_latest_lts || 'false' }}")
fi
# Keep a reference to _a_ tag to get the image later on
echo "PRIMARY_TAG=${TAGS_TO_PUSH%% *}" >> ${GITHUB_ENV}
{
echo 'tags<<EOF'
for tag in ${TAGS_TO_PUSH[@]}; do
echo "${LOCAL_IMAGE_NAME}:${tag}"
done
echo 'EOF'
} >> "${GITHUB_OUTPUT}"
- name: Determine labels
id: labels
if: ${{ inputs.HZ_REVISION != '' }}
run: |
echo "label=hazelcast.revision=${{ inputs.HZ_REVISION }}" >> "$GITHUB_OUTPUT"
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: source_path/${{ matrix.distribution-type.docker-dir }}
labels: ${{ steps.labels.outputs.label }}
platforms: ${{ steps.platforms.outputs.platforms }}
push: true
tags: ${{ steps.tags.outputs.TAGS }}
build-args: |
JDK_VERSION=${{ matrix.jdk }}
- name: Delete the distribution file
run: |
# GitHub Actions have limited disk capacity
# The distribution is large and no longer required now the image has been built
rm "${{ steps.download-hz-dist.outputs.output_file }}"
- name: Run smoke test against image
timeout-minutes: 2
run: |
.github/scripts/simple-smoke-test.sh ${LOCAL_IMAGE_NAME}:${PRIMARY_TAG} "${TEST_CONTAINER_NAME}" ${{ matrix.distribution-type.label }} "${HZ_VERSION}" "${{ matrix.jdk }}"
env:
HZ_LICENSEKEY: ${{ matrix.distribution-type.label == 'ee' && secrets.HAZELCAST_ENTERPRISE_KEY || '' }}
- name: Get docker logs
if: ${{ always() }}
run: |
docker logs "${TEST_CONTAINER_NAME}" > "docker.log" || true
- name: Store docker logs as artifact
if: ${{ always() }}
uses: actions/upload-artifact@v5
with:
name: docker-logs-tag-image-push-${{ matrix.distribution-type.image-name }}-${{ env.PRIMARY_TAG }}
path: docker.log
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
with:
aws-access-key-id: ${{ secrets.AWS_DEV_INFRA_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_DEV_INFRA_SECRET_ACCESS_KEY }}
aws-region: 'us-east-1'
- name: Get Secrets
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
secret-ids: |
JFROG,JFROG/WRITE_DEV_ACCOUNT
parse-json-secrets: true
- name: Login to JFrog
uses: docker/login-action@v3
with:
registry: ${{ env.JFROG_URL }}
username: ${{ env.JFROG_USERNAME }}
password: ${{ env.JFROG_PASSWORD }}
- name: Push image to remote registry
run: |
if [[ "${{ matrix.distribution-type.label }}" == "oss" && "${HZ_VERSION}" =~ SNAPSHOT ]]; then
remote_registry=${{ env.JFROG_URL }}/docker/hazelcast
else
remote_registry=hazelcast
fi
# Skopeo expects HTTPS registry but local is HTTP
skopeo sync \
--all \
--src-tls-verify=false \
--src docker \
--dest docker \
${LOCAL_IMAGE_NAME} \
${remote_registry}
create-release:
needs:
- prepare
- push
if: ${{ !contains(needs.prepare.outputs.HZ_VERSION, 'SNAPSHOT') }}
runs-on: ubuntu-latest
steps:
- name: Create release
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
allowUpdates: true
tag: ${{ inputs.SOURCE_REF }}
readme:
needs:
- prepare
- push
if: ${{ !contains(needs.prepare.outputs.HZ_VERSION, 'SNAPSHOT') }}
uses: ./.github/workflows/update_readme.yml
with:
ENVIRONMENT: ${{ inputs.ENVIRONMENT }}
secrets: inherit
push-rhel:
name: Push RHEL image
needs:
- prepare
- push
# Restrict to non-SNAPSHOT for `live` environment only
if: needs.prepare.outputs.should-build-ee == 'true' && !(inputs.ENVIRONMENT == 'live' && contains(needs.prepare.outputs.HZ_VERSION, 'SNAPSHOT'))
uses: ./.github/workflows/tag_image_push_rhel.yml
with:
HZ_VERSION: ${{ needs.prepare.outputs.HZ_VERSION }}
JDKS: ${{ needs.prepare.outputs.jdks }}
IS_LATEST_LTS: ${{ needs.push.outputs.is_latest_lts }}
DEFAULT_JDK: ${{ needs.prepare.outputs.default-jdk }}
ENVIRONMENT: ${{ inputs.ENVIRONMENT }}
secrets: inherit
failure-notifications:
runs-on: ubuntu-latest
name: Failure notification
if: failure() && github.triggering_actor == 'devOpsHazelcast'
needs:
- push
- push-rhel
- readme
- create-release
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
with:
aws-access-key-id: ${{ secrets.AWS_DEV_INFRA_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_DEV_INFRA_SECRET_ACCESS_KEY }}
aws-region: 'us-east-1'
- name: Get Secrets
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
secret-ids: |
SLACK_WEBHOOK,SLACK/WEBHOOK_HAZELCAST_DOCKER_NOTIFICATIONS
parse-json-secrets: true
- name: Slack notification
uses: hazelcast/docker-actions/slack-notification@master
with:
slack-webhook-url: ${{ env.SLACK_WEBHOOK }}
status: failure