You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2022/01/31 08:58:41 UTC

[camel-k] 30/40: Extract action bash scripts to their own files

This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 62d87c7f7d4792624fb5747fc99af97f4c11f9b1
Author: phantomjinx <p....@phantomjinx.co.uk>
AuthorDate: Thu Jan 6 13:51:18 2022 +0000

    Extract action bash scripts to their own files
    
    * Allows for easier local unit testing of the functions
---
 .github/actions/e2e-kubernetes/action.yml          |  40 +----
 .github/actions/e2e-kubernetes/exec-tests.sh       | 119 ++++++++++++++
 .github/actions/kamel-build-binary/action.yml      |  51 +-----
 .github/actions/kamel-build-binary/build-binary.sh | 111 +++++++++++++
 .github/actions/kamel-build-bundle/action.yaml     | 180 ++-------------------
 .../kamel-build-bundle/build-bundle-image.sh       | 114 +++++++++++++
 .../kamel-build-bundle/build-image-catalog.sh      |  90 +++++++++++
 .../kamel-build-bundle/build-index-image.sh        | 173 ++++++++++++++++++++
 .github/actions/kamel-cleanup/action.yaml          |  29 +---
 .github/actions/kamel-cleanup/cleanup.sh           |  72 +++++++++
 .../actions/kamel-install-cluster-setup/action.yml |  21 +--
 .../install-cluster-setup.sh                       |  68 ++++++++
 12 files changed, 782 insertions(+), 286 deletions(-)

diff --git a/.github/actions/e2e-kubernetes/action.yml b/.github/actions/e2e-kubernetes/action.yml
index ec8c2c2..2d004dc 100644
--- a/.github/actions/e2e-kubernetes/action.yml
+++ b/.github/actions/e2e-kubernetes/action.yml
@@ -64,38 +64,14 @@ runs:
     name: Run IT
     shell: bash
     run: |
-      # Cluster environment
-      export CUSTOM_IMAGE=${{ steps.build-kamel.outputs.build-binary-local-image-name }}
-      export CUSTOM_VERSION=${{ steps.build-kamel.outputs.build-binary-local-image-version }}
-
-      #
-      # If bundle has been built and installed then use it
-      #
-      if [ -n "${{ steps.build-kamel.outputs.build-bundle-catalog-source-name }}" ]; then
-        export KAMEL_INSTALL_OLM_SOURCE_NAMESPACE=${{ steps.config-cluster.outputs.cluster-image-namespace }}
-        export KAMEL_INSTALL_OLM_SOURCE=${{ steps.build-kamel.outputs.build-bundle-catalog-source-name }}
-      fi
-
-      export KAMEL_INSTALL_MAVEN_REPOSITORIES=$(make get-staging-repo)
-      export KAMEL_INSTALL_REGISTRY=${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }}
-      export KAMEL_INSTALL_REGISTRY_INSECURE=${{steps.config-cluster.outputs.cluster-image-registry-insecure }}
-      export KAMEL_INSTALL_OPERATOR_IMAGE=${CUSTOM_IMAGE}:${CUSTOM_VERSION}
-
-      export CAMEL_K_TEST_IMAGE_NAME=${CUSTOM_IMAGE}
-      export CAMEL_K_TEST_IMAGE_VERSION=${CUSTOM_VERSION}
-      export CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE=${{ env.CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE }}
-
-      # Then run all integration tests rather than ending on first failure
-      set -e
-      exit_code=0
-      make test-integration || exit_code=1
-      make test-service-binding || exit_code=1
-      make test-quarkus-native || exit_code=1
-      make test-kustomize || exit_code=1
-      set +e
-
-      echo "Tests completed with exit code: ${exit_code}"
-      exit ${exit_code}
+      ./.github/actions/e2e-kubernetes/exec-tests.sh \
+        -c "${{ steps.build-kamel.outputs.build-bundle-catalog-source-name }}" \
+        -i "${{ steps.config-cluster.outputs.cluster-image-namespace }}" \
+        -l "${{ steps.config-cluster.outputs.cluster-image-registry-pull-host }}" \
+        -n "${{ steps.build-kamel.outputs.build-binary-local-image-name }}" \
+        -s "${{steps.config-cluster.outputs.cluster-image-registry-insecure }}" \
+        -v "${{ steps.build-kamel.outputs.build-binary-local-image-version }}" \
+        -x "${{ env.CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE }}"
 
   - name: Cleanup
     uses: ./.github/actions/kamel-cleanup
