Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
196 changes: 196 additions & 0 deletions .github/workflows/upgrade-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
name: Upgrade CI test

on:
# pull_request:
# branches:
# - main
push: # Runs on any direct push to any branch


jobs:
k8s:
runs-on: ubuntu-latest
steps:
- name: Checkout tackle
uses: actions/checkout@v2
with:
repository: konveyor/tackle
path: tackle

- name: Checkout to branch
uses: actions/checkout@v4

- name: Get Initial Branch Name
run: echo "INIT_BRANCH=$(git symbolic-ref --short HEAD)" >> $GITHUB_ENV

- name: Install operator-sdk
shell: bash
run: |
if command -v operator-sdk >/dev/null 2>&1; then
echo "operator-sdk is already installed...yay"
exit 0
fi
curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.35.0/operator-sdk_linux_amd64
sudo install -o root -g root -m 0755 operator-sdk_linux_amd64 /usr/local/bin/operator-sdk

- name: Install kubectl
shell: bash
run: |
if command -v kubectl >/dev/null 2>&1; then
echo "kubectl is already installed...yay"
exit 0
fi
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
- name: Installing oc binary
shell: bash
run: |
if command -v oc >/dev/null 2>&1; then
echo "oc is already installed...yay"
exit 0
fi
OC_VERSION=$(curl -s https://mirror.openshift.com/pub/openshift-v4/clients/ocp/stable/release.txt | grep 'Name:' | awk '{print $2}')
curl -LO "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/${OC_VERSION}/openshift-client-linux.tar.gz"
tar -xzf openshift-client-linux.tar.gz oc
sudo mv oc /usr/local/bin/oc
oc version --client
Comment on lines +52 to +56
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

oc binary also lacks checksum verification

You extract and install oc with root privileges but never validate the archive.
Add SHA-256 (or GPG) verification to avoid executing a tampered binary.

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml around lines 52 to 56, the script downloads
and installs the 'oc' binary without verifying its integrity. To fix this, add a
step to download the corresponding checksum file or signature, then verify the
downloaded archive's SHA-256 checksum or GPG signature before extracting and
installing it. This ensures the binary is authentic and untampered before
execution.


- name: Install opm cli
shell: bash
run: |
if command -v opm >/dev/null 2>&1; then
echo "opm is already installed"
exit 0
fi
export OPM_VERSION=$(curl -s https://api.github.com/repos/operator-framework/operator-registry/releases/latest | grep tag_name | cut -d '"' -f 4)

# Download the binary
curl -Lo opm-linux-amd64 "https://github.com/operator-framework/operator-registry/releases/download/${OPM_VERSION}/linux-amd64-opm"
chmod +x opm-linux-amd64
sudo mv opm-linux-amd64 /usr/local/bin/opm
opm version
Comment on lines +65 to +71
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Extend checksum/sig verification to the opm binary

The OPM CLI is fetched from GitHub and installed with root privileges, yet no integrity check is performed.
Add a SHA-256 (or GPG) verification step before mv.

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml around lines 53 to 59, the script downloads
the opm binary and installs it with root privileges but lacks integrity
verification. To fix this, add a step to download the corresponding SHA-256
checksum or GPG signature file for the opm binary, then verify the downloaded
binary against this checksum or signature before moving it to /usr/local/bin. If
the verification fails, the script should abort to prevent installing a
potentially tampered binary.


- name: Set Environment Variables
run: |
echo "QUAY_USERNAME=${{ secrets.QUAY_USERNAME }}" >> $GITHUB_ENV
echo "QUAY_PASSWORD=${{ secrets.QUAY_PASSWORD }}" >> $GITHUB_ENV

Comment on lines +73 to +77
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid echoing secrets in logs – set them via env: instead

Even though GitHub masks secret values, writing them to the log with echo is unnecessary and a potential foot-gun. Prefer the built-in env: map:

      - name: Set Quay credentials
        env:
          QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
          QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
        run: echo "Quay creds injected via environment"

This keeps logs clean and removes an extra file write to $GITHUB_ENV.

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml around lines 61 to 65, avoid echoing secrets
into the logs by removing the echo commands that write QUAY_USERNAME and
QUAY_PASSWORD to $GITHUB_ENV. Instead, set these secrets directly using the env:
map in the step definition to inject them as environment variables securely
without writing to files or logs.

- name: Create and push index image to quay
run: bash hack/create-index-image.sh

- name: Setup minikube
uses: konveyor/tackle2-operator/.github/actions/start-minikube@main
with:
memory: 'max'
cpus: 'max'

- name: Enable olm
run: minikube addons enable olm

- name: Enable ingress addon
run : minikube addons enable ingress

Comment on lines +90 to +92
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

run : is invalid YAML – the job will fail to parse
The extra space before the colon makes the key run invalid.

-      - name: Enable ingress addon
-        run : minikube addons enable ingress
+      - name: Enable ingress addon
+        run: minikube addons enable ingress
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Enable ingress addon
run : minikube addons enable ingress
- name: Enable ingress addon
run: minikube addons enable ingress
🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 79-79: too many spaces before colon

(colons)

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml at lines 78 to 80, the key `run` has an
extra space before the colon, making it invalid YAML syntax. Remove the space
before the colon so it reads `run:` instead of `run :` to fix the YAML parsing
error.

- name: Install Pre Upgrade konveyor
run: bash hack/install-preupgrade-konveyor.sh

- name: Set preupgrade konveyor value
run: |
konveyor_version=$(kubectl get csv -n konveyor-tackle -o=custom-columns=:spec.version | head -n 2 | tr -d '[:space:]')
echo "cypress_mtaVersion=$konveyor_version" >> $GITHUB_ENV
echo "Konveyor version: $konveyor_version"

- name: Display konveyor version for confirmation
run: |
echo "Confirming konveyor version from environment variable: $cypress_mtaVersion"
echo "Environment variable cypress_mtaVersion value: ${{ env.cypress_mtaVersion }}"

- name: Use mtaVersion
run: echo "Konveyor version is $cypress_mtaVersion"



- name: Check pod status
run: kubectl get pods -n konveyor-tackle

- name: Wait for Ingress
shell: bash
run: |
bash -c 'external_ip="";
echo $external_ip;
while [[ -z $external_ip ]]
do
echo "Waiting for end point..."
external_ip=$(kubectl get ingress tackle --template="{{range.status.loadBalancer.ingress}}{{.ip}}{{end}}" -n konveyor-tackle);[[ -z $external_ip ]] &&
echo $external_ip;
Comment on lines +120 to +124
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

kubectl get ingress … --template is wrong and loop can spin forever

  1. kubectl uses -o go-template='…' or -o jsonpath=; the --template flag is invalid and the command exits non-zero, so $external_ip is always empty ⇒ infinite loop.
  2. Variables are unquoted (SC2086) and there is no timeout.

Suggested fix:

-              external_ip=$(kubectl get ingress tackle --template="{{range.status.loadBalancer.ingress}}{{.ip}}{{end}}" -n konveyor-tackle);[[ -z $external_ip ]] &&
+              external_ip=$(kubectl get ingress tackle -n konveyor-tackle \
+                             -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) ||
+                true
+              [[ -z "$external_ip" ]] &&

And wrap the loop with a timeout, e.g. end=$((SECONDS+300))

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while [[ -z $external_ip ]]
do
echo "Waiting for end point..."
external_ip=$(kubectl get ingress tackle --template="{{range.status.loadBalancer.ingress}}{{.ip}}{{end}}" -n konveyor-tackle);[[ -z $external_ip ]] &&
echo $external_ip;
while [[ -z $external_ip ]]
do
echo "Waiting for end point..."
external_ip=$(kubectl get ingress tackle -n konveyor-tackle \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) || true
[[ -z "$external_ip" ]] && echo $external_ip;
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 100-100: trailing spaces

(trailing-spaces)


[error] 101-101: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml around lines 100 to 104, the kubectl command
incorrectly uses the invalid --template flag causing it to fail and the loop to
spin forever. Replace --template with the correct -o go-template flag and quote
all variable expansions to avoid word splitting issues. Additionally, add a
timeout mechanism to the loop by setting an end time (e.g.,
end=$((SECONDS+300))) and break the loop if the timeout is reached to prevent
infinite looping.

sleep 10;
done
echo "End point ready:" &&
echo $external_ip;
export endpoint=$(minikube ip);
echo "CYPRESS_tackleUrl=https://$endpoint" >>$GITHUB_ENV'
Comment on lines +129 to +130
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use the resolved ingress IP instead of Minikube’s node IP
You work hard to poll external_ip but then ignore it:

-          export endpoint=$(minikube ip);
-          echo "CYPRESS_tackleUrl=https://$endpoint" >>$GITHUB_ENV'
+          endpoint="$external_ip"
+          echo "CYPRESS_tackleUrl=https://$endpoint" >>"$GITHUB_ENV"

This ensures tests hit the actual ingress rather than the node-IP, which may not route correctly with ingress enabled.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export endpoint=$(minikube ip);
echo "CYPRESS_tackleUrl=https://$endpoint" >>$GITHUB_ENV'
endpoint="$external_ip"
echo "CYPRESS_tackleUrl=https://$endpoint" >>"$GITHUB_ENV"
🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml at lines 111-112, replace the use of
Minikube's node IP with the resolved ingress IP by using the previously polled
`external_ip` variable instead of calling `minikube ip`. Update the export line
to assign `endpoint` to the `external_ip` value so that the tests target the
ingress IP, ensuring correct routing through ingress.

git branch
Comment on lines +115 to +131
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Wait for Ingress loop can hang forever & misses quoting
The while-loop lacks a timeout and uses unquoted variable expansions flagged by ShellCheck (SC2086). A safer, bounded version:

-run: |
-  bash -c 'external_ip="";
-  ...
-  while [[ -z $external_ip ]]
-    do
-      ...
-    done
-  ...
-  echo "CYPRESS_tackleUrl=https://$endpoint" >>$GITHUB_ENV'
+run: |
+  set -eo pipefail
+  timeout=300  # 5 min
+  end=$((SECONDS+timeout))
+  while [[ -z "${external_ip:-}" && $SECONDS -lt $end ]]; do
+    echo "Waiting for ingress…"
+    external_ip=$(kubectl get ingress tackle -n konveyor-tackle \
+                  --template='{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}')
+    sleep 10
+  done
+  [[ -z $external_ip ]] && { echo "::error::Ingress not ready in ${timeout}s"; exit 1; }
+  echo "Ingress IP: $external_ip"
+  echo "CYPRESS_tackleUrl=https://$(minikube ip)" >> "$GITHUB_ENV"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Wait for Ingress
shell: bash
run: |
bash -c 'external_ip="";
echo $external_ip;
while [[ -z $external_ip ]]
do
echo "Waiting for end point..."
external_ip=$(kubectl get ingress tackle --template="{{range.status.loadBalancer.ingress}}{{.ip}}{{end}}" -n konveyor-tackle);[[ -z $external_ip ]] &&
echo $external_ip;
sleep 10;
done
echo "End point ready:" &&
echo $external_ip;
export endpoint=$(minikube ip);
echo "CYPRESS_tackleUrl=https://$endpoint" >>$GITHUB_ENV'
git branch
- name: Wait for Ingress
shell: bash
run: |
set -eo pipefail
timeout=300 # 5 min
end=$((SECONDS + timeout))
while [[ -z "${external_ip:-}" && SECONDS -lt end ]]; do
echo "Waiting for ingress…"
external_ip=$(kubectl get ingress tackle \
-n konveyor-tackle \
--template='{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}')
sleep 10
done
[[ -z $external_ip ]] && {
echo "::error::Ingress not ready in ${timeout}s"
exit 1
}
echo "Ingress IP: $external_ip"
echo "CYPRESS_tackleUrl=https://$(minikube ip)" >> "$GITHUB_ENV"
git branch
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 103-103: trailing spaces

(trailing-spaces)


[error] 104-104: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In .github/workflows/upgrade-ci.yml between lines 98 and 114, the 'Wait for
Ingress' step's while-loop can hang indefinitely and uses unquoted variable
expansions, which is unsafe. To fix this, add a timeout counter to break the
loop after a reasonable number of attempts, and quote all variable expansions
like "$external_ip" to prevent word splitting and globbing issues. This ensures
the loop terminates and the script is more robust.


- name: Checkout to release-0.6 branch
uses: actions/checkout@v4
with:
ref: release-0.6

- name: Install NPM
run: npm install .

- name: Set Keycloak admin password and git credentials
run: |
keycloak_password=$(kubectl get secret tackle-keycloak-sso -n konveyor-tackle -o=jsonpath='{.data.admin-password}' | base64 -d)
echo "cypress_keycloakAdminPassword=$keycloak_password" >> $GITHUB_ENV

- name: Run cypress login test
run: npx cypress run --spec "cypress/e2e/tests/login.test.ts" --env user="admin",pass="password",tackleUrl=${{ env.CYPRESS_tackleUrl }}

- name: Run Preupgrade test cases
run: |
CYPRESS_INCLUDE_TAGS=@pre-upgrade npx cypress run --spec cypress/e2e/tests/upgrade/create_upgrade_data.test.ts --env user=admin,pass=Dog8code,tackleUrl=${{ env.CYPRESS_tackleUrl }},git_user=${{ secrets.KONVEYOR_GIT_USER }},git_password=${{ secrets.KONVEYOR_GIT_PASSWORD }}

- uses: actions/upload-artifact@v4
if: failure()
with:
name: minikube-tests-screenshots
path: /home/runner/work/tackle-ui-tests/tackle-ui-tests/cypress/screenshots/

- name: Checkout to initial branch
run: git checkout $INIT_BRANCH


- name: Install Post Upgrade konveyor
run: git branch && bash hack/install-postupgrade-konveyor.sh


- name: Install NPM
run: npm install .


- name: Set postupgrade konveyor value
run: |
konveyor_version=$(kubectl get csv -n konveyor-tackle -o=custom-columns=:spec.version | head -n 2 | tr -d '[:space:]')
echo "cypress_mtaVersion=$konveyor_version" >> $GITHUB_ENV

- name: Set Keycloak admin password and git credentials (post-upgrade)
run: |
keycloak_password=$(kubectl get secret tackle-keycloak-sso -n konveyor-tackle -o=jsonpath='{.data.admin-password}' | base64 -d)
echo "cypress_keycloakAdminPassword=$keycloak_password" >> $GITHUB_ENV

- name: Use mtaVersion
run: echo "Konveyor version is $cypress_mtaVersion"


- name: Run cypress login test
run: npx cypress run --spec "cypress/e2e/tests/login.test.ts" --env user="admin",pass="Dog8code",tackleUrl=${{ env.CYPRESS_tackleUrl }}

- name: Run Post upgrade test cases
run: |
CYPRESS_INCLUDE_TAGS=@post-upgrade npx cypress run --spec cypress/e2e/tests/upgrade/after_upgrade.test.ts --env user=admin,pass=Dog8code,tackleUrl=${{ env.CYPRESS_tackleUrl }},git_user=${{ secrets.KONVEYOR_GIT_USER }},git_password=${{ secrets.KONVEYOR_GIT_PASSWORD }}

- uses: actions/upload-artifact@v4
if: failure()
with:
name: minikube-tests-screenshots
path: /home/runner/work/tackle-ui-tests/tackle-ui-tests/cypress/screenshots/
20 changes: 20 additions & 0 deletions hack/create-index-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

set -E
set -e
set -x
set -o pipefail

SOURCE_UPGRADE_BUNDLE_IMAGE="${OPERATOR_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:v0.6.0}"
TARGET_UPGRADE_BUNDLE_IMAGE="${OPERATOR_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:latest}"
Comment on lines +8 to +9
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Environment variable collision makes source ↔ target indistinguishable

Both variables fall back to the same OPERATOR_BUNDLE_IMAGE value.
If the env-var is set, you will end up building an index that contains the identical bundle twice, defeating the upgrade test.

-SOURCE_UPGRADE_BUNDLE_IMAGE="${OPERATOR_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:v0.6.0}"
-TARGET_UPGRADE_BUNDLE_IMAGE="${OPERATOR_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:latest}"
+# Allows callers to override each side independently
+SOURCE_UPGRADE_BUNDLE_IMAGE="${SOURCE_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:v0.6.0}"
+TARGET_UPGRADE_BUNDLE_IMAGE="${TARGET_BUNDLE_IMAGE:-quay.io/konveyor/tackle2-operator-bundle:latest}"
🤖 Prompt for AI Agents
In hack/create-index-image.sh around lines 8 to 9, both
SOURCE_UPGRADE_BUNDLE_IMAGE and TARGET_UPGRADE_BUNDLE_IMAGE use the same
environment variable OPERATOR_BUNDLE_IMAGE as fallback, causing them to be
identical if the variable is set. To fix this, use distinct environment
variables for source and target bundle images, for example,
OPERATOR_SOURCE_BUNDLE_IMAGE for SOURCE_UPGRADE_BUNDLE_IMAGE and
OPERATOR_TARGET_BUNDLE_IMAGE for TARGET_UPGRADE_BUNDLE_IMAGE, each with
appropriate default values, so the source and target bundles differ and the
upgrade test is valid.


echo 'Creating bundle image using $SOURCE_UPGRADE_BUNDLE_IMAGE and $TARGET_UPGRADE_BUNDLE_IMAGE'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Variables inside single quotes are not expanded

echo 'Creating bundle image using $SOURCE_UPGRADE_BUNDLE_IMAGE and $TARGET_UPGRADE_BUNDLE_IMAGE' prints the literal string.
Use double quotes so the actual images are logged.

-echo 'Creating bundle image using $SOURCE_UPGRADE_BUNDLE_IMAGE and $TARGET_UPGRADE_BUNDLE_IMAGE'
+echo "Creating bundle image using ${SOURCE_UPGRADE_BUNDLE_IMAGE} and ${TARGET_UPGRADE_BUNDLE_IMAGE}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo 'Creating bundle image using $SOURCE_UPGRADE_BUNDLE_IMAGE and $TARGET_UPGRADE_BUNDLE_IMAGE'
echo "Creating bundle image using ${SOURCE_UPGRADE_BUNDLE_IMAGE} and ${TARGET_UPGRADE_BUNDLE_IMAGE}"
🤖 Prompt for AI Agents
In hack/create-index-image.sh at line 11, the echo statement uses single quotes
which prevent variable expansion. Change the single quotes to double quotes so
that $SOURCE_UPGRADE_BUNDLE_IMAGE and $TARGET_UPGRADE_BUNDLE_IMAGE are expanded
and their values are printed in the log.


opm index add --bundles "${SOURCE_UPGRADE_BUNDLE_IMAGE}","${TARGET_UPGRADE_BUNDLE_IMAGE}" --tag quay.io/migqe/tackle2-operator-upgrade-index:latest

podman images

podman login -u="${QUAY_USERNAME}" -p="${QUAY_PASSWORD}" quay.io
podman push quay.io/migqe/tackle2-operator-upgrade-index:latest #To do , maybe change the tag from latest to the source/target versions.

echo 'Image pushed succesfully'
48 changes: 48 additions & 0 deletions hack/install-postupgrade-konveyor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
NAMESPACE="${NAMESPACE:-konveyor-tackle}"
TEMPLATE_DIR="${TEMPLATE_DIR:-hack/templates}"
KONVEYOR_UPGRADE_INDEX="${KONVEYOR_UPGRADE_INDEX:-quay.io/migqe/tackle2-operator-upgrade-index:latest}"
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add a proper she-bang and fail-fast flags

Without a she-bang the script inherits /bin/sh on many systems and ShellCheck (SC2148) complains.
set -euo pipefail prevents silent errors and unbound variables.

+#!/usr/bin/env bash
+set -euo pipefail
 NAMESPACE="${NAMESPACE:-konveyor-tackle}"
 TEMPLATE_DIR="${TEMPLATE_DIR:-hack/templates}"
 KONVEYOR_UPGRADE_INDEX="${KONVEYOR_UPGRADE_INDEX:-quay.io/migqe/tackle2-operator-upgrade-index:latest}"
🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In hack/install-postupgrade-konveyor.sh at the beginning of the file (lines 1 to
3), add a proper she-bang line such as #!/bin/bash to explicitly specify the
shell interpreter. Also, add the line set -euo pipefail after the she-bang to
enable fail-fast behavior, causing the script to exit on errors, unset
variables, or pipeline failures. This will improve script robustness and silence
ShellCheck SC2148 warnings.

SUBSCRIPTION_CHANNEL="${SUBSCRIPTION_CHANNEL:-development}"
PREUPGRADE_VERSION="${PREUPGRADE_VERSION:-0.6.0}"
POSTUPGRADE_VERSION="${POSTUPGRADE_VERSION:-99.0.0}" #Always the latest from main.
TIMEOUT=300 # Maximum wait time in seconds (5 minutes)
INTERVAL=10 # Time to wait between checks (10 seconds)
ELAPSED=0


echo "Patch subscription channel to ${SUBSCRIPTION_CHANNEL}"
kubectl patch sub konveyor-operator -n konveyor-tackle --type=merge -p "{\"spec\":{\"channel\":\"${SUBSCRIPTION_CHANNEL}\"}}"

Comment on lines +13 to +14
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Hard-coded namespace ignores the configurable $NAMESPACE
You export NAMESPACE at the top yet this line patches konveyor-tackle directly.

-kubectl patch sub konveyor-operator -n konveyor-tackle --type=merge -p "{\"spec\":{\"channel\":\"${SUBSCRIPTION_CHANNEL}\"}}"
+kubectl patch sub konveyor-operator -n "${NAMESPACE}" --type=merge \
+  -p "{\"spec\":{\"channel\":\"${SUBSCRIPTION_CHANNEL}\"}}"
🤖 Prompt for AI Agents
In hack/install-postupgrade-konveyor.sh at lines 13 to 14, the kubectl patch
command uses a hard-coded namespace 'konveyor-tackle' instead of the
configurable $NAMESPACE variable. Replace the hard-coded namespace with the
$NAMESPACE variable to respect the exported configuration and allow flexibility.

echo "Patching installplan for konveyor..."

kubectl patch installplan $(kubectl get installplan -n "${NAMESPACE}" | egrep "$POSTUPGRADE_VERSION"|awk '{print $1}') -n "${NAMESPACE}" --type merge --patch '{"spec":{"approved":true}}'

Comment on lines +17 to +18
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Quote command substitution to avoid word-splitting

If kubectl get installplan … returns multiple items the unquoted substitution
will be split and only the first token passed to patch, breaking the upgrade.

-kubectl patch installplan $(kubectl get installplan -n "${NAMESPACE}" | egrep "$POSTUPGRADE_VERSION"|awk '{print $1}') -n "${NAMESPACE}" --type merge --patch '{"spec":{"approved":true}}'
+kubectl patch installplan "$(kubectl get installplan -n "${NAMESPACE}" \
+  | grep -E "$POSTUPGRADE_VERSION" | awk '{print $1}')" \
+  -n "${NAMESPACE}" --type merge --patch '{"spec":{"approved":true}}'
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 17-17: Quote this to prevent word splitting.

(SC2046)

🤖 Prompt for AI Agents
In hack/install-postupgrade-konveyor.sh at lines 17 to 18, the command
substitution for getting the installplan names is unquoted, which can cause word
splitting if multiple installplans are returned. To fix this, enclose the
command substitution in double quotes to ensure the entire output is treated as
a single string, preventing incorrect splitting and ensuring all intended
installplans are passed correctly to the kubectl patch command.

kubectl wait --namespace "${NAMESPACE}" --for=condition=Successful --timeout=600s tackles.tackle.konveyor.io/tackle

kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=tackle-ui -n "${NAMESPACE}" --timeout=300s

echo "Waiting for UI pod to be replaced after upgrade..."
echo "Previous UI Pod: $PREUPGRADE_UI_POD"

while true; do
# Get the current UI pod name
UI_POD_AFTER=$(kubectl get pods -n "${NAMESPACE}" -l app.kubernetes.io/name=tackle-ui -o name)

# Check if the pod has changed
if [[ "$PREUPGRADE_UI_POD" != "$UI_POD_AFTER" ]]; then
echo "UI pod has changed! New pod: $UI_POD_AFTER"
break
fi

# Check if timeout is reached
if [[ "$ELAPSED" -ge "$TIMEOUT" ]]; then
echo "Timeout reached! Pod did not change within $TIMEOUT seconds."
exit 1 # Fail the script if pod did not bounce
fi

echo "Pod has not changed yet. Retrying in $INTERVAL seconds..."
sleep $INTERVAL
((ELAPSED+=INTERVAL))
done
Comment on lines +26 to +45
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Timeout loop never fails if PREUPGRADE_UI_POD is empty

When PREUPGRADE_UI_POD is not exported (e.g. previous script failed) the loop compares empty strings and exits immediately, giving a false positive.

Guard early:

[[ -z "${PREUPGRADE_UI_POD:-}" ]] && { echo "PREUPGRADE_UI_POD not set"; exit 1; }
🤖 Prompt for AI Agents
In hack/install-postupgrade-konveyor.sh around lines 26 to 45, the timeout loop
incorrectly succeeds immediately if PREUPGRADE_UI_POD is empty, causing a false
positive. Add an early guard before the loop to check if PREUPGRADE_UI_POD is
set and non-empty; if it is empty or unset, print an error message and exit with
failure to prevent the loop from running with invalid state.

sleep 200s

kubectl get po -n "${NAMESPACE}"
36 changes: 36 additions & 0 deletions hack/install-preupgrade-konveyor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
NAMESPACE="${NAMESPACE:-konveyor-tackle}"
TEMPLATE_DIR="${TEMPLATE_DIR:-hack/templates}"
KONVEYOR_UPGRADE_INDEX="${KONVEYOR_UPGRADE_INDEX:-quay.io/migqe/tackle2-operator-upgrade-index:latest}"
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Missing shebang & strict mode

Without #!/usr/bin/env bash the shell is undetermined (SC2148).
Add strict flags while you’re at it:

#!/usr/bin/env bash
set -Eeuo pipefail
🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In hack/install-preupgrade-konveyor.sh at the beginning of the file (lines 1 to
3), add the shebang line #!/usr/bin/env bash as the very first line to specify
the shell interpreter. Immediately after, add set -Eeuo pipefail to enable
strict mode for better error handling and safer script execution.

SUBSCRIPTION_CHANNEL="${SUBSCRIPTION_CHANNEL:-konveyor-0.6}"
PREUPGRADE_VERSION="${PREUPGRADE_VERSION:-0.6.0}"
POSTUPGRADE_VERSION="${POSTUPGRADE_VERSION:-99.0.0}" #Always the latest from main.
echo "Creating namespace"
echo "${SUBSCRIPTION_CHANNEL}"
source "${TEMPLATE_DIR}/01_namespace.sh"

source "${TEMPLATE_DIR}/02_catsrc.sh"

source "${TEMPLATE_DIR}/03_operatorgroup.sh"

source "${TEMPLATE_DIR}/04_subscription.sh"

kubectl get sub -n konveyor-tackle -o yaml #Remove later

Comment on lines +17 to +18
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Hard-coded namespace breaks parameterisation

kubectl get sub -n konveyor-tackle ignores ${NAMESPACE}.
Use the variable consistently so consumers can override the namespace.

-kubectl get sub -n konveyor-tackle -o yaml
+kubectl get sub -n "${NAMESPACE}" -o yaml
🤖 Prompt for AI Agents
In hack/install-preupgrade-konveyor.sh at lines 17 to 18, the kubectl command
uses a hard-coded namespace 'konveyor-tackle' instead of the variable
${NAMESPACE}. Replace the fixed namespace with the ${NAMESPACE} variable to
ensure the script respects the parameterization and allows consumers to override
the namespace as intended.

sleep 60s
echo "Patching installplan for konveyor..."

kubectl get installplan -n "${NAMESPACE}"

kubectl patch installplan $(kubectl get installplan -n "${NAMESPACE}" | egrep "$PREUPGRADE_VERSION"|awk '{print $1}') -n "${NAMESPACE}" --type merge --patch '{"spec":{"approved":true}}'

sleep 20s

source "${TEMPLATE_DIR}/05_tacklecr.sh"

kubectl wait --namespace "${NAMESPACE}" --for=condition=Successful --timeout=600s tackles.tackle.konveyor.io/tackle
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=tackle-ui -n "${NAMESPACE}" --timeout=300s
PREUPGRADE_UI_POD=$(kubectl get pod -l app.kubernetes.io/name=tackle-ui -n "${NAMESPACE}" -o name)
echo "PREUPGRADE_UI_POD=$PREUPGRADE_UI_POD" >> $GITHUB_ENV
sleep 120s

kubectl get po -n "${NAMESPACE}"
6 changes: 6 additions & 0 deletions hack/templates/01_namespace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: "${NAMESPACE}"
EOF
Comment on lines +1 to +6
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fail fast when ${NAMESPACE} is not provided
If NAMESPACE is unset the manifest will contain an empty string, producing an invalid namespace and a confusing error downstream.

+: "${NAMESPACE:?Environment variable NAMESPACE must be set}"

Insert the guard right after the she-bang.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In hack/templates/01_namespace.sh at lines 1 to 6, the script uses the variable
NAMESPACE without checking if it is set, which can lead to an invalid namespace
manifest and confusing errors. Add a guard clause immediately after the she-bang
line to check if NAMESPACE is set and non-empty; if not, print an error message
and exit the script to fail fast and prevent applying an invalid manifest.

15 changes: 15 additions & 0 deletions hack/templates/02_catsrc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cat << EOF | kubectl create -f -
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: konveyor-tackle
namespace: "${NAMESPACE}"
spec:
displayName: Konveyor Operator
publisher: Konveyor
sourceType: grpc
image: "${KONVEYOR_UPGRADE_INDEX}"
updateStrategy:
Comment on lines +10 to +12
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard required environment variables
KONVEYOR_UPGRADE_INDEX is interpolated without validation. Add a defensive check:

: "${KONVEYOR_UPGRADE_INDEX:?Environment variable KONVEYOR_UPGRADE_INDEX must be set}"

Place this near the top of the script.

🤖 Prompt for AI Agents
In hack/templates/02_catsrc.sh around lines 10 to 12, the environment variable
KONVEYOR_UPGRADE_INDEX is used without validation. Add a defensive check near
the top of the script using the syntax ': "${KONVEYOR_UPGRADE_INDEX:?Environment
variable KONVEYOR_UPGRADE_INDEX must be set}"' to ensure the variable is set
before it is used.

registryPoll:
interval: 10m
EOF
Comment on lines +1 to +15
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Prefer kubectl apply to make the template idempotent
This script may be rerun during CI or locally; kubectl create fails if the CatalogSource already exists, breaking the workflow. Switching to apply keeps the run repeatable.

-cat << EOF | kubectl create -f -
+cat << EOF | kubectl apply -f -
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cat << EOF | kubectl create -f -
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: konveyor-tackle
namespace: "${NAMESPACE}"
spec:
displayName: Konveyor Operator
publisher: Konveyor
sourceType: grpc
image: "${KONVEYOR_UPGRADE_INDEX}"
updateStrategy:
registryPoll:
interval: 10m
EOF
cat << EOF | kubectl apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: konveyor-tackle
namespace: "${NAMESPACE}"
spec:
displayName: Konveyor Operator
publisher: Konveyor
sourceType: grpc
image: "${KONVEYOR_UPGRADE_INDEX}"
updateStrategy:
registryPoll:
interval: 10m
EOF
🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In hack/templates/02_catsrc.sh lines 1 to 15, replace the use of 'kubectl
create' with 'kubectl apply' to make the script idempotent. This change ensures
that rerunning the script does not fail if the CatalogSource resource already
exists, allowing repeated executions without errors.

10 changes: 10 additions & 0 deletions hack/templates/03_operatorgroup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cat << EOF | kubectl create -f -
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use apply instead of create to avoid “AlreadyExists” errors

-cat << EOF | kubectl create -f -
+cat << EOF | kubectl apply -f -
🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In hack/templates/03_operatorgroup.sh at line 1, replace the kubectl command
from 'kubectl create -f -' to 'kubectl apply -f -' to prevent errors when the
resource already exists. This change ensures the command updates existing
resources instead of failing on duplicates.

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: konveyor-tackle
namespace: "${NAMESPACE}"
spec:
targetNamespaces:
- konveyor-tackle
Comment on lines +8 to +9
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Hard-coded targetNamespaces breaks custom namespace installs
The OperatorGroup is parameterised everywhere except here:

targetNamespaces:
  - konveyor-tackle   # <- hard-coded

Use the same variable to keep the install self-contained:

-  - konveyor-tackle
+  - "${NAMESPACE}"
🤖 Prompt for AI Agents
In hack/templates/03_operatorgroup.sh at lines 8 to 9, the targetNamespaces
field is hard-coded to "konveyor-tackle", which breaks custom namespace
installs. Replace the hard-coded value with the existing parameter variable used
elsewhere in the template to make the installation namespace configurable and
self-contained.

EOF
13 changes: 13 additions & 0 deletions hack/templates/04_subscription.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cat <<EOF | kubectl apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: konveyor-operator
namespace: "${NAMESPACE}"
spec:
channel: "${SUBSCRIPTION_CHANNEL}"
installPlanApproval: "Manual"
Comment on lines +7 to +9
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate ${SUBSCRIPTION_CHANNEL} before use

: "${SUBSCRIPTION_CHANNEL:?Environment variable SUBSCRIPTION_CHANNEL must be set}"

Failing early prevents the creation of an invalid Subscription manifest.

🤖 Prompt for AI Agents
In hack/templates/04_subscription.sh around lines 7 to 9, the environment
variable SUBSCRIPTION_CHANNEL is used without validation, which can lead to
creating an invalid Subscription manifest. Add a validation line at the start of
the script using the syntax ': "${SUBSCRIPTION_CHANNEL:?Environment variable
SUBSCRIPTION_CHANNEL must be set}"' to ensure the variable is set and fail early
if it is not.

name: konveyor-operator
source: konveyor-tackle
sourceNamespace: konveyor-tackle
EOF
9 changes: 9 additions & 0 deletions hack/templates/05_tacklecr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cat <<EOF | kubectl apply -f -
kind: Tackle
apiVersion: tackle.konveyor.io/v1alpha1
metadata:
name: tackle
namespace: "${NAMESPACE}"
spec:
feature_auth_required: "true"
EOF