Promote RC to Release #46
Workflow file for this run
This file contains hidden or 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: Promote RC to Release | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref_name }} | |
cancel-in-progress: true | |
on: | |
workflow_dispatch: | |
inputs: | |
mage_version: | |
description: "Mage version (format: X.Y.Z)" | |
required: true | |
type: string | |
mage_rc_version: | |
description: "Mage RC version to promote (format: rcX)" | |
required: false | |
type: string | |
force_promote: | |
type: boolean | |
description: "Override existing release" | |
default: false | |
test: | |
description: "Run in test mode" | |
required: false | |
type: boolean | |
use_test_rc: | |
description: "Use RC from 'mage-test/' (cannot be used for official release)" | |
default: false | |
type: boolean | |
env: | |
s3_region: eu-west-1 | |
rc_bucket: deps.memgraph.io | |
docker_repo_rc: memgraph/memgraph-mage | |
docker_repo_release: memgraph/memgraph-mage${{ github.event.inputs.test == 'true' && '-release-test' || '' }} | |
jobs: | |
PromoteDocker: | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- build_target: "prod" | |
build_type: "Release" | |
- build_target: "prod" | |
build_type: "RelWithDebInfo" | |
image_ext: "-relwithdebinfo" | |
- build_target: "prod" | |
build_type: "Release" | |
image_ext: "-malloc" | |
runs-on: ["self-hosted", "DockerMgBuild", "X64"] | |
steps: | |
- name: Validate “use_test_rc” only with test | |
if: inputs.use_test_rc && ! inputs.test | |
run: | | |
echo "Must not run 'use_test_rc=true' without setting 'test=true'" | |
exit 1 | |
- name: Setup environment variables | |
run: | | |
mage_version=${{ github.event.inputs.mage_version }} | |
rc_dir="${{ inputs.use_test_rc && 'mage-test/v' || 'mage/v'}}${{ github.event.inputs.mage_version }}" | |
if [[ -n "${{ inputs.mage_rc_version }}" ]]; then | |
rc_dir="${rc_dir}-${{ inputs.mage_rc_version }}" | |
fi | |
echo "rc_dir=${rc_dir}" >> $GITHUB_ENV | |
echo "docker_tar_amd=mage-${mage_version%.0}${{ matrix.image_ext }}.tar.gz" >> $GITHUB_ENV | |
echo "docker_tar_arm=mage-${mage_version%.0}-arm64${{ matrix.image_ext }}.tar.gz" >> $GITHUB_ENV | |
echo "rc_image=${docker_repo_rc}:${mage_version%.0}${{ matrix.image_ext }}" >> $GITHUB_ENV | |
echo "release_image=${docker_repo_release}:${mage_version%.0}${{ matrix.image_ext }}" >> $GITHUB_ENV | |
- name: Setup S3 Paths | |
run: | | |
echo "s3_input_amd=s3://${rc_bucket}/${rc_dir}/${docker_tar_amd}" >> $GITHUB_ENV | |
echo "s3_input_arm=s3://${rc_bucket}/${rc_dir}/${docker_tar_arm}" >> $GITHUB_ENV | |
- name: Setup AWS credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ env.s3_region }} | |
- name: Check if RC image for this build exists | |
run: | | |
if aws s3 ls ${s3_input_amd} &> /dev/null; then | |
echo "has_rc_package_amd=true" >> $GITHUB_ENV | |
else | |
echo "has_rc_package_amd=false" >> $GITHUB_ENV | |
echo "RC package does not exist at ${s3_input_amd}" | |
fi | |
if aws s3 ls ${s3_input_arm} &> /dev/null; then | |
echo "has_rc_package_arm=true" >> $GITHUB_ENV | |
else | |
echo "has_rc_package_arm=false" >> $GITHUB_ENV | |
echo "RC package does not exist at ${s3_input_arm}" | |
fi | |
- name: Early exit if no RC packages are found | |
if: ${{ env.has_rc_package_amd == 'false' && env.has_rc_package_arm == 'false' }} | |
run: | | |
echo "Neither RC package exists. Skipping the rest of the workflow." | |
exit 0 | |
- name: Check if release image for this build already exists | |
run: | | |
existing_amd64=false | |
existing_arm64=false | |
# Get the manifest details in verbose mode; suppress errors if manifest does not exist. | |
manifest_output=$(docker manifest inspect ${release_image} --verbose 2>/dev/null || true) | |
# If manifest_output is not empty, check for each architecture. | |
if [[ -n "$manifest_output" ]]; then | |
if echo "$manifest_output" | grep -q '"architecture": "amd64"'; then | |
existing_amd64=true | |
fi | |
if echo "$manifest_output" | grep -q '"architecture": "arm64"'; then | |
existing_arm64=true | |
fi | |
fi | |
echo "On Docker Hub: amd64: $existing_amd64; arm64: $existing_arm64" | |
if [ "$existing_amd64" = "true" ] || [ "$existing_arm64" = "true" ]; then | |
echo "Release image ${release_image} already exists on DockerHub with:" | |
if [ "$existing_amd64" = "true" ]; then | |
echo " - amd64" | |
fi | |
if [ "$existing_arm64" = "true" ]; then | |
echo " - arm64" | |
fi | |
if [[ "${{ github.event.inputs.force_promote }}" != "true" ]]; then | |
echo "Set force_promote to true to override the existing release!" | |
exit 1 | |
fi | |
echo "Forcing promotion of existing release ..." | |
else | |
echo "No conflict found..." | |
fi | |
- name: Log in to Docker Hub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Get dockerhub token | |
run: | | |
dockerhub_token=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' https://hub.docker.com/v2/users/login/ | jq -r .token) | |
echo "dockerhub_token=${dockerhub_token}" >> $GITHUB_ENV | |
- name: Promote RC to Release | |
run: | | |
release_image_amd=${release_image}-amd64 | |
release_image_arm=${release_image}-arm64 | |
release_image_latest=${docker_repo_release}:latest | |
# Download and load, retag if necessary, push temporary arm64 image if available | |
if [ "${has_rc_package_arm}" = "true" ]; then | |
echo "Downloading and loading ${rc_image} for arm64 ..." | |
aws s3 cp $s3_input_arm - | docker load | |
echo "Tagging ${rc_image} as ${release_image_arm} ..." | |
docker tag ${rc_image} ${release_image_arm} | |
echo "Pushing ${release_image_arm} to DockerHub!" | |
docker push ${release_image_arm} | |
else | |
echo "Skipping arm64 promotion: RC package not available." | |
fi | |
# Download and load, retag if necessary, push temporary amd64 image if available | |
if [ "${has_rc_package_amd}" = "true" ]; then | |
echo "Downloading and loading ${rc_image} for amd64 ..." | |
aws s3 cp $s3_input_amd - | docker load | |
echo "Tagging ${rc_image} as ${release_image_amd} ..." | |
docker tag ${rc_image} ${release_image_amd} | |
echo "Pushing ${release_image_amd} to DockerHub!" | |
docker push ${release_image_amd} | |
else | |
echo "Skipping amd64 promotion: RC package not available." | |
fi | |
# Build the manifest list from the promoted images | |
manifest_images="" | |
if [ "${has_rc_package_amd}" = "true" ]; then | |
manifest_images="$manifest_images --amend ${release_image_amd}" | |
fi | |
if [ "${has_rc_package_arm}" = "true" ]; then | |
manifest_images="$manifest_images --amend ${release_image_arm}" | |
fi | |
if [ -n "$manifest_images" ]; then | |
echo "Creating and pushing manifest for ${release_image} with images:$manifest_images" | |
docker manifest create ${release_image} $manifest_images | |
docker manifest push ${release_image} | |
echo "Successfully published ${release_image} to DockerHub!" | |
else | |
echo "No images promoted; skipping manifest creation." | |
fi | |
# Setup and push the 'latest' manifest if production image | |
if [[ -z "${{ matrix.image_ext }}" ]]; then | |
if [ -n "$manifest_images" ]; then | |
docker manifest create ${release_image_latest} $manifest_images | |
docker manifest push ${release_image_latest} | |
echo "Successfully published ${release_image_latest} to DockerHub!" | |
else | |
echo "No images promoted; skipping 'latest' manifest creation." | |
fi | |
fi | |
- name: Clean up temporary images | |
run: | | |
if [ "${has_rc_package_amd}" = "true" ]; then | |
echo "Deleting temporary image ${release_image_amd} ..." | |
curl -i -n -X DELETE -H "Authorization: JWT ${dockerhub_token}" https://hub.docker.com/v2/repositories/${docker_repo_release}/tags/${release_image#*:}-amd64/ | |
else | |
echo "Skipping deletion for amd64: image not promoted." | |
fi | |
if [ "${has_rc_package_arm}" = "true" ]; then | |
echo "Deleting temporary image ${release_image_arm} ..." | |
curl -i -n -X DELETE -H "Authorization: JWT ${dockerhub_token}" https://hub.docker.com/v2/repositories/${docker_repo_release}/tags/${release_image#*:}-arm64/ | |
else | |
echo "Skipping deletion for arm64: image not promoted." | |
fi | |