diff --git a/.github/actions/e2e-kubernetes/exec-tests.sh b/.github/actions/e2e-kubernetes/exec-tests.sh
new file mode 100755
index 0000000..b3311a5
--- /dev/null
+++ b/.github/actions/e2e-kubernetes/exec-tests.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Execute the kubernetes tests
+#
+####
+
+set -e
+
+while getopts ":c:i:l:n:s:v:x:" opt; do
+  case "${opt}" in
+    c)
+      BUILD_CATALOG_SOURCE=${OPTARG}
+      ;;
+    i)
+      IMAGE_NAMESPACE=${OPTARG}
+      ;;
+    l)
+      REGISTRY_PULL_HOST=${OPTARG}
+      ;;
+    n)
+      IMAGE_NAME=${OPTARG}
+      ;;
+    s)
+      REGISTRY_INSECURE=${OPTARG}
+      ;;
+    v)
+      IMAGE_VERSION=${OPTARG}
+      ;;
+    x)
+      SAVE_FAILED_TEST_NS=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+if [ -z "${IMAGE_NAME}" ]; then
+  echo "Error: local-image-name not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_VERSION}" ]; then
+  echo "Error: local-image-version not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_NAMESPACE}" ]; then
+  echo "Error: image-namespace not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_PULL_HOST}" ]; then
+  echo "Error: image-registry-pull-host not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_INSECURE}" ]; then
+  echo "Error: image-registry-insecure not defined"
+  exit 1
+fi
+
+# Cluster environment
+export CUSTOM_IMAGE=${IMAGE_NAME}
+export CUSTOM_VERSION=${IMAGE_VERSION}
+
+#
+# If bundle has been built and installed then use it
+#
+if [ -n "${BUILD_CATALOG_SOURCE}" ]; then
+  export KAMEL_INSTALL_OLM_SOURCE_NAMESPACE=${IMAGE_NAMESPACE}
+  export KAMEL_INSTALL_OLM_SOURCE=${BUILD_CATALOG_SOURCE}
+fi
+
+export KAMEL_INSTALL_MAVEN_REPOSITORIES=$(make get-staging-repo)
+export KAMEL_INSTALL_REGISTRY=${REGISTRY_PULL_HOST}
+export KAMEL_INSTALL_REGISTRY_INSECURE=${REGISTRY_INSECURE}
+export KAMEL_INSTALL_OPERATOR_IMAGE=${CUSTOM_IMAGE}:${CUSTOM_VERSION}
+
+export CAMEL_K_TEST_IMAGE_NAME=${CUSTOM_IMAGE}
+export CAMEL_K_TEST_IMAGE_VERSION=${CUSTOM_VERSION}
+export CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE=${SAVE_FAILED_TEST_NS}
+
+# Then run all integration tests rather than ending on first failure
+set -e
+exit_code=0
+make test-integration || exit_code=1
+make test-service-binding || exit_code=1
+make test-quarkus-native || exit_code=1
+make test-kustomize || exit_code=1
+set +e
+
+echo "Tests completed with exit code: ${exit_code}"
+exit ${exit_code}
diff --git a/.github/actions/kamel-build-binary/action.yml b/.github/actions/kamel-build-binary/action.yml
index 8b87dd6..86451fe 100644
--- a/.github/actions/kamel-build-binary/action.yml
+++ b/.github/actions/kamel-build-binary/action.yml
@@ -40,51 +40,12 @@ runs:
       name: Build Kamel Operator
       shell: bash
       run: |
-        if [ -n "${{ inputs.image-registry-push-host }}" ]; then
-          #
-          # Build with the PUSH host to ensure the correct image:tag
-          # for docker to push the image.
-          #
-          export CUSTOM_IMAGE=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k
-        fi
-
-        if [ -n "${{ env.DEBUG_USE_EXISTING_IMAGE }}" ] && [ -n "${CUSTOM_IMAGE}" ]; then
-          echo "Fetching Kamel from existing build"
-
-          docker pull ${{ env.DEBUG_USE_EXISTING_IMAGE }}
-          id=$(docker create ${{ env.DEBUG_USE_EXISTING_IMAGE }})
-          docker cp $id:/usr/local/bin/kamel .
-
-          docker tag ${{ env.DEBUG_USE_EXISTING_IMAGE }} ${CUSTOM_IMAGE}:$(make get-version)
-          docker push ${CUSTOM_IMAGE}:$(make get-version)
-        else
-
-          echo "Build Kamel from source"
-
-          RULES="PACKAGE_ARTIFACTS_STRATEGY=download build package-artifacts images"
-          if [ -n "${{ inputs.make-rules }}" ]; then
-            RULES="${{ inputs.make-rules }}"
-          fi
-
-          if [ -n "${{ inputs.image-registry-push-host }}" ]; then
-            RULES="${RULES} images-push"
-          fi
-
-          make ${RULES}
-        fi
-
-        echo "Moving kamel binary to /usr/local/bin"
-        sudo mv ./kamel /usr/local/bin
-        echo "Kamel version installed: $(kamel version)"
-
-        #
-        # Use the PULL host to ensure the correct image:tag
-        # is passed into the tests for the deployment to pull from
-        #
-        BUILD_BINARY_LOCAL_IMAGE_NAME="${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k"
-        BUILD_BINARY_LOCAL_IMAGE_VERSION="$(make get-version)"
-        echo "::set-output name=build-binary-local-image-name::${BUILD_BINARY_LOCAL_IMAGE_NAME}"
-        echo "::set-output name=build-binary-local-image-version::${BUILD_BINARY_LOCAL_IMAGE_VERSION}"
+        ./.github/actions/kamel-build-binary/build-binary.sh \
+          -i "${{ inputs.image-namespace }}" \
+          -l "${{ inputs.image-registry-pull-host }}" \
+          -m "${{ inputs.make-rules }}" \
+          -s "${{ inputs.image-registry-push-host }}" \
+          -x "${{ env.DEBUG_USE_EXISTING_IMAGE }}"
 
 outputs:
   build-binary-local-image-name:
