Skip to content

CLOUDP-329235/release-images #2447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions .github/workflows/promote-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,39 @@ jobs:
- name: Checkout PR commit
uses: actions/checkout@v4

# Note, we have to be careful how we retrive the image. The event that pushed
# the image to the ghcr.io repo was mainly a push/schedule that passed all the
# tests. This event has access to github.ref_name. However, the workflow_run
# event does not have access github.ref_name set up.
#
# Therefore, we need to manually specify the branch as main
- name: Prepare image tag
id: set_tag
uses: ./.github/actions/set-tag
with:
branch_name: ${{ github.event.workflow_run.head_branch }}
commit_sha: ${{ github.event.workflow_run.head_sha }}

- name: Log in to the GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Pull unofficial image from GitHub Container Registry
run: |
docker pull ${{ env.GHCR_REPO }}:${{ steps.set_tag.outputs.tag }}

- name: Login to Docker registry
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Log in to Quay registry
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

# Note, we have to be careful how we retrive the image. The event that pushed
# the image to the ghcr.io repo was mainly a push/schedule that passed all the
# tests. This event has access to github.ref_name. However, the workflow_run
# event does not have access github.ref_name set up.
#
# Therefore, we need to manually specify the branch as main
- name: Prepare image tag
id: set_tag
uses: ./.github/actions/set-tag
with:
branch_name: ${{ github.event.workflow_run.head_branch }}
commit_sha: ${{ github.event.workflow_run.head_sha }}

- name: Prepare tag for promoted image
id: promoted_tag
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-branch.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Create Release Branch
# DEPRECATED: Create Release Branch
# TODO after GitHub add permission for action-bot to commit to the protected branches - please merge release-* workflow into one

name: Create Release Branch
name: "[Deprecated] Create Release Branch"

on:
workflow_dispatch:
Expand Down
204 changes: 204 additions & 0 deletions .github/workflows/release-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
name: Release Image

on:
workflow_dispatch:
inputs:
version:
description: "Release version (e.g., 1.2.3)"
required: true
type: string
authors:
description: "Comma-separated list of the release authors' emails"
required: true
type: string
commit_sha:
description: "Commit SHA to use for the image (e.g. 7c2a91 or latest)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing the idea is to use latest more often than not, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly.

required: false
default: "latest"
type: string

permissions:
contents: write
pull-requests: write

jobs:
release-image:
runs-on: ubuntu-latest
environment: release
env:
VERSION: ${{ inputs.version }}
AUTHORS: ${{ inputs.authors }}
COMMIT_SHA: ${{ inputs.commit_sha }}

DOCKER_RELEASE_REPO: docker.io/mongodb/mongodb-atlas-kubernetes-operator
DOCKER_PRERELEASE_REPO: docker.io/mongodb/mongodb-atlas-kubernetes-operator-prerelease
DOCKER_SIGNATURE_REPO: docker.io/mongodb/signatures
QUAY_RELEASE_REPO: quay.io/mongodb/mongodb-atlas-kubernetes-operator
QUAY_PRERELEASE_REPO: quay.io/mongodb/mongodb-atlas-kubernetes-operator-prerelease

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Generate GitHub App Token
id: generate_token
uses: mongodb/apix-action/token@v8
with:
app-id: ${{ secrets.AKO_RELEASER_APP_ID }}
private-key: ${{ secrets.AKO_RELEASER_RSA_KEY }}

# Login in into all registries
- name: Log in to Docker registry
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.OCKER_PASSWORD }}

- name: Log in to Quay registry
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

- name: Log in to Artifactory
uses: docker/login-action@v3
with:
registry: artifactory.corp.mongodb.com
username: ${{ secrets.MDB_ARTIFACTORY_USERNAME }}
password: ${{ secrets.MDB_ARTIFACTORY_PASSWORD }}

- name: Install devbox
uses: jetify-com/[email protected]

- name: Resolve commit SHA and tags
id: tags
run: |
if [ "${{ env.COMMIT_SHA }}" = "latest" ]; then
git fetch origin main
sha=$(git rev-parse origin/main)
else
sha="${{ env.COMMIT_SHA }}"
fi

