From b7dcee73a0a8421b1ad2bcddbad6af091c257d56 Mon Sep 17 00:00:00 2001 From: David Kornel Date: Thu, 19 Mar 2026 15:21:57 +0100 Subject: [PATCH 1/3] Integration gh workflow for test install and uninstall Signed-off-by: David Kornel --- .github/actions/smoke-test/action.yaml | 73 +++++++++++++++++++ .github/actions/smoke-test/kind-config.yaml | 17 +++++ .github/workflows/integration.yaml | 48 ++++++++++++ .github/workflows/validate.yaml | 13 ++-- .gitignore | 9 +++ .idea/.gitignore | 10 +++ README.md | 44 +++++++++++ .../kustomization.yaml | 2 +- 8 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 .github/actions/smoke-test/action.yaml create mode 100644 .github/actions/smoke-test/kind-config.yaml create mode 100644 .github/workflows/integration.yaml create mode 100644 .gitignore create mode 100644 .idea/.gitignore diff --git a/.github/actions/smoke-test/action.yaml b/.github/actions/smoke-test/action.yaml new file mode 100644 index 0000000..3765c7f --- /dev/null +++ b/.github/actions/smoke-test/action.yaml @@ -0,0 +1,73 @@ +name: 'Smoke Test' +description: 'Install, verify, uninstall, and debug the developer quickstart' + +inputs: + timeout: + description: 'Timeout for install/uninstall scripts' + required: false + default: '300s' + +runs: + using: 'composite' + steps: + - name: Run install script + shell: bash + run: LOCAL_DIR=. TIMEOUT=${{ inputs.timeout }} ./install.sh + + - name: Verify deployments + shell: bash + run: | + echo "--- Strimzi operator ---" + kubectl get deployment -n strimzi strimzi-cluster-operator + echo "--- Apicurio Registry operator ---" + kubectl get deployment -n apicurio-registry apicurio-registry-operator + echo "--- StreamsHub Console operator ---" + kubectl get deployment -n streamshub-console streamshub-console-operator + + echo "--- Kafka cluster ---" + kubectl wait kafka/dev-cluster --for=condition=Ready -n kafka --timeout=600s + echo "--- Apicurio Registry instance ---" + kubectl wait apicurioregistry3/apicurio-registry --for=condition=Ready -n apicurio-registry --timeout=600s + echo "--- StreamsHub Console instance ---" + kubectl wait console.console.streamshub.github.com/streamshub-console --for=condition=Ready -n streamshub-console --timeout=600s + + - name: Run uninstall script + shell: bash + run: LOCAL_DIR=. TIMEOUT=${{ inputs.timeout }} ./uninstall.sh + + - name: Verify uninstall + shell: bash + run: | + echo "--- Checking for remaining quick-start resources ---" + remaining=$(kubectl get all -A -l app.kubernetes.io/part-of=streamshub-developer-quickstart --no-headers 2>/dev/null | wc -l | tr -d ' ') + if [ "$remaining" -gt 0 ]; then + echo "ERROR: Found $remaining remaining resources after uninstall:" + kubectl get all -A -l app.kubernetes.io/part-of=streamshub-developer-quickstart + exit 1 + fi + echo "All quick-start resources successfully removed" + + - name: Debug on failure + if: failure() + shell: bash + run: | + echo "=== CR status ===" + kubectl get apicurioregistry3/apicurio-registry -n apicurio-registry -o yaml 2>/dev/null || true + kubectl get kafka/dev-cluster -n kafka -o yaml 2>/dev/null || true + kubectl get console.console.streamshub.github.com/streamshub-console -n streamshub-console -o yaml 2>/dev/null || true + echo "" + echo "=== Events (all namespaces) ===" + kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -50 + echo "" + echo "=== Pods (all namespaces) ===" + kubectl get pods --all-namespaces + echo "" + for ns in strimzi kafka apicurio-registry streamshub-console; do + echo "=== Pods in ${ns} ===" + kubectl get pods -n "${ns}" -o wide 2>/dev/null || true + echo "=== Pod logs in ${ns} ===" + for pod in $(kubectl get pods -n "${ns}" -o name 2>/dev/null); do + echo "--- ${pod} ---" + kubectl logs "${pod}" -n "${ns}" --tail=30 2>/dev/null || true + done + done diff --git a/.github/actions/smoke-test/kind-config.yaml b/.github/actions/smoke-test/kind-config.yaml new file mode 100644 index 0000000..89ded6b --- /dev/null +++ b/.github/actions/smoke-test/kind-config.yaml @@ -0,0 +1,17 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml new file mode 100644 index 0000000..488beac --- /dev/null +++ b/.github/workflows/integration.yaml @@ -0,0 +1,48 @@ +name: Integration Test + +on: + push: + branches: + - main + pull_request: + +jobs: + smoke-minikube: + name: smoke-minikube + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Start Minikube + id: minikube + uses: medyagh/setup-minikube@e9e035a86bbc3caea26a450bd4dbf9d0c453682e # v0.0.21 + with: + minikube-version: 'latest' + addons: registry,ingress,ingress-dns + insecure-registry: 'localhost:5000,10.0.0.0/24' + start-args: '--extra-config=kubeadm.ignore-preflight-errors=SystemVerification --extra-config=apiserver.authorization-mode=RBAC,Node' + + - name: Smoke test + uses: ./.github/actions/smoke-test + + smoke-kind: + name: smoke-kind + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Create Kind cluster + uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 + with: + config: .github/actions/smoke-test/kind-config.yaml + + - name: Deploy ingress-nginx + run: | + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.1/deploy/static/provider/kind/deploy.yaml + kubectl wait --namespace ingress-nginx \ + --for=condition=Ready pod \ + --selector=app.kubernetes.io/component=controller \ + --timeout=120s + + - name: Smoke test + uses: ./.github/actions/smoke-test diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 42b3a61..b5ca400 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -2,7 +2,8 @@ name: Validate on: push: - branches: [main] + branches: + - main pull_request: jobs: @@ -10,10 +11,10 @@ jobs: name: Validate Kustomize configs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up kubectl - uses: azure/setup-kubectl@v4 + uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4.0.1 - name: Build base layer run: kubectl kustomize base/ @@ -33,10 +34,10 @@ jobs: name: Lint shell scripts runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run ShellCheck - uses: ludeeus/action-shellcheck@2.0.0 + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 with: version: v0.11.0 scandir: "." @@ -46,7 +47,7 @@ jobs: name: Lint YAML files runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install yamllint run: | diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c8dfaf --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# VSCode +.vscode + +# IntelliJ IDEA specific +.idea/ +*.iml + +### Mac OS ### +**.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/README.md b/README.md index c41cfd0..10eec81 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,50 @@ kubectl port-forward -n streamshub-console svc/streamshub-console-console-servic Open [http://localhost:8080](http://localhost:8080) in your browser. +### Kind + +When using Kind, create the cluster with ingress-ready port mappings: + +```bash +cat < Date: Mon, 23 Mar 2026 14:22:29 +0100 Subject: [PATCH 2/3] Address comments Signed-off-by: David Kornel --- .github/actions/smoke-test/action.yaml | 65 ++++++------------- .../smoke-test => config}/kind-config.yaml | 0 .github/config/overlays/base.env | 11 ++++ .github/scripts/debug.sh | 45 +++++++++++++ .github/scripts/verify-install.sh | 43 ++++++++++++ .github/scripts/verify-uninstall.sh | 17 +++++ .github/workflows/integration.yaml | 2 +- .idea/.gitignore | 10 --- 8 files changed, 136 insertions(+), 57 deletions(-) rename .github/{actions/smoke-test => config}/kind-config.yaml (100%) create mode 100644 .github/config/overlays/base.env create mode 100755 .github/scripts/debug.sh create mode 100755 .github/scripts/verify-install.sh create mode 100755 .github/scripts/verify-uninstall.sh delete mode 100644 .idea/.gitignore diff --git a/.github/actions/smoke-test/action.yaml b/.github/actions/smoke-test/action.yaml index 3765c7f..32bb91a 100644 --- a/.github/actions/smoke-test/action.yaml +++ b/.github/actions/smoke-test/action.yaml @@ -6,68 +6,41 @@ inputs: description: 'Timeout for install/uninstall scripts' required: false default: '300s' + overlay: + description: 'Overlay name for component verification (matches .github/config/overlays/.env)' + required: false + default: 'base' runs: using: 'composite' steps: - name: Run install script shell: bash - run: LOCAL_DIR=. TIMEOUT=${{ inputs.timeout }} ./install.sh + env: + LOCAL_DIR: . + TIMEOUT: ${{ inputs.timeout }} + run: ./install.sh - name: Verify deployments shell: bash - run: | - echo "--- Strimzi operator ---" - kubectl get deployment -n strimzi strimzi-cluster-operator - echo "--- Apicurio Registry operator ---" - kubectl get deployment -n apicurio-registry apicurio-registry-operator - echo "--- StreamsHub Console operator ---" - kubectl get deployment -n streamshub-console streamshub-console-operator - - echo "--- Kafka cluster ---" - kubectl wait kafka/dev-cluster --for=condition=Ready -n kafka --timeout=600s - echo "--- Apicurio Registry instance ---" - kubectl wait apicurioregistry3/apicurio-registry --for=condition=Ready -n apicurio-registry --timeout=600s - echo "--- StreamsHub Console instance ---" - kubectl wait console.console.streamshub.github.com/streamshub-console --for=condition=Ready -n streamshub-console --timeout=600s + env: + OVERLAY: ${{ inputs.overlay }} + run: .github/scripts/verify-install.sh - name: Run uninstall script shell: bash - run: LOCAL_DIR=. TIMEOUT=${{ inputs.timeout }} ./uninstall.sh + env: + LOCAL_DIR: . + TIMEOUT: ${{ inputs.timeout }} + run: ./uninstall.sh - name: Verify uninstall shell: bash - run: | - echo "--- Checking for remaining quick-start resources ---" - remaining=$(kubectl get all -A -l app.kubernetes.io/part-of=streamshub-developer-quickstart --no-headers 2>/dev/null | wc -l | tr -d ' ') - if [ "$remaining" -gt 0 ]; then - echo "ERROR: Found $remaining remaining resources after uninstall:" - kubectl get all -A -l app.kubernetes.io/part-of=streamshub-developer-quickstart - exit 1 - fi - echo "All quick-start resources successfully removed" + run: .github/scripts/verify-uninstall.sh - name: Debug on failure if: failure() shell: bash - run: | - echo "=== CR status ===" - kubectl get apicurioregistry3/apicurio-registry -n apicurio-registry -o yaml 2>/dev/null || true - kubectl get kafka/dev-cluster -n kafka -o yaml 2>/dev/null || true - kubectl get console.console.streamshub.github.com/streamshub-console -n streamshub-console -o yaml 2>/dev/null || true - echo "" - echo "=== Events (all namespaces) ===" - kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -50 - echo "" - echo "=== Pods (all namespaces) ===" - kubectl get pods --all-namespaces - echo "" - for ns in strimzi kafka apicurio-registry streamshub-console; do - echo "=== Pods in ${ns} ===" - kubectl get pods -n "${ns}" -o wide 2>/dev/null || true - echo "=== Pod logs in ${ns} ===" - for pod in $(kubectl get pods -n "${ns}" -o name 2>/dev/null); do - echo "--- ${pod} ---" - kubectl logs "${pod}" -n "${ns}" --tail=30 2>/dev/null || true - done - done + env: + OVERLAY: ${{ inputs.overlay }} + run: .github/scripts/debug.sh diff --git a/.github/actions/smoke-test/kind-config.yaml b/.github/config/kind-config.yaml similarity index 100% rename from .github/actions/smoke-test/kind-config.yaml rename to .github/config/kind-config.yaml diff --git a/.github/config/overlays/base.env b/.github/config/overlays/base.env new file mode 100644 index 0000000..e2ffc68 --- /dev/null +++ b/.github/config/overlays/base.env @@ -0,0 +1,11 @@ +# Components expected in the base (default) deployment. +# Used by verify-install.sh, verify-uninstall.sh, and debug.sh. +# +# Format: +# OPERATORS - "namespace:deployment" pairs (space-separated) +# CUSTOM_RESOURCES - "namespace:resource" pairs (space-separated) +# NAMESPACES - namespaces to inspect on failure (space-separated) + +OPERATORS="strimzi:strimzi-cluster-operator apicurio-registry:apicurio-registry-operator streamshub-console:streamshub-console-operator" +CUSTOM_RESOURCES="kafka:kafka/dev-cluster apicurio-registry:apicurioregistry3/apicurio-registry streamshub-console:console.console.streamshub.github.com/streamshub-console" +NAMESPACES="strimzi kafka apicurio-registry streamshub-console" diff --git a/.github/scripts/debug.sh b/.github/scripts/debug.sh new file mode 100755 index 0000000..f9e5137 --- /dev/null +++ b/.github/scripts/debug.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# +# Dump diagnostic information for debugging failed smoke tests. +# Reads component definitions from an overlay config file. +# +# Environment variables: +# OVERLAY - overlay name (default: "base") +# + +set +e + +OVERLAY="${OVERLAY:-base}" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/../config/overlays/${OVERLAY}.env" + +if [ ! -f "${CONFIG_FILE}" ]; then + echo "ERROR: Overlay config not found: ${CONFIG_FILE}" + exit 1 +fi + +# shellcheck source=../.github/config/overlays/base.env +source "${CONFIG_FILE}" + +echo "=== CR status ===" +for entry in ${CUSTOM_RESOURCES}; do + ns="${entry%%:*}" + resource="${entry#*:}" + kubectl get "${resource}" -n "${ns}" -o yaml 2>/dev/null || true +done +echo "" +echo "=== Events (all namespaces) ===" +kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -50 +echo "" +echo "=== Pods (all namespaces) ===" +kubectl get pods --all-namespaces +echo "" +for ns in ${NAMESPACES}; do + echo "=== Pods in ${ns} ===" + kubectl get pods -n "${ns}" -o wide 2>/dev/null || true + echo "=== Pod logs in ${ns} ===" + for pod in $(kubectl get pods -n "${ns}" -o name 2>/dev/null); do + echo "--- ${pod} ---" + kubectl logs "${pod}" -n "${ns}" --tail=30 2>/dev/null || true + done +done diff --git a/.github/scripts/verify-install.sh b/.github/scripts/verify-install.sh new file mode 100755 index 0000000..b360891 --- /dev/null +++ b/.github/scripts/verify-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# +# Verify that all expected deployments and custom resources are ready. +# Reads component definitions from an overlay config file. +# +# Environment variables: +# OVERLAY - overlay name (default: "base") +# TIMEOUT - kubectl wait timeout (default: "600s") +# + +set -euo pipefail + +OVERLAY="${OVERLAY:-base}" +TIMEOUT="${TIMEOUT:-600s}" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/../config/overlays/${OVERLAY}.env" + +if [ ! -f "${CONFIG_FILE}" ]; then + echo "ERROR: Overlay config not found: ${CONFIG_FILE}" + exit 1 +fi + +# shellcheck source=../.github/config/overlays/base.env +source "${CONFIG_FILE}" + +echo "=== Verifying install (overlay: ${OVERLAY}) ===" +echo "" + +for entry in ${OPERATORS}; do + ns="${entry%%:*}" + deploy="${entry#*:}" + echo "--- ${deploy} (${ns}) ---" + kubectl get deployment -n "${ns}" "${deploy}" +done + +echo "" + +for entry in ${CUSTOM_RESOURCES}; do + ns="${entry%%:*}" + resource="${entry#*:}" + echo "--- ${resource} (${ns}) ---" + kubectl wait "${resource}" --for=condition=Ready -n "${ns}" --timeout="${TIMEOUT}" +done diff --git a/.github/scripts/verify-uninstall.sh b/.github/scripts/verify-uninstall.sh new file mode 100755 index 0000000..232e922 --- /dev/null +++ b/.github/scripts/verify-uninstall.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# Verify that all quick-start resources have been removed after uninstall. +# + +set -euo pipefail + +QUICKSTART_LABEL="app.kubernetes.io/part-of=streamshub-developer-quickstart" + +echo "--- Checking for remaining quick-start resources ---" +remaining=$(kubectl get all -A -l "${QUICKSTART_LABEL}" --no-headers 2>/dev/null | wc -l | tr -d ' ') +if [ "$remaining" -gt 0 ]; then + echo "ERROR: Found $remaining remaining resources after uninstall:" + kubectl get all -A -l "${QUICKSTART_LABEL}" + exit 1 +fi +echo "All quick-start resources successfully removed" diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 488beac..b7eb86f 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -34,7 +34,7 @@ jobs: - name: Create Kind cluster uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 with: - config: .github/actions/smoke-test/kind-config.yaml + config: .github/config/kind-config.yaml - name: Deploy ingress-nginx run: | diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index ab1f416..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Ignored default folder with query files -/queries/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ From f1d25ed1f774775c996c7e101ddf6e8cbd705b74 Mon Sep 17 00:00:00 2001 From: David Kornel Date: Mon, 23 Mar 2026 14:24:34 +0100 Subject: [PATCH 3/3] Fix schellcheck Signed-off-by: David Kornel --- .github/scripts/debug.sh | 2 +- .github/scripts/verify-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/debug.sh b/.github/scripts/debug.sh index f9e5137..58c65ec 100755 --- a/.github/scripts/debug.sh +++ b/.github/scripts/debug.sh @@ -18,7 +18,7 @@ if [ ! -f "${CONFIG_FILE}" ]; then exit 1 fi -# shellcheck source=../.github/config/overlays/base.env +# shellcheck disable=SC1090 source "${CONFIG_FILE}" echo "=== CR status ===" diff --git a/.github/scripts/verify-install.sh b/.github/scripts/verify-install.sh index b360891..2418ee2 100755 --- a/.github/scripts/verify-install.sh +++ b/.github/scripts/verify-install.sh @@ -20,7 +20,7 @@ if [ ! -f "${CONFIG_FILE}" ]; then exit 1 fi -# shellcheck source=../.github/config/overlays/base.env +# shellcheck disable=SC1090 source "${CONFIG_FILE}" echo "=== Verifying install (overlay: ${OVERLAY}) ==="