diff --git a/.github/actions/kamel-build-binary/build-binary.sh b/.github/actions/kamel-build-binary/build-binary.sh
new file mode 100755
index 0000000..76ebd2b
--- /dev/null
+++ b/.github/actions/kamel-build-binary/build-binary.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Builds the kamel binary
+#
+####
+
+set -e
+
+while getopts ":i:l:m:s:x:" opt; do
+  case "${opt}" in
+    i)
+      IMAGE_NAMESPACE=${OPTARG}
+      ;;
+    l)
+      REGISTRY_PULL_HOST=${OPTARG}
+      ;;
+    m)
+      MAKE_RULES="${OPTARG}"
+      ;;
+    s)
+      REGISTRY_PUSH_HOST=${OPTARG}
+      ;;
+    x)
+      DEBUG_USE_EXISTING_IMAGE=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+if [ -n "${REGISTRY_PUSH_HOST}" ]; then
+  #
+  # Need an image namespace if using a registry
+  #
+  if [ -z "${IMAGE_NAMESPACE}" ]; then
+    echo "Error: image-namespace not defined"
+    exit 1
+  fi
+
+  #
+  # Build with the PUSH host to ensure the correct image:tag
+  # for docker to push the image.
+  #
+  export CUSTOM_IMAGE=${REGISTRY_PUSH_HOST}/${IMAGE_NAMESPACE}/camel-k
+fi
+
+if [ -n "${DEBUG_USE_EXISTING_IMAGE}" ] && [ -n "${CUSTOM_IMAGE}" ]; then
+  echo "Fetching Kamel from existing build"
+
+  docker pull ${DEBUG_USE_EXISTING_IMAGE}
+  id=$(docker create ${DEBUG_USE_EXISTING_IMAGE})
+  docker cp $id:/usr/local/bin/kamel .
+
+  docker tag ${DEBUG_USE_EXISTING_IMAGE} ${CUSTOM_IMAGE}:$(make get-version)
+  docker push ${CUSTOM_IMAGE}:$(make get-version)
+else
+
+  echo "Build Kamel from source"
+
+  RULES="PACKAGE_ARTIFACTS_STRATEGY=download build package-artifacts images"
+  if [ -n "${MAKE_RULES}" ]; then
+    RULES=" ${MAKE_RULES} "
+  fi
+
+  if [ -n "${REGISTRY_PUSH_HOST}" ]; then
+    RULES="${RULES} images-push"
+  fi
+
+  make ${RULES}
+fi
+
+echo "Moving kamel binary to /usr/local/bin"
+sudo mv ./kamel /usr/local/bin
+echo "Kamel version installed: $(kamel version)"
+
+#
+# Use the PULL host to ensure the correct image:tag
+# is passed into the tests for the deployment to pull from
+#
+BUILD_BINARY_LOCAL_IMAGE_NAME="${REGISTRY_PULL_HOST}/${IMAGE_NAMESPACE}/camel-k"
+BUILD_BINARY_LOCAL_IMAGE_VERSION="$(make get-version)"
+echo "Setting build-binary-local-image-name to ${BUILD_BINARY_LOCAL_IMAGE_NAME}"
+echo "::set-output name=build-binary-local-image-name::${BUILD_BINARY_LOCAL_IMAGE_NAME}"
+echo "Setting build-binary-local-image-name-version to ${BUILD_BINARY_LOCAL_IMAGE_VERSION}"
+echo "::set-output name=build-binary-local-image-version::${BUILD_BINARY_LOCAL_IMAGE_VERSION}"
diff --git a/.github/actions/kamel-build-bundle/action.yaml b/.github/actions/kamel-build-bundle/action.yaml
index 2a6f65f..b52ccf8 100644
--- a/.github/actions/kamel-build-bundle/action.yaml
+++ b/.github/actions/kamel-build-bundle/action.yaml
@@ -47,59 +47,12 @@ runs:
       name: Build Operator bundle
       shell: bash
       run: |