short_sha="${sha:0:6}"
promoted_tag="promoted-${short_sha}"
release_tag="${{ env.VERSION }}"
certified_tag="certified-${release_tag}"

docker_image_url="${{ env.DOCKER_RELEASE_REPO }}:${release_tag}"
quay_image_url="${{ env.QUAY_RELEASE_REPO }}:${release_tag}"
quay_certified_image_url="${{ env.QUAY_RELEASE_REPO }}:${certified_tag}"

echo "promoted_tag=${promoted_tag}" >> "$GITHUB_OUTPUT"
echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
echo "certified_tag=${certified_tag}" >> "$GITHUB_OUTPUT"
echo "docker_image_url=${docker_image_url}" >> "$GITHUB_OUTPUT"
echo "quay_image_url=${quay_image_url}" >> "$GITHUB_OUTPUT"
echo "quay_certified_image_url=${quay_certified_image_url}" >> "$GITHUB_OUTPUT"

# Move prerelease images to official release registries in Docker Hub and Quay
- name: Promote Docker prerelease image
run: devbox run -- ./scripts/move-image.sh
env:
IMAGE_SRC_REPO: ${{ env.DOCKER_PRERELEASE_REPO }}
IMAGE_DEST_REPO: ${{ env.DOCKER_RELEASE_REPO }}
IMAGE_SRC_TAG: ${{ steps.tags.outputs.promoted_tag }}
IMAGE_DEST_TAG: ${{ steps.tags.outputs.release_tag }}

- name: Promote Quay prerelease image
run: devbox run -- ./scripts/move-image.sh
env:
IMAGE_SRC_REPO: ${{ env.QUAY_PRERELEASE_REPO }}
IMAGE_DEST_REPO: ${{ env.QUAY_RELEASE_REPO }}
IMAGE_SRC_TAG: ${{ steps.tags.outputs.promoted_tag }}
IMAGE_DEST_TAG: ${{ steps.tags.outputs.release_tag }}

# Create Openshift certified images
- name: Create OpenShift certified image on Quay
run: devbox run -- ./scripts/move-image.sh
env:
IMAGE_SRC_REPO: ${{ env.QUAY_PRERELEASE_REPO }}
IMAGE_DEST_REPO: ${{ env.QUAY_RELEASE_REPO }}
IMAGE_SRC_TAG: ${{ steps.tags.outputs.promoted_tag }}
IMAGE_DEST_TAG: ${{ steps.tags.outputs.certified_tag }}

- name: Certify Openshift images
uses: ./.github/actions/certify-openshift-images
with:
registry: quay.io
version: ${{ steps.tags.outputs.certified_tag }}
repository: mongodb/mongodb-atlas-kubernetes-operator
registry_password: ${{ secrets.QUAY_PASSWORD }}
rhcc_project: ${{ secrets.RH_CERTIFICATION_OSPID }}
rhcc_token: ${{ secrets.RH_CERTIFICATION_PYXIS_API_TOKEN }}
submit: true

# Link updates to pr: all-in-one.yml, helm-updates, sdlc requirements
- name: Generate deployment configurations
uses: ./.github/actions/gen-install-scripts
with:
ENV: prod
IMAGE_URL: ${{ steps.tags.outputs.docker_image_url }}

- name: Bump Helm chart version
run: devbox run -- ./scripts/bump-helm-chart-version.sh

# Prepare SDLC requirement: signatures, sboms, compliance reports
# Note, signed images will live in mongodb/release and mongodb/signature repos
- name: Sign released images
run: |
devbox run -- make sign IMG="${{ steps.tags.outputs.docker_image_url }}" SIGNATURE_REPO="${{ env.DOCKER_RELEASE_REPO }}"
devbox run -- make sign IMG="${{ steps.tags.outputs.quay_image_url }}" SIGNATURE_REPO="${{ env.QUAY_RELEASE_REPO }}"
devbox run -- make sign IMG="${{ steps.tags.outputs.docker_image_url }}" SIGNATURE_REPO="${{ env.DOCKER_SIGNATURE_REPO }}"
devbox run -- make sign IMG="${{ steps.tags.outputs.quay_certified_image_url }}" SIGNATURE_REPO="${{ env.QUAY_RELEASE_REPO }}"
devbox run -- make sign IMG="${{ steps.tags.outputs.quay_certified_image_url }}" SIGNATURE_REPO="${{ env.DOCKER_SIGNATURE_REPO }}"
env:
PKCS11_URI: ${{ secrets.PKCS11_URI }}
GRS_USERNAME: ${{ secrets.GRS_USERNAME }}
GRS_PASSWORD: ${{ secrets.GRS_PASSWORD }}

