Skip to content

Commit fedeb9a

Browse files
author
Lucas Yoon
committed
adding renovate and test scripts
1 parent a173e94 commit fedeb9a

File tree

7 files changed

+439
-0
lines changed

7 files changed

+439
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Validate with Devfile Registry Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
validate-devfile:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout current repo
16+
uses: actions/checkout@v4
17+
with:
18+
path: current-repo
19+
20+
- name: Checkout devfile registry
21+
uses: actions/checkout@v4
22+
with:
23+
repository: devfile/registry
24+
path: registry
25+
26+
- name: Setup test environment with overrides
27+
run: |
28+
cp -r registry/tests registry-tests-base
29+
30+
if [ -d "current-repo/tests" ]; then
31+
echo "Found local test overrides, applying them..."
32+
cp -r current-repo/tests/* registry-tests-base/ 2>/dev/null || true
33+
fi
34+
35+
mkdir -p registry/stacks/current-sample
36+
cp current-repo/devfile.yaml registry/stacks/current-sample/
37+
cp -r registry-tests-base/* registry/tests/
38+
39+
- name: Setup Go
40+
uses: actions/setup-go@v4
41+
with:
42+
go-version: '1.21'
43+
44+
- name: Install dependencies
45+
run: |
46+
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
47+
sudo chmod +x /usr/local/bin/yq
48+
go install github.com/onsi/ginkgo/v2/ginkgo@latest
49+
50+
- name: Setup Minikube
51+
uses: medyagh/setup-minikube@master
52+
with:
53+
minikube-version: latest
54+
kubernetes-version: v1.28.0
55+
56+
- name: Run Registry Validation Tests
57+
working-directory: registry
58+
run: |
59+
cd tests/check_non_terminating
60+
go build -o flatten-parent .
61+
cd ../..
62+
63+
export STACKS="current-sample"
64+
export TEST_NAMESPACE="default"
65+
export YQ_PATH="yq"
66+
export ENV="minikube"
67+
68+
echo "Running validation tests for current sample..."
69+
70+
echo "=== Schema Validation ==="
71+
cd tests
72+
bash validate_devfile_schemas.sh
73+
74+
echo "=== Non-terminating Test ==="
75+
bash check_non_terminating.sh
76+
77+
echo "All tests completed successfully!"
78+
79+
- name: Cleanup
80+
if: always()
81+
run: |
82+
kubectl delete pods --all -n default --ignore-not-found=true || true

.github/workflows/validate_devfile.yaml

Whitespace-only changes.

renovate.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"enabledManagers": ["pip_requirements"],
4+
"pip_requirements": {
5+
"fileMatch": ["requirements\\.txt$"]
6+
},
7+
"packageRules": [
8+
{
9+
"matchManagers": ["pip_requirements"],
10+
"groupName": "python dependencies",
11+
"groupSlug": "python-deps",
12+
"commitMessageTopic": "Python {{depName}}"
13+
}
14+
],
15+
"vulnerabilityAlerts": {
16+
"enabled": true
17+
}
18+
}

tests/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Test Scripts
2+
3+
These test scripts are adapted from the [devfile/registry](https://github.com/devfile/registry) repository.
4+
5+
Our CI workflow clones the registry repository and uses their test infrastructure, with the ability to override any test scripts by placing them in this directory.

tests/check_non_terminating.sh

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
#!/bin/bash
2+
set -o nounset
3+
set -o errexit
4+
5+
# Path to the devfile in this sample repository
6+
DEVFILE_PATH="$(pwd)/devfile.yaml"
7+
8+
# Path to the devfile/registry repository (assumed to be cloned as a sibling)
9+
REGISTRY_PATH=${REGISTRY_PATH:-"../registry"}
10+
11+
# Path to the check_non_terminating go package
12+
BIN_NAME=${BIN_NAME:-"flatten-parent"}
13+
NON_TERMINATING_MODULE_BIN="${REGISTRY_PATH}/tests/check_non_terminating/$BIN_NAME"
14+
15+
replaceVariables() {
16+
image=$1
17+
VAR_KEYS=(liberty-version)
18+
VAR_VALUES=(22.0.0.1)
19+
20+
for i in "${!VAR_KEYS[@]}"; do
21+
key='{{'
22+
key+=${VAR_KEYS[i]}
23+
key+='}}'
24+
value=${VAR_VALUES[i]}
25+
image=${image/${key}/${value}}
26+
done
27+
echo "$image"
28+
}
29+
30+
getContainerComponentsNum() {
31+
devfilePath=$1
32+
component_num=$($YQ_PATH eval '[ .components[] | select(has("container")) ] | length' "$devfilePath" -r)
33+
echo "${component_num}"
34+
}
35+
36+
getName() {
37+
devfilePath=$1
38+
name=$($YQ_PATH eval '.metadata.name' "$devfilePath" -r)
39+
echo "${name}"
40+
}
41+
42+
getFirstContainerComponentImage() {
43+
devfilePath=$1
44+
45+
image_original=$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.image' "$devfilePath" -r)
46+
image_processed=$(replaceVariables "${image_original}")
47+
echo "${image_processed}"
48+
}
49+
50+
getFirstContainerComponentCommand() {
51+
devfilePath=$1
52+
local _gfccc_command=()
53+
local _gfccc_command_string=()
54+
55+
IFS=" " read -r -a _gfccc_command_string <<<"$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.command[]? + " "' "$devfilePath" -r | paste -s -d '\0' -)"
56+
if ((${#_gfccc_command_string[@]} == 0)); then
57+
echo ""
58+
else
59+
for command_word in "${_gfccc_command_string[@]}"; do
60+
_gfccc_command+=("${command_word}")
61+
done
62+
echo "${_gfccc_command[@]}"
63+
fi
64+
}
65+
66+
getFirstContainerComponentArgs() {
67+
devfilePath=$1
68+
local _gfcca_args=()
69+
local _gfcca_args_string=()
70+
71+
IFS=" " read -r -a _gfcca_args_string <<<"$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.args[]? + " "' "$devfilePath" -r | paste -s -d '\0' -)"
72+
if ((${#_gfcca_args_string[@]} == 0)); then
73+
echo ""
74+
else
75+
for arg in "${_gfcca_args_string[@]}"; do
76+
_gfcca_args+=("${arg}")
77+
done
78+
echo "${_gfcca_args[@]}"
79+
fi
80+
}
81+
82+
isNonTerminating() {
83+
_int_image=$1
84+
_int_command=("$2")
85+
_int_command_args=("$3")
86+
87+
timeout_in_sec=240 # <== includes image pulling
88+
89+
# workaround: cri-dockerd v0.2.6+ fixes a timeout issue where large images are not being pulled
90+
# this can be removed when actions-setup-minikube updates cri-dockerd
91+
if [ "$ENV" = "minikube" ]; then
92+
echo " COMMAND: minikube ssh docker pull $_int_image"
93+
minikube ssh docker pull $_int_image >/dev/null 2>&1
94+
fi
95+
96+
echo " PARAMS: image --> $_int_image, command --> ${_int_command[*]}, args --> ${_int_command_args[*]}"
97+
98+
if [ "${_int_command[*]}" == "null" ] && [ "${_int_command_args[*]}" == "null" ]; then
99+
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image\""
100+
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" >/dev/null 2>&1
101+
elif [ "${_int_command[*]}" == "null" ]; then
102+
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image -- ${_int_command_args[*]}\""
103+
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" -- ${_int_command_args[*]} >/dev/null 2>&1
104+
elif [ "${_int_command_args[*]}" == "null" ]; then
105+
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image --command -- ${_int_command[*]}\""
106+
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" --command=true -- ${_int_command[*]} >/dev/null 2>&1
107+
else
108+
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image --command -- ${_int_command[*]} ${_int_command_args[*]}\""
109+
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" --command=true -- ${_int_command[*]} ${_int_command_args[*]} >/dev/null 2>&1
110+
fi
111+
112+
if kubectl wait pods -n "${TEST_NAMESPACE}" test-terminating --for condition=Ready --timeout=${timeout_in_sec}s >/dev/null 2>&1; then
113+
echo " SUCCESS: The container started successfully and didn't terminate"
114+
kubectl delete pod test-terminating -n "${TEST_NAMESPACE}" >/dev/null 2>&1
115+
116+
return 0
117+
else
118+
echo " ERROR: Failed to reach \"Ready\" condition after $timeout_in_sec seconds"
119+
echo " ↓↓↓↓↓↓↓↓↓ Pod description ↓↓↓↓↓↓↓↓"
120+
echo ""
121+
kubectl describe pod -n "${TEST_NAMESPACE}" test-terminating
122+
echo ""
123+
echo " ↑↑↑↑↑↑↑↑↑ Pod description ↑↑↑↑↑↑↑↑"
124+
kubectl delete pod test-terminating -n "${TEST_NAMESPACE}" >/dev/null 2>&1
125+
return 1
126+
fi
127+
}
128+
129+
YQ_PATH=${YQ_PATH:-yq}
130+
TEST_NAMESPACE=${TEST_NAMESPACE:-default}
131+
132+
if [ -z "${ENV:-}" ]; then
133+
ENV=minikube
134+
fi
135+
136+
if [ "$ENV" != "minikube" ] && [ "$ENV" != "openshift" ]; then
137+
echo "ERROR:: Allowed values for ENV are either \"minikube\" (default) or \"openshift\"."
138+
exit 1
139+
fi
140+
141+
# Check if the devfile/registry binary exists
142+
if [ ! -f "$NON_TERMINATING_MODULE_BIN" ]; then
143+
echo "ERROR: Go binary not found at $NON_TERMINATING_MODULE_BIN"
144+
echo "Please ensure the devfile/registry repository is cloned and the binary is built."
145+
exit 1
146+
fi
147+
148+
# Check if devfile exists
149+
if [ ! -f "$DEVFILE_PATH" ]; then
150+
echo "ERROR: Devfile not found at path $DEVFILE_PATH"
151+
exit 1
152+
fi
153+
154+
echo "======================="
155+
echo "Testing single sample: ${DEVFILE_PATH}"
156+
157+
# if devfile in path has a parent flatten it
158+
if $YQ_PATH eval 'has("parent")' "$DEVFILE_PATH" -r | grep -q "true"; then
159+
echo "INFO:: Found parent for $DEVFILE_PATH"
160+
"$NON_TERMINATING_MODULE_BIN" "$DEVFILE_PATH"
161+
fi
162+
163+
IFS=" " read -r -a components_num <<<"$(getContainerComponentsNum "$DEVFILE_PATH")"
164+
165+
# if there are zero components of type container skip
166+
if ((components_num == 0)); then
167+
echo "WARNING: Devfile with no container component found (""$DEVFILE_PATH""). Skipping."
168+
echo "======================="
169+
exit 0
170+
fi
171+
172+
# if there is more than one component of type container skip (we may want to cover this case in the future)
173+
if ((components_num > 1)); then
174+
echo "WARNING: Devfile with more than one container component found (""$DEVFILE_PATH""). Skipping."
175+
echo "======================="
176+
exit 0
177+
fi
178+
179+
name=$(getName "$DEVFILE_PATH")
180+
image=$(getFirstContainerComponentImage "$DEVFILE_PATH")
181+
182+
declare -a command=()
183+
IFS=" " read -r -a command <<<"$(getFirstContainerComponentCommand "$DEVFILE_PATH")"
184+
185+
declare -a command_args=()
186+
IFS=" " read -r -a command_args <<<"$(getFirstContainerComponentArgs "$DEVFILE_PATH")"
187+
188+
if ((${#command[@]} > 0)); then
189+
command_string="${command[*]}"
190+
else
191+
command_string="null"
192+
fi
193+
194+
if ((${#command_args[@]} > 0)); then
195+
command_args_string="${command_args[*]}"
196+
else
197+
command_args_string="null"
198+
fi
199+
200+
echo "Sample: $name"
201+
echo "Image: $image"
202+
echo "Command: $command_string"
203+
echo "Args: $command_args_string"
204+
205+
isNonTerminating "${image}" "${command_string}" "${command_args_string}"
206+
207+
# remove image to save space
208+
if [ "$ENV" = "minikube" ]; then
209+
echo " COMMAND: \"minikube ssh -- docker image rm ${image} --force\""
210+
minikube ssh -- docker image rm ${image} --force >/dev/null 2>&1
211+
fi
212+
213+
echo "======================="
214+
echo "Non-terminating test completed successfully!"
215+
216+
exit 0

tests/check_odov3.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env bash
2+
3+
set -x
4+
5+
# Path to the devfile in this sample repository
6+
SAMPLE_PATH="$(pwd)"
7+
DEVFILE_PATH="$SAMPLE_PATH/devfile.yaml"
8+
9+
# Path to the devfile/registry repository (assumed to be cloned as a sibling)
10+
REGISTRY_PATH=${REGISTRY_PATH:-"../registry"}
11+
12+
args=""
13+
14+
if [ ! -z "${1}" ]; then
15+
args="-odoPath ${1} ${args}"
16+
fi
17+
18+
# Check if devfile exists
19+
if [ ! -f "$DEVFILE_PATH" ]; then
20+
echo "ERROR: Devfile not found at path $DEVFILE_PATH"
21+
exit 1
22+
fi
23+
24+
# Check if the devfile/registry test directory exists
25+
if [ ! -d "$REGISTRY_PATH/tests/odov3" ]; then
26+
echo "ERROR: Registry test directory not found at $REGISTRY_PATH/tests/odov3"
27+
echo "Please ensure the devfile/registry repository is cloned."
28+
exit 1
29+
fi
30+
31+
# Get the sample name from the devfile metadata
32+
SAMPLE_NAME=$(yq eval '.metadata.name' "$DEVFILE_PATH")
33+
34+
echo "======================="
35+
echo "Running ODO v3 tests for single sample: ${SAMPLE_NAME}"
36+
echo "Devfile path: ${DEVFILE_PATH}"
37+
echo "Registry path: ${REGISTRY_PATH}"
38+
echo "======================="
39+
40+
# Change to the registry test directory and run the ODO test
41+
cd "$REGISTRY_PATH/tests/odov3"
42+
43+
# Run the ODO test with the single sample
44+
# Note: We pass "." as the stackDirs since we're testing the current sample
45+
ginkgo run --procs 1 \
46+
--timeout 3h \
47+
--slow-spec-threshold 120s \
48+
. -- -stacksPath "$SAMPLE_PATH" -stackDirs "." ${args}
49+
50+
echo "======================="
51+
echo "ODO v3 test completed!"
52+
echo "======================="

0 commit comments

Comments
 (0)