-        echo "Build Operator bundle"
-        if ! command -v kustomize &> /dev/null
-        then
-          echo "kustomize could not be found. Has it not been installed?"
-          exit 1
-        fi
-
-        if [ -z "${{ inputs.local-image-name }}" ]; then
-          echo "Error: local-image-name not defined"
-          exit 1
-        fi
-
-        if [ -z "${{ inputs.local-image-version }}" ]; then
-          echo "Error: local-image-version not defined"
-          exit 1
-        fi
-
-        if [ -z "${{ inputs.image-registry-push-host }}" ]; then
-          echo "Error: image-registry-push-host not defined"
-          exit 1
-        fi
-
-        if [ -z "${{ inputs.image-registry-pull-host }}" ]; then
-          echo "Error: image-registry-pull-host not defined"
-          exit 1
-        fi
-
-        #
-        # Build with the PUSH host to ensure the correct image:tag
-        # for docker to push the image.
-        #
-        export LOCAL_IMAGE_BUNDLE=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }}
-        export CUSTOM_IMAGE=${{ inputs.local-image-name }}
-
-        export PREV_XY_CHANNEL=stable-$(make get-last-released-version | grep -Po "\d.\d")
-        echo "PREV_XY_CHANNEL=${PREV_XY_CHANNEL}" >> $GITHUB_ENV
-        export NEW_XY_CHANNEL=stable-$(make get-version | grep -Po "\d.\d")
-        echo "NEW_XY_CHANNEL=${NEW_XY_CHANNEL}" >> $GITHUB_ENV
-
-        make bundle-build \
-          BUNDLE_IMAGE_NAME=${LOCAL_IMAGE_BUNDLE} \
-          DEFAULT_CHANNEL="${NEW_XY_CHANNEL}" \
-          CHANNELS="${NEW_XY_CHANNEL}"
-
-        docker push ${LOCAL_IMAGE_BUNDLE}
-
-        #
-        # Use the PULL host to ensure the correct image:tag
-        # is passed into the tests for the deployment to pull from
-        #
-        BUILD_BUNDLE_LOCAL_IMAGE="${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }}"
-        echo "::set-output name=build-bundle-local-image::${BUILD_BUNDLE_LOCAL_IMAGE}"
-
+        ./.github/actions/kamel-build-bundle/build-bundle-image.sh \
+          -i "${{ inputs.image-namespace }}" \
+          -l "${{ inputs.image-registry-pull-host }}" \
+          -n "${{ inputs.local-image-name }}" \
+          -s "${{ inputs.image-registry-push-host }}" \
+          -v "${{ inputs.local-image-version }}"
 
     - id: install-opm
       name: Install opm if required
@@ -116,121 +69,22 @@ runs:
       name: Create New Index Image
       shell: bash
       run: |
-        export LOCAL_IIB=${{ inputs.image-registry-push-host }}/${{ inputs.image-namespace }}/camel-k-iib:${{ inputs.local-image-version }}
-        if ! command -v opm &> /dev/null
-        then
-          echo "opm could not be found. Has it not been installed?"
-          exit 1
-        fi
-
-        # Shorten the vars
-        PUSH_REGISTRY=${{ inputs.image-registry-push-host }}
-        PULL_REGISTRY=${{ inputs.image-registry-pull-host }}
-
-        #
-        # opm requires an active pull registry from which to verify (if not download) the bundle image
-        # Since the image-registry-pull-host may not be visible (eg. in the case of openshift), we need
-        # to fake the registry to allow opm to complete its task of creating an index image.
-        #
-        # 1. Add and alias to the hosts file for the name of the image-registry
-        # 2. Run a container of registry:2 docker image on the same port as the image-registry (port 80 if not present)
-        # 3. Tag and them push the image to the registry using docker
-        # 4. Run opm
-        #
-
-        if [ "${PULL_REGISTRY}" != "${PUSH_REGISTRY}" ]; then
-          #
-          # With the registry interfaces different then good chance that
-          # pull registry is not externally accessible, eg. openshift
-          #
-
-          PULL_HOST=$(echo ${PULL_REGISTRY} | sed -e 's/\(.*\):.*/\1/')
-          PULL_PORT=$(echo ${PULL_REGISTRY} | sed -e 's/.*:\([0-9]\+\).*/\1/')
-          if [ -z "${PULL_PORT}" ]; then
-            # Use standard http port
-            PULL_PORT=80
-          fi
-
-          echo "Impersonating registry at ${PULL_HOST}:${PULL_PORT}"
-
-          #
-          # Update both ipv4 and ipv6 addresses if they exist
-          # 127.0.0.1 localhost
-          # ::1     localhost ip6-localhost ip6-loopback
-          sudo sed -i "s/\(localhost.*\)/\1 ${PULL_HOST}/g" /etc/hosts
-
-          #
-          # Bring up the registry:2 instance if not already started
-          #
-          reg=$(docker ps -q -f name=triage-registry)
-          if [ -z "${reg}" ]; then
-            docker run -d -p ${PULL_PORT}:5000 --name triage-registry registry:2
-          fi
-
-          #
-          # Tag the bundle image
-          #
-          docker tag \
-            ${PUSH_REGISTRY}/${{ inputs.image-namespace }}/camel-k-bundle:${{ inputs.local-image-version }} \
-            ${{ steps.build-bundle-image.outputs.build-bundle-local-image }}
-
-          # Push the bundle image to the registry
-          #
-          docker push ${{ steps.build-bundle-image.outputs.build-bundle-local-image }}
-        fi
-
-        #
-        # Construct an index image containing the newly built bundle image
-        #   Bug:
-        #     https://github.com/operator-framework/operator-registry/issues/870
-        #   Workaround:
-        #     image catalog layers contain root owned files so fails with `permission denied` error.
-        #     Running with sudo fixes this error (alternative is to switch to podman)
-        #
-        sudo opm index add \
-          -c docker --skip-tls \
-          --bundles ${{ steps.build-bundle-image.outputs.build-bundle-local-image }} \
-          --from-index quay.io/operatorhubio/catalog:latest \
-          --tag ${LOCAL_IIB}
-
-        docker push ${LOCAL_IIB}
-        BUILD_BUNDLE_LOCAL_IMAGE_BUNDLE_INDEX="${{ inputs.image-registry-pull-host }}/${{ inputs.image-namespace }}/camel-k-iib:${{ inputs.local-image-version }}"
-        echo "::set-output name=build-bundle-image-bundle-index::${BUILD_BUNDLE_LOCAL_IMAGE_BUNDLE_INDEX}"
+        ./.github/actions/kamel-build-bundle/build-index-image.sh \
+          -b "${{ steps.build-bundle-image.outputs.build-bundle-local-image }}" \
+          -i "${{ inputs.image-namespace }}" \
+          -l "${{ inputs.image-registry-pull-host }}" \
+          -n "${{ inputs.local-image-name }}" \
+          -s "${{ inputs.image-registry-push-host }}" \
+          -v "${{ inputs.local-image-version }}"
 
     - id: build-image-catalog
       name: Create a new catalog to host the index image
       shell: bash
       run: |
-
-        if [ -z "${{ inputs.catalog-source-namespace }}" ]; then
-          echo "No catalog source namespace defined ... skipping catalog source creation"
-          exit 0
-        fi
-
-        kubectl get ns ${{ inputs.catalog-source-namespace }} &> /dev/null
-        if [ $? != 0 ]; then
-          echo "Error: Catalog source cannot be created as namespace ${{ inputs.catalog-source-namespace }} does not exist."
-          exit 1
-        fi
-
-        export BUILD_CATALOG_SOURCE="camel-k-test-source"
-        echo "::set-output name=build-bundle-catalog-source-name::${BUILD_CATALOG_SOURCE}"
-
-        cat <<EOF | kubectl apply -f -
-        apiVersion: operators.coreos.com/v1alpha1
-        kind: CatalogSource
-        metadata:
-          name: ${BUILD_CATALOG_SOURCE}
-          namespace: ${{ inputs.image-namespace }}
-        spec:
-          displayName: OLM upgrade test Catalog
-          image: ${{ steps.build-index-image.outputs.build-bundle-image-bundle-index }}
-          sourceType: grpc
-          publisher: grpc
-          updateStrategy:
-            registryPoll:
-              interval: 1m0s
-        EOF
+        ./.github/actions/kamel-build-bundle/build-image-catalog.sh \
+          -c "${{ inputs.catalog-source-namespace }}" \
+          -i "${{ inputs.image-namespace }}" \
+          -x "${{ steps.build-index-image.outputs.build-bundle-image-bundle-index }}"
 
 outputs:
   build-bundle-local-image:
