Generate and push jvm-runtime base image to Dockerhub #13
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Generate and push jvm-runtime base image to Dockerhub | |
on: | |
workflow_dispatch: | |
inputs: | |
sem-ver: | |
type: choice | |
description: Version Bump Type | |
required: false | |
default: none | |
options: | |
- existing | |
- patch | |
- minor | |
- major | |
- none | |
replace_prev: | |
description: Version Bump (Use only for updating existing version) | |
required: false | |
type: string | |
default: "" | |
jobs: | |
pre-validate-registry-sync: | |
uses: ./.github/workflows/validate-registry-sync.yml | |
secrets: inherit | |
build-jre-docker: | |
needs: pre-validate-registry-sync | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout branch | |
uses: actions/checkout@v3 | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v2 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
- name: Login to Docker Hub | |
uses: docker/login-action@v1 | |
with: | |
username: ${{ secrets.BAL_DOCKER_HUB_USERNAME }} | |
password: ${{ secrets.BAL_DOCKER_HUB_ACCESS_TOKEN }} | |
- name: Login to ACR | |
uses: docker/login-action@v2 | |
with: | |
registry: ${{ secrets.DOCKER_ACR_NAME }}.azurecr.io | |
username: ${{ secrets.DOCKER_ACR_USERNAME }} | |
password: ${{ secrets.DOCKER_ACR_PASSWORD }} | |
- name: Generate new tag | |
run: | | |
docker_hub_name="${{ secrets.DOCKER_REPO_NAME }}" | |
# Assume updating latest version | |
do_change_latest=1 | |
do_change_major=1 | |
do_change_major_minor=1 | |
formatted_tags=() | |
last_tags=() | |
i=1 | |
# Retrieve all tags from all pages of dockerhub | |
while : | |
do | |
retrieved_tags=( $(curl -s -S 'https://hub.docker.com/v2/repositories/'$docker_hub_name'/jvm-runtime/tags/?page='$i'&page_size=100' | jq '."results"[]["name"]') ) | |
last_tags=( ${last_tags[@]} ${retrieved_tags[@]} ) | |
if [ ${#retrieved_tags[@]} -lt 100 ] ; then | |
break | |
fi | |
i=$(($i +1)) | |
done | |
# Assign a last tag based retrieved set of tags | |
if [ -z "$last_tags" ]; then | |
last_tag="0.0.0" | |
else | |
IFS=$'\n' sorted_last_tags=($(sort <<<"${last_tags[*]}")); unset IFS # Sort and assign last tag next to 'latest' | |
last_tag=${sorted_last_tags[-2]} | |
# Retrieve tags in the format of (major.minor.patch) | |
for tag_i in ${sorted_last_tags[@]}; do | |
if [ $(($(echo "$tag_i" | awk -F. '{ print NF - 1 }') == 2)) -eq 1 ]; then | |
formatted_tags=( ${formatted_tags[@]} $tag_i ) | |
fi | |
done | |
fi | |
# Get major minor patch info from last tag | |
last_tag_array=( $(grep -Eo '[0-9]+' <<<"$last_tag") ) | |
major=${last_tag_array[0]} | |
minor=${last_tag_array[1]} | |
patch=${last_tag_array[2]} | |
# Modify existing tag (replace_prev --> tag needs to be modified) | |
if [ "${{ inputs.replace_prev }}" != "" ] && [ ${{ inputs.sem-ver }} = "existing" ]; then | |
curr_tag=${{ inputs.replace_prev }} | |
curr_tag_array=( $(grep -Eo '[0-9]+' <<<"$curr_tag") ) | |
major=${curr_tag_array[0]} | |
minor=${curr_tag_array[1]} | |
patch=${curr_tag_array[2]} | |
# Compare tags pairwise with curr_tag | |
for (( i=1; i<${#formatted_tags[@]}; i++ )) | |
do | |
prev_tag=${formatted_tags[$i-1]} | |
prev_tag_array=( $(grep -Eo '[0-9]+' <<<"$prev_tag") ) | |
prev_major=${prev_tag_array[0]} | |
prev_minor=${prev_tag_array[1]} | |
prev_patch=${prev_tag_array[2]} | |
next_tag=${formatted_tags[$i]} | |
next_tag_array=( $(grep -Eo '[0-9]+' <<<"$next_tag") ) | |
next_major=${next_tag_array[0]} | |
next_minor=${next_tag_array[1]} | |
next_patch=${next_tag_array[2]} | |
# Case 1 :- Replace existing patch (not a latest patch) | |
# ( 1.0.0 , 1.0.1 , 1.0.2 - update 1.0.0) | |
if [ $major -eq $prev_major ] && [ $minor -eq $prev_minor ] && | |
[ $patch -eq $prev_patch ] && [ $major -eq $next_major ] && | |
[ $minor -eq $next_minor ] && [ $patch -eq $(($next_patch - 1)) ] ; then | |
do_change_latest=0 | |
do_change_major=0 | |
do_change_major_minor=0 | |
# Case 2 :- Upgrade patch / Replace existing latest patch (Updatable minor) | |
# ( 1.0.0 , 1.0.1 , 1.0.2 , 1.1.0 - update 1.0.2,1.0.3) | |
elif [ $major -eq $prev_major ] && [ $minor -eq $prev_minor ] && | |
[ $(("$patch" >= "$prev_patch")) = 1 ] && [ $major -le $next_major ] && | |
[ $minor -lt $next_minor ]; then | |
do_change_latest=0 | |
do_change_major=0 | |
do_change_major_minor=1 | |
# Case 3 :- Upgrade patch / Replace existing latest patch (Updatable minor & major) | |
# ( 1.0.0 , 1.0.1 , 1.0.2 , 2.0.0 - update 1.0.2,1.0.3) | |
elif [ $major -eq $prev_major ] && [ $minor -ge $prev_minor ] && | |
[ $next_major -gt $major ] ; then | |
do_change_latest=0 | |
do_change_major=1 | |
do_change_major_minor=1 | |
fi | |
done | |
fi | |
if [ "${{ inputs.replace_prev }}" = "" ] && [ ${{ inputs.sem-ver }} = "existing" ]; then | |
echo "Inputs are not given properly" | |
exit 1 | |
fi | |
# Update latest version | |
if [ -z ${{ inputs.replace_prev }} ] && [ ${{ inputs.sem-ver }} != "none" ]; then | |
if [ ${{ inputs.sem-ver }} = "patch" ] ; then | |
patch=$(($patch + 1)) | |
fi | |
if [ ${{ inputs.sem-ver }} = "minor" ] ; then | |
minor=$(($minor + 1)) | |
patch=0 | |
fi | |
if [ ${{ inputs.sem-ver }} = "major" ] ; then | |
major=$(($major + 1)) | |
minor=0 | |
patch=0 | |
fi | |
fi | |
if [ -z ${{ inputs.replace_prev }} ] && [ ${{ inputs.sem-ver }} = "none" ]; then | |
echo "Inputs are not given properly" | |
exit 1 | |
fi | |
# Tag needs update | |
tag="$major.$minor.$patch" | |
maj_min_tag="$major.$minor" | |
maj_tag="$major" | |
# Update status for major.minor.patch | |
generate_only_one_tag=$(($do_change_latest==0 && $do_change_major==0 && $do_change_major_minor==0)) | |
generate_only_two_tag=$(($do_change_latest==0 && $do_change_major==0 && $do_change_major_minor==1)) | |
generate_only_three_tag=$(($do_change_latest==0 && $do_change_major==1 && $do_change_major_minor==1)) | |
generate_only_four_tag=$(($do_change_latest==1 && $do_change_major==1 && $do_change_major_minor==1)) | |
echo ::set-output name=TAG::$tag | |
echo ::set-output name=MAJ_MIN_TAG::$maj_min_tag | |
echo ::set-output name=MAJ_TAG::$maj_tag | |
echo ::set-output name=GENERATE_ONLY_ONE_TAG::$generate_only_one_tag | |
echo ::set-output name=GENERATE_ONLY_TWO_TAG::$generate_only_two_tag | |
echo ::set-output name=GENERATE_ONLY_THREE_TAG::$generate_only_three_tag | |
echo ::set-output name=GENERATE_ONLY_FOUR_TAG::$generate_only_four_tag | |
echo ::set-output name=DOCKER_HUB_NAME::$docker_hub_name | |
id: tag-gen | |
- name: Build and push only major.minor.patch tag | |
if: ${{ steps.tag-gen.outputs.GENERATE_ONLY_ONE_TAG == 1 }} | |
uses: docker/build-push-action@v3 | |
with: | |
context: . | |
file: ./docker-images/base-image/Dockerfile | |
push: true | |
tags: | | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
- name: Build and push only major.minor.patch, major.minor | |
if: ${{ steps.tag-gen.outputs.GENERATE_ONLY_TWO_TAG == 1 }} | |
uses: docker/build-push-action@v3 | |
with: | |
context: . | |
file: ./docker-images/base-image/Dockerfile | |
push: true | |
tags: | | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
- name: Build and push only major.minor.patch, major.minor, major | |
if: ${{ steps.tag-gen.outputs.GENERATE_ONLY_THREE_TAG == 1 }} | |
uses: docker/build-push-action@v3 | |
with: | |
context: . | |
file: ./docker-images/base-image/Dockerfile | |
push: true | |
tags: | | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_TAG}} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_TAG}} | |
- name: Build and push only major.minor.patch, major.minor, major, latest | |
if: ${{ steps.tag-gen.outputs.GENERATE_ONLY_FOUR_TAG == 1 }} | |
uses: docker/build-push-action@v3 | |
with: | |
context: . | |
file: ./docker-images/base-image/Dockerfile | |
push: true | |
tags: | | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_TAG}} | |
${{ steps.tag-gen.outputs.DOCKER_HUB_NAME }}/jvm-runtime:latest | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:${{ steps.tag-gen.outputs.MAJ_TAG}} | |
${{ secrets.DOCKER_ACR_NAME }}.azurecr.io/ballerina/jvm-runtime:latest | |
- name: Send Notifications | |
run: | | |
tags="" | |
if [[ ${{ steps.tag-gen.outputs.GENERATE_ONLY_ONE_TAG }} == 1 ]] | |
then | |
tags="${{ steps.tag-gen.outputs.TAG }} (patch)" | |
elif [[ ${{ steps.tag-gen.outputs.GENERATE_ONLY_TWO_TAG }} == 1 ]] | |
then | |
tags="${{ steps.tag-gen.outputs.TAG }} (patch), ${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} (minor)" | |
elif [[ ${{ steps.tag-gen.outputs.GENERATE_ONLY_THREE_TAG }} == 1 ]] | |
then | |
tags="${{ steps.tag-gen.outputs.TAG }} (patch), ${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} (minor), ${{ steps.tag-gen.outputs.MAJ_TAG }} (major)" | |
elif [[ ${{ steps.tag-gen.outputs.GENERATE_ONLY_FOUR_TAG }} == 1 ]] | |
then | |
tags="${{ steps.tag-gen.outputs.TAG }} (patch), ${{ steps.tag-gen.outputs.MAJ_MIN_TAG }} (minor), ${{ steps.tag-gen.outputs.MAJ_TAG }} (major), latest" | |
else | |
tags="no tags has been updated" | |
fi | |
docker run -e SPACE_ID="${{ secrets.SPACE_ID }}" -e MESSAGE_KEY="${{ secrets.MESSAGE_KEY }}" -e CHAT_TOKEN="${{ secrets.CHAT_TOKEN }}" -e TAGS="${tags}" ballerina/base_image_update_notifications | |
post-validate-registry-sync: | |
needs: build-jre-docker | |
uses: ./.github/workflows/validate-registry-sync.yml | |
secrets: inherit |