Skip to content

[Test] Operator Release #40

[Test] Operator Release

[Test] Operator Release #40

name: "[Test] Operator Release"
run-name: "[Test] Operator Release"
on:
workflow_dispatch:
inputs:
# Test configuration:
release-version:
description: Upstream version that the release was based on.
required: true
tests-tag:
description: Git ref to use when checking out the testsuite sources. Should either be the same as the upstream version, or `main`.
required: true
default: main
# Test artifacts:
operatorImage:
description: Operator image (optional - if not provided, the image from the upstream version will be used).
required: false
appImage:
description: Application image (optional - if not provided, the image from the upstream version will be used).
required: false
uiImage:
description: UI image (optional - if not provided, the image from the upstream version will be used).
required: false
# OLM
artifact-cluster-name:
type: string
description: >-
Name of the artifact cluster where the downstream catalog images are hosted.
Catalog images must be prepared before running this test, see docs/Operator-Testing.md for details.
If left empty, it is assumed that a publicly available (upstream) catalog image is used.
required: false
catalog-images:
type: string
description: >-
Upstream or downstream catalog image(s) in the `cluster-version=catalog-image,…` format, for example:
`4.16=image-registry-infra.apps.art.apicurio-testing.org/rh-osbs/iib:123,4.19=image-registry-infra.apps.art.apicurio-testing.org/rh-osbs/iib:456`.
Upstream OLM catalog image can be the latest one, i.e. `quay.io/apicurio/apicurio-registry-3-operator-catalog:latest`.
Downstream catalog image is assumed to be hosted on the artifact cluster,
but the original downstream image URI can also be used and the workflow will attempt to transform the URI.
required: true
default: >
4.16=,
4.19=
package-version:
type: string
description: >-
CSV package version to install from the catalog image. For downstream, include the rebuild suffix, e.g. `3.1.4-r1`.
required: true
jobs:
record-start-time:
name: Record start time
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
start-time: ${{ steps.get-start-time.outputs.start-time }}
steps:
- name: Get Workflow Start Time
id: get-start-time
run: |
START_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo "start-time=$START_TIME" >> $GITHUB_OUTPUT
echo "Workflow start time: $START_TIME"
prepare:
name: Prepare test matrix
runs-on: ubuntu-latest
timeout-minutes: 5
needs: record-start-time
outputs:
random-suffix: ${{ steps.generate-suffix.outputs.random-suffix }}
matrix-json: ${{ steps.parse-catalog-images.outputs.matrix-json }}
steps:
- name: Print Workflow Parameters
run: |
echo "📋 Workflow Input Parameters:"
echo " release-version: ${{ inputs.release-version }}"
echo " tests-tag: ${{ inputs.tests-tag }}"
echo " operatorImage: ${{ inputs.operatorImage }}"
echo " appImage: ${{ inputs.appImage }}"
echo " uiImage: ${{ inputs.uiImage }}"
echo " artifact-cluster-name: ${{ inputs.artifact-cluster-name }}"
echo " catalog-images: ${{ inputs.catalog-images }}"
echo " package-version: ${{ inputs.package-version }}"
- name: Generate Random Suffix
id: generate-suffix
run: |
FIRST_CHAR=$(tr -cd 'a-z' < /dev/urandom | head -c1)
REST_CHARS=$(tr -cd 'a-z0-9' < /dev/urandom | head -c2)
SUFFIX="${FIRST_CHAR}${REST_CHARS}"
echo "random-suffix=$SUFFIX" >> $GITHUB_OUTPUT
echo "Generated random suffix: $SUFFIX"
- name: Parse Catalog Images
id: parse-catalog-images
run: |
INPUT="${{ inputs.catalog-images }}"
# Remove all whitespace, newlines, and tabs:
INPUT=$(echo "$INPUT" | tr -d '[:space:]')
# Check if input contains '=':
if [[ "$INPUT" == *"="* ]]; then
echo "📦 Parsing multi-version catalog images..."
# Parse comma-separated key=value pairs:
IFS=',' read -ra PAIRS <<< "$INPUT"
declare -A CATALOG_MAP
for pair in "${PAIRS[@]}"; do
# Skip empty pairs:
if [[ -z "$pair" ]]; then
continue
fi
# Extract version and image:
if [[ "$pair" == *"="* ]]; then
VERSION="${pair%%=*}"
IMAGE="${pair#*=}"
# Skip if either version or image is empty:
if [[ -n "$VERSION" && -n "$IMAGE" ]]; then
CATALOG_MAP["$VERSION"]="$IMAGE"
echo " $VERSION -> $IMAGE"
fi
fi
done
# Validate that we have at least one version:
if [[ ${#CATALOG_MAP[@]} -eq 0 ]]; then
echo "❌ Error: No valid version=image pairs found."
exit 1
fi
# Build JSON matrix
MATRIX_JSON='{"include":['
FIRST=true
for VERSION in "${!CATALOG_MAP[@]}"; do
IMAGE="${CATALOG_MAP[$VERSION]}"
# Remove dots from version for cluster name (e.g., 4.16 -> 416):
VERSION_SHORT="${VERSION//./}"
if [[ "$FIRST" == true ]]; then
FIRST=false
else
MATRIX_JSON+=","
fi
MATRIX_JSON+="{\"cluster-version\":\"$VERSION\",\"catalog-image\":\"$IMAGE\",\"version-short\":\"$VERSION_SHORT\"}"
done
MATRIX_JSON+=']}'
echo "matrix-json=$MATRIX_JSON" >> $GITHUB_OUTPUT
echo "Generated matrix JSON: $MATRIX_JSON"
else
echo "❌ Error: No valid version=image pairs found."
exit 1
fi
test:
name: Test on OCP ${{ matrix.cluster-version }}
needs:
- prepare
strategy:
matrix: ${{ fromJson(needs.prepare.outputs.matrix-json) }}
fail-fast: false
uses: ./.github/workflows/subtest-registry-operator.yaml
with:
cluster-name: ci${{ matrix.version-short }}${{ needs.prepare.outputs.random-suffix }}
skip-provision-cluster: false
cluster-version: ${{ matrix.cluster-version }}
release-version: ${{ inputs.release-version }}
tests-tag: ${{ inputs.tests-tag }}
operatorImage: ${{ inputs.operatorImage }}
appImage: ${{ inputs.appImage }}
uiImage: ${{ inputs.uiImage }}
artifact-cluster-name: ${{ inputs.artifact-cluster-name }}
catalog-image: ${{ matrix.catalog-image }}
package-version: ${{ inputs.package-version }}
destroy-test-cluster: true
secrets: inherit
save_workflow_metadata:
name: Save Workflow Metadata
runs-on: ubuntu-latest
timeout-minutes: 5
needs:
- record-start-time
- test
if: >-
!cancelled() && needs.record-start-time.result == 'success'
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Commit workflow metadata to repository
uses: ./.github/actions/commit-workflow-metadata
with:
github-token: ${{ secrets.ACCESS_TOKEN }}
workflow-start-time: ${{ needs.record-start-time.outputs.start-time }}