diff --git a/.github/actions/kamel-build-bundle/build-bundle-image.sh b/.github/actions/kamel-build-bundle/build-bundle-image.sh
new file mode 100755
index 0000000..4844499
--- /dev/null
+++ b/.github/actions/kamel-build-bundle/build-bundle-image.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Builds the kamel bundle image
+#
+####
+
+set -e
+
+while getopts ":i:l:n:s:v:" opt; do
+  case "${opt}" in
+    i)
+      IMAGE_NAMESPACE=${OPTARG}
+      ;;
+    l)
+      REGISTRY_PULL_HOST=${OPTARG}
+      ;;
+    n)
+      IMAGE_NAME=${OPTARG}
+      ;;
+    s)
+      REGISTRY_PUSH_HOST=${OPTARG}
+      ;;
+    v)
+      IMAGE_VERSION=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+echo "Build Operator bundle"
+if ! command -v kustomize &> /dev/null
+then
+  echo "kustomize could not be found. Has it not been installed?"
+  exit 1
+fi
+
+if [ -z "${IMAGE_NAME}" ]; then
+  echo "Error: local-image-name not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_VERSION}" ]; then
+  echo "Error: local-image-version not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_NAMESPACE}" ]; then
+  echo "Error: image-namespace not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_PUSH_HOST}" ]; then
+  echo "Error: image-registry-push-host not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_PULL_HOST}" ]; then
+  echo "Error: image-registry-pull-host not defined"
+  exit 1
+fi
+
+#
+# Build with the PUSH host to ensure the correct image:tag
+# for docker to push the image.
+#
+export LOCAL_IMAGE_BUNDLE=${REGISTRY_PUSH_HOST}/${IMAGE_NAMESPACE}/camel-k-bundle:${IMAGE_VERSION}
+export CUSTOM_IMAGE=${IMAGE_NAME}
+
+export PREV_XY_CHANNEL="stable-$(make get-last-released-version | grep -Po '\d.\d')"
+echo "PREV_XY_CHANNEL=${PREV_XY_CHANNEL}" >> $GITHUB_ENV
+export NEW_XY_CHANNEL=stable-$(make get-version | grep -Po "\d.\d")
+echo "NEW_XY_CHANNEL=${NEW_XY_CHANNEL}" >> $GITHUB_ENV
+
+make bundle-build \
+  BUNDLE_IMAGE_NAME=${LOCAL_IMAGE_BUNDLE} \
+  DEFAULT_CHANNEL="${NEW_XY_CHANNEL}" \
+  CHANNELS="${NEW_XY_CHANNEL}"
+
+docker push ${LOCAL_IMAGE_BUNDLE}
+
+#
+# Use the PULL host to ensure the correct image:tag
+# is passed into the tests for the deployment to pull from
+#
+BUILD_BUNDLE_LOCAL_IMAGE="${REGISTRY_PULL_HOST}/${IMAGE_NAMESPACE}/camel-k-bundle:${IMAGE_VERSION}"
+echo "Setting build-bundle-local-image to ${BUILD_BUNDLE_LOCAL_IMAGE}"
+echo "::set-output name=build-bundle-local-image::${BUILD_BUNDLE_LOCAL_IMAGE}"
diff --git a/.github/actions/kamel-build-bundle/build-image-catalog.sh b/.github/actions/kamel-build-bundle/build-image-catalog.sh
new file mode 100755
index 0000000..bde0633
--- /dev/null
+++ b/.github/actions/kamel-build-bundle/build-image-catalog.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Builds the kamel bundle index image
+#
+####
+
+set -e
+
+while getopts ":c:i:x:" opt; do
+  case "${opt}" in
+    c)
+      CATALOG_SOURCE_NAMESPACE=${OPTARG}
+      ;;
+    i)
+      IMAGE_NAMESPACE=${OPTARG}
+      ;;
+    x)
+      BUNDLE_IMAGE_INDEX=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+if [ -z "${CATALOG_SOURCE_NAMESPACE}" ]; then
+  echo "No catalog source namespace defined ... skipping catalog source creation"
+  exit 0
+fi
+
+if [ -z "${IMAGE_NAMESPACE}" ]; then
+  echo "Error: image-namespace not defined"
+  exit 1
+fi
+
+if [ -z "${BUNDLE_IMAGE_INDEX}" ]; then
+  echo "Error: build-bundle-image-bundle-index not defined"
+  exit 1
+fi
+
+kubectl get ns ${CATALOG_SOURCE_NAMESPACE} &> /dev/null
+if [ $? != 0 ]; then
+  echo "Error: Catalog source cannot be created as namespace ${CATALOG_SOURCE_NAMESPACE} does not exist."
+  exit 1
+fi
+
+export BUILD_CATALOG_SOURCE="camel-k-test-source"
+echo "Setting build-bundle-catalog-source-name to ${BUILD_CATALOG_SOURCE}"
+echo "::set-output name=build-bundle-catalog-source-name::${BUILD_CATALOG_SOURCE}"
+
+cat <<EOF | kubectl apply -f -
+apiVersion: operators.coreos.com/v1alpha1
+kind: CatalogSource
+metadata:
+  name: ${BUILD_CATALOG_SOURCE}
+  namespace: ${IMAGE_NAMESPACE}
+spec:
+  displayName: OLM upgrade test Catalog
+  image: ${BUNDLE_IMAGE_INDEX}
+  sourceType: grpc
+  publisher: grpc
+  updateStrategy:
+    registryPoll:
+      interval: 1m0s
+EOF
diff --git a/.github/actions/kamel-build-bundle/build-index-image.sh b/.github/actions/kamel-build-bundle/build-index-image.sh
new file mode 100755
index 0000000..e3f1d8b
--- /dev/null
+++ b/.github/actions/kamel-build-bundle/build-index-image.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Builds the kamel bundle index image
+#
+####
+
+set -e
+
+while getopts ":b:i:l:n:s:v:" opt; do
+  case "${opt}" in
+    b)
+      BUNDLE_IMAGE=${OPTARG}
+      ;;
+    i)
+      IMAGE_NAMESPACE=${OPTARG}
+      ;;
+    l)
+      REGISTRY_PULL_HOST=${OPTARG}
+      ;;
+    n)
+      IMAGE_NAME=${OPTARG}
+      ;;
+    s)
+      REGISTRY_PUSH_HOST=${OPTARG}
+      ;;
+    v)
+      IMAGE_VERSION=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+if [ -z "${BUNDLE_IMAGE}" ]; then
+  echo "Error: build-bundle-local-image not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_NAME}" ]; then
+  echo "Error: local-image-name not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_VERSION}" ]; then
+  echo "Error: local-image-version not defined"
+  exit 1
+fi
+
+if [ -z "${IMAGE_NAMESPACE}" ]; then
+  echo "Error: image-namespace not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_PUSH_HOST}" ]; then
+  echo "Error: image-registry-push-host not defined"
+  exit 1
+fi
+
+if [ -z "${REGISTRY_PULL_HOST}" ]; then
+  echo "Error: image-registry-pull-host not defined"
+  exit 1
+fi
+
+export LOCAL_IIB=${REGISTRY_PUSH_HOST}/${IMAGE_NAMESPACE}/camel-k-iib:${IMAGE_VERSION}
+if ! command -v opm &> /dev/null
+then
+  echo "opm could not be found. Has it not been installed?"
+  exit 1
+fi
+
+# Shorten the vars
+PUSH_REGISTRY=${REGISTRY_PUSH_HOST}
+PULL_REGISTRY=${REGISTRY_PULL_HOST}
+
+#
+# opm requires an active pull registry from which to verify (if not download) the bundle image
+# Since the image-registry-pull-host may not be visible (eg. in the case of openshift), we need
+# to fake the registry to allow opm to complete its task of creating an index image.
+#
+# 1. Add and alias to the hosts file for the name of the image-registry
+# 2. Run a container of registry:2 docker image on the same port as the image-registry (port 80 if not present)
+# 3. Tag and them push the image to the registry using docker
+# 4. Run opm
+#
+
+if [ "${PULL_REGISTRY}" != "${PUSH_REGISTRY}" ]; then
+  #
+  # With the registry interfaces different then good chance that
+  # pull registry is not externally accessible, eg. openshift
+  #
+
+  PULL_HOST=$(echo ${PULL_REGISTRY} | sed -e 's/\(.*\):.*/\1/')
+  PULL_PORT=$(echo ${PULL_REGISTRY} | sed -e 's/.*:\([0-9]\+\).*/\1/')
+  if [ -z "${PULL_PORT}" ]; then
+    # Use standard http port
+    PULL_PORT=80
+  fi
+
+  echo "Impersonating registry at ${PULL_HOST}:${PULL_PORT}"
+
+  #
+  # Update both ipv4 and ipv6 addresses if they exist
+  # 127.0.0.1 localhost
+  # ::1     localhost ip6-localhost ip6-loopback
+  sudo sed -i "s/\(localhost.*\)/\1 ${PULL_HOST}/g" /etc/hosts
+
+  #
+  # Bring up the registry:2 instance if not already started
+  #
+  reg=$(docker ps -a -q -f name=triage-registry)
+  if [ -n "${reg}" ]; then
+    docker stop triage-registry
+    docker rm triage-registry
+  fi
+
+  docker run -d -p ${PULL_PORT}:5000 --name triage-registry registry:2
+
+  #
+  # Tag the bundle image
+  #
+  docker tag \
+    ${PUSH_REGISTRY}/${IMAGE_NAMESPACE}/camel-k-bundle:${IMAGE_VERSION} \
+    ${BUNDLE_IMAGE}
+
+  # Push the bundle image to the registry
+  #
+  docker push ${BUNDLE_IMAGE}
+fi
+
+#
+# Construct an index image containing the newly built bundle image
+#   Bug:
+#     https://github.com/operator-framework/operator-registry/issues/870
+#   Workaround:
+#     image catalog layers contain root owned files so fails with `permission denied` error.
+#     Running with sudo fixes this error (alternative is to switch to podman)
+#
+sudo opm index add \
+  -c docker --skip-tls \
+  --bundles ${BUNDLE_IMAGE} \
+  --from-index quay.io/operatorhubio/catalog:latest \
+  --tag ${LOCAL_IIB}
+
+docker push ${LOCAL_IIB}
+BUILD_BUNDLE_LOCAL_IMAGE_BUNDLE_INDEX="${REGISTRY_PULL_HOST}/${IMAGE_NAMESPACE}/camel-k-iib:${IMAGE_VERSION}"
+echo "Setting build-bundle-image-bundle-index to ${BUILD_BUNDLE_LOCAL_IMAGE_BUNDLE_INDEX}"
+echo "::set-output name=build-bundle-image-bundle-index::${BUILD_BUNDLE_LOCAL_IMAGE_BUNDLE_INDEX}"
diff --git a/.github/actions/kamel-cleanup/action.yaml b/.github/actions/kamel-cleanup/action.yaml
index aadc8a4..2f970a5 100644
--- a/.github/actions/kamel-cleanup/action.yaml
+++ b/.github/actions/kamel-cleanup/action.yaml
@@ -31,30 +31,5 @@ runs:
       shell: bash
       if: ${{ always() }}
       run: |