- name: Generate SBOMs
run: devbox run -- make generate-sboms
env:
RELEASED_OPERATOR_IMAGE: ${{ env.DOCKER_RELEASE_REPO }}

- name: Generate SDLC report
run: devbox run -- make gen-sdlc-checklist

# Create pr with all updates
- name: Create pull request for release changes
uses: peter-evans/create-pull-request@v6
with:
token: ${{ steps.generate_token.outputs.token }}
commit-message: "chore(release): updates from new release v${{ env.VERSION }}"
title: "Release v${{ env.VERSION }}"
body: |
This PR was automatically generated by the **release-image** workflow.

Version: `${{ env.VERSION }}`
Authors: ${{ env.AUTHORS }}
base: main
branch: "new-release/${{ env.VERSION }}" # This should avoid for now running all tests till we fix cloud-test-filter.yml
delete-branch: true
draft: true

# Create release assets on GitHub
- name: Create configuration package
run: |
devbox run -- 'set -x'
devbox run -- 'tar czvf atlas-operator-all-in-one-${{ env.VERSION }}.tar.gz -C deploy all-in-one.yaml'

- name: Create GitHub Release and Upload Asset
uses: softprops/action-gh-release@v2
with:
draft: true
prerelease: false
tag_name: ${{ env.VERSION }}
name: ${{ env.VERSION }}
body_path: docs/release-notes/release-notes-template.md
files: ./atlas-operator-all-in-one-${{ env.VERSION }}.tar.gz
token: ${{ steps.generate_token.outputs.token }}
4 changes: 2 additions & 2 deletions .github/workflows/release-post-merge.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# GitHub workflow for creating release.
# DEPRECATED: GitHub workflow for creating release.
# Trigger release branch should be merge into main
# TODO add e2e/smoke test for autogen configuration

name: Create Release
name: "[Deprecated] Create Release"

on:
push:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/sboms-pr.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# GitHub workflow for creating the SDLC SBOMs PR after a release.
name: Create SBOMs PR
# DEPRECATED: GitHub workflow for creating the SDLC SBOMs PR after a release.
name: "[Deprecated] Create SBOMs PR"

on:
workflow_call:
Expand Down
26 changes: 17 additions & 9 deletions scripts/move-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright 2025 MongoDB Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
Expand All @@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# This scripts moves an image from a registry to another with retagging
# This script moves a multi-arch image from one registry to another using docker buildx.

set -euo pipefail

Expand All @@ -26,12 +26,20 @@ set -euo pipefail
image_src_url="${IMAGE_SRC_REPO}:${IMAGE_SRC_TAG}"
image_dest_url="${IMAGE_DEST_REPO}:${IMAGE_DEST_TAG}"

echo "Checking if ${image_dest_url} already exists..."
echo "Checking if ${image_dest_url} already exists remotely..."
if docker manifest inspect "${image_dest_url}" > /dev/null 2>&1; then
echo "${image_dest_url} already exists. Skipping push."
else
echo "Tagging ${image_src_url} -> ${image_dest_url}"
docker tag "${image_src_url}" "${image_dest_url}"
echo "Pushing to ${image_dest_url}..."
docker push "${image_dest_url}"
echo "Image ${image_dest_url} already exists. Skipping transfer."
exit 0
fi

echo "Transferring multi-arch image:"
echo " From: ${image_src_url}"
echo " To: ${image_dest_url}"

BUILDER_NAME="tmpbuilder-move-image"

echo "Creating temporary buildx builder..."
docker buildx create --name "${BUILDER_NAME}" --use > /dev/null
docker buildx imagetools create "${image_src_url}" --tag "${image_dest_url}"
docker buildx rm "${BUILDER_NAME}" > /dev/null
echo "Successfully moved ${image_src_url} -> ${image_dest_url}"
Loading