-        set +e
-        if command -v kamel &> /dev/null
-        then
-          kamel uninstall --olm=false --all
-        fi
-
-        # Ensure the CRDs are removed
-        kubectl get crds | grep camel | awk '{print $1}' | xargs kubectl delete crd &> /dev/null
-        set -e
-
-    - id: remove-kamel-catalog-source
-      name: Remove Catalog Source
-      shell: bash
-      if: ${{ always() }}
-      run: |
-        if [ -z "${{ inputs.build-bundle-catalog-source-name }}" ]; then
-          # Catalog source never defined so nothing to do
-          exit 0
-        fi
-
-        set +e
-        CATALOG_NS=$(kubectl get catalogsource --all-namespaces | grep ${{ inputs.build-bundle-catalog-source-name }} | awk {'print $1'})
-        for ns in ${CATALOG_NS}
-        do
-          kubectl delete CatalogSource ${{ inputs.build-bundle-catalog-source-name }} -n ${ns}
-        done
-        set -e
+        ./.github/actions/kamel-cleanup/cleanup.sh \
+          -c "${{ inputs.build-bundle-catalog-source-name }}"
diff --git a/.github/actions/kamel-cleanup/cleanup.sh b/.github/actions/kamel-cleanup/cleanup.sh
new file mode 100755
index 0000000..03875dc
--- /dev/null
+++ b/.github/actions/kamel-cleanup/cleanup.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Perform a cleanup of the test suite
+#
+####
+
+set -e
+
+while getopts ":c:" opt; do
+  case "${opt}" in
+    c)
+      BUILD_CATALOG_SOURCE=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+#
+# Remove installed kamel
+#
+set +e
+if command -v kamel &> /dev/null
+then
+  kamel uninstall --olm=false --all
+fi
+
+# Ensure the CRDs are removed
+kubectl get crds | grep camel | awk '{print $1}' | xargs kubectl delete crd &> /dev/null
+set -e
+
+#
+# Remove Catalog Source
+#
+if [ -z "${BUILD_CATALOG_SOURCE}" ]; then
+  # Catalog source never defined so nothing to do
+  exit 0
+fi
+
+set +e
+CATALOG_NS=$(kubectl get catalogsource --all-namespaces | grep ${BUILD_CATALOG_SOURCE} | awk {'print $1'})
+for ns in ${CATALOG_NS}
+do
+  kubectl delete CatalogSource ${BUILD_CATALOG_SOURCE} -n ${ns}
+done
+set -e
diff --git a/.github/actions/kamel-install-cluster-setup/action.yml b/.github/actions/kamel-install-cluster-setup/action.yml
index a0f17ae..4cc48fd 100644
--- a/.github/actions/kamel-install-cluster-setup/action.yml
+++ b/.github/actions/kamel-install-cluster-setup/action.yml
@@ -30,25 +30,8 @@ runs:
       name: Install Camel-K Cluster Resources
       shell: bash
       run: |
-        #
-        # Get current context
-        #
-        ctx=$(kubectl config current-context)
-
-        #
-        # Need to be admin so switch to the admin context
-        #
-        kubectl config use-context "${{ inputs.kube-admin-user-ctx }}"
-
-        #
-        # Ensure built binary CRDs are always installed by turning off olm
-        #
-        kamel install --cluster-setup --olm=false
-
-        #
-        # Change back to original context
-        #
-        kubectl config use-context "${ctx}"
+        ./.github/actions/kamel-install-cluster-setup/install-cluster-setup.sh \
+          -a "${{ inputs.kube-admin-user-ctx }}"
 
     - id: post-execution
       shell: bash
diff --git a/.github/actions/kamel-install-cluster-setup/install-cluster-setup.sh b/.github/actions/kamel-install-cluster-setup/install-cluster-setup.sh
new file mode 100755
index 0000000..36a706b
--- /dev/null
+++ b/.github/actions/kamel-install-cluster-setup/install-cluster-setup.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ---------------------------------------------------------------------------
+
+####
+#
+# Install the kamel setup using the admin context
+#
+####
+
+set -e
+
+while getopts ":a:" opt; do
+  case "${opt}" in
+    a)
+      KUBE_ADMIN_CTX=${OPTARG}
+      ;;
+    :)
+      echo "ERROR: Option -$OPTARG requires an argument"
+      exit 1
+      ;;
+    \?)
+      echo "ERROR: Invalid option -$OPTARG"
+      exit 1
+      ;;
+  esac
+done
+shift $((OPTIND-1))
+
+if [ -z "${KUBE_ADMIN_CTX}" ]; then
+  echo "Error: kube-admin-user-ctx not defined"
+  exit 1
+fi
+
+#
+# Get current context
+#
+ctx=$(kubectl config current-context)
+
+#
+# Need to be admin so switch to the admin context
+#
+kubectl config use-context "${KUBE_ADMIN_CTX}"
+
+#
+# Ensure built binary CRDs are always installed by turning off olm
+#
+kamel install --cluster-setup --olm=false
+
+#
+# Change back to original context
+#
+kubectl config use-context "${ctx}"