-
Notifications
You must be signed in to change notification settings - Fork 395
[Devfile#1718 ] Adding renovate.json and test script to ensure sample can still be parsed and used by consumers #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,87 @@ | ||||||
name: Validate with Devfile Registry Tests | ||||||
|
||||||
on: | ||||||
push: | ||||||
branches: [ main ] | ||||||
pull_request: | ||||||
branches: [ main ] | ||||||
workflow_dispatch: | ||||||
|
||||||
jobs: | ||||||
validate-devfile: | ||||||
runs-on: ubuntu-latest | ||||||
|
||||||
env: | ||||||
REGISTRY_PATH: ${{ github.workspace }}/registry | ||||||
|
||||||
steps: | ||||||
- name: Checkout current repo | ||||||
uses: actions/checkout@v4 | ||||||
with: | ||||||
path: current-repo | ||||||
|
||||||
- name: Checkout devfile registry | ||||||
uses: actions/checkout@v4 | ||||||
with: | ||||||
repository: devfile/registry | ||||||
path: registry | ||||||
|
||||||
- name: Setup test environment with overrides | ||||||
run: | | ||||||
# Copy entire project for devfile validation | ||||||
mkdir -p test-sample | ||||||
cp -r current-repo/* test-sample/ | ||||||
|
||||||
# Stage registry test files and apply local overrides | ||||||
mkdir -p test-environment/tests | ||||||
cp -r registry/tests/* test-environment/tests/ | ||||||
|
||||||
if [ -d "current-repo/tests" ]; then | ||||||
echo "Applying local test overrides..." | ||||||
cp -r current-repo/tests/* test-environment/tests/ 2>/dev/null || true | ||||||
fi | ||||||
|
||||||
# Copy staged files to execution location | ||||||
cp -r test-environment/tests/* registry/tests/ | ||||||
cp -r test-sample/* registry/tests/ | ||||||
|
||||||
- name: Setup Go | ||||||
uses: actions/setup-go@v4 | ||||||
with: | ||||||
go-version: '1.21' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the latest target Go version current in devfile/registry:
Suggested change
|
||||||
|
||||||
- name: Install dependencies | ||||||
run: | | ||||||
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 | ||||||
sudo chmod +x /usr/local/bin/yq | ||||||
go install github.com/onsi/ginkgo/v2/ginkgo@latest | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the current
Suggested change
|
||||||
|
||||||
- name: Setup Minikube | ||||||
uses: medyagh/setup-minikube@master | ||||||
with: | ||||||
minikube-version: latest | ||||||
kubernetes-version: v1.28.0 | ||||||
|
||||||
- name: Run Registry Validation Tests | ||||||
env: | ||||||
REGISTRY_PATH: ${{ github.workspace }}/registry | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
No need to set for the step, it is already set for the entire job. |
||||||
DEVFILE_PATH: ${{ github.workspace }}/registry/tests/devfile.yaml | ||||||
TEST_NAMESPACE: "default" | ||||||
YQ_PATH: "yq" | ||||||
ENV: "minikube" | ||||||
run: | | ||||||
cd registry/tests/check_non_terminating | ||||||
go build -o flatten-parent . | ||||||
cd ../../.. | ||||||
|
||||||
echo "=== Schema Validation ===" | ||||||
cd registry/tests | ||||||
bash validate_devfile_schemas.sh | ||||||
|
||||||
echo "=== Non-terminating Test ===" | ||||||
bash check_non_terminating.sh | ||||||
|
||||||
- name: Cleanup | ||||||
if: always() | ||||||
run: | | ||||||
kubectl delete pods --all -n default --ignore-not-found=true || true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
"enabledManagers": ["pip_requirements"], | ||
"pip_requirements": { | ||
"fileMatch": ["requirements\\.txt$"] | ||
}, | ||
"packageRules": [ | ||
{ | ||
"matchManagers": ["pip_requirements"], | ||
"groupName": "python dependencies", | ||
"groupSlug": "python-deps", | ||
"commitMessageTopic": "Python {{depName}}" | ||
} | ||
], | ||
"vulnerabilityAlerts": { | ||
"enabled": true | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JslYoon I wonder if it is worth having a separate repository for the sample test scripts then pull them into each sample workflow when they run 🤔 Would reduce the number of places we would need to maintain these under. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or we could modify the ones under devfile/registry to take single stack/sample inputs then there is no need to have separate copies of these scripts for overriding. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wdyt? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Test Scripts | ||
|
||
These test scripts are adapted from the [devfile/registry](https://github.com/devfile/registry) repository. | ||
|
||
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
#!/bin/bash | ||
set -o nounset | ||
set -o errexit | ||
|
||
DEVFILE_PATH=${DEVFILE_PATH:-"$(pwd)/devfile.yaml"} | ||
|
||
REGISTRY_PATH=${REGISTRY_PATH:-"../registry"} | ||
|
||
BIN_NAME=${BIN_NAME:-"flatten-parent"} | ||
NON_TERMINATING_MODULE_BIN="${REGISTRY_PATH}/tests/check_non_terminating/$BIN_NAME" | ||
|
||
replaceVariables() { | ||
image=$1 | ||
VAR_KEYS=(liberty-version) | ||
VAR_VALUES=(22.0.0.1) | ||
|
||
for i in "${!VAR_KEYS[@]}"; do | ||
key='{{' | ||
key+=${VAR_KEYS[i]} | ||
key+='}}' | ||
value=${VAR_VALUES[i]} | ||
image=${image/${key}/${value}} | ||
done | ||
echo "$image" | ||
} | ||
|
||
getContainerComponentsNum() { | ||
devfilePath=$1 | ||
component_num=$($YQ_PATH eval '[ .components[] | select(has("container")) ] | length' "$devfilePath" -r) | ||
echo "${component_num}" | ||
} | ||
|
||
getName() { | ||
devfilePath=$1 | ||
name=$($YQ_PATH eval '.metadata.name' "$devfilePath" -r) | ||
echo "${name}" | ||
} | ||
|
||
getFirstContainerComponentImage() { | ||
devfilePath=$1 | ||
|
||
image_original=$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.image' "$devfilePath" -r) | ||
image_processed=$(replaceVariables "${image_original}") | ||
echo "${image_processed}" | ||
} | ||
|
||
getFirstContainerComponentCommand() { | ||
devfilePath=$1 | ||
local _gfccc_command=() | ||
local _gfccc_command_string=() | ||
|
||
IFS=" " read -r -a _gfccc_command_string <<<"$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.command[]? + " "' "$devfilePath" -r | paste -s -d '\0' -)" | ||
if ((${#_gfccc_command_string[@]} == 0)); then | ||
echo "" | ||
else | ||
for command_word in "${_gfccc_command_string[@]}"; do | ||
_gfccc_command+=("${command_word}") | ||
done | ||
echo "${_gfccc_command[@]}" | ||
fi | ||
} | ||
|
||
getFirstContainerComponentArgs() { | ||
devfilePath=$1 | ||
local _gfcca_args=() | ||
local _gfcca_args_string=() | ||
|
||
IFS=" " read -r -a _gfcca_args_string <<<"$($YQ_PATH eval '[ .components[] | select(has("container")) ] | .[0].container.args[]? + " "' "$devfilePath" -r | paste -s -d '\0' -)" | ||
if ((${#_gfcca_args_string[@]} == 0)); then | ||
echo "" | ||
else | ||
for arg in "${_gfcca_args_string[@]}"; do | ||
_gfcca_args+=("${arg}") | ||
done | ||
echo "${_gfcca_args[@]}" | ||
fi | ||
} | ||
|
||
isNonTerminating() { | ||
_int_image=$1 | ||
_int_command=("$2") | ||
_int_command_args=("$3") | ||
|
||
timeout_in_sec=240 # <== includes image pulling | ||
|
||
# workaround: cri-dockerd v0.2.6+ fixes a timeout issue where large images are not being pulled | ||
# this can be removed when actions-setup-minikube updates cri-dockerd | ||
if [ "$ENV" = "minikube" ]; then | ||
echo " COMMAND: minikube ssh docker pull $_int_image" | ||
minikube ssh docker pull $_int_image >/dev/null 2>&1 | ||
fi | ||
|
||
echo " PARAMS: image --> $_int_image, command --> ${_int_command[*]}, args --> ${_int_command_args[*]}" | ||
|
||
if [ "${_int_command[*]}" == "null" ] && [ "${_int_command_args[*]}" == "null" ]; then | ||
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image\"" | ||
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" >/dev/null 2>&1 | ||
elif [ "${_int_command[*]}" == "null" ]; then | ||
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image -- ${_int_command_args[*]}\"" | ||
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" -- ${_int_command_args[*]} >/dev/null 2>&1 | ||
elif [ "${_int_command_args[*]}" == "null" ]; then | ||
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image --command -- ${_int_command[*]}\"" | ||
kubectl run test-terminating -n "${TEST_NAMESPACE}" --attach=false --restart=Never --image="$_int_image" --command=true -- ${_int_command[*]} >/dev/null 2>&1 | ||
else | ||
echo " COMMAND: \"kubectl run test-terminating -n ${TEST_NAMESPACE} --attach=false --restart=Never --image=$_int_image --command -- ${_int_command[*]} ${_int_command_args[*]}\"" | ||
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 | ||
fi | ||
|
||
if kubectl wait pods -n "${TEST_NAMESPACE}" test-terminating --for condition=Ready --timeout=${timeout_in_sec}s >/dev/null 2>&1; then | ||
echo " SUCCESS: The container started successfully and didn't terminate" | ||
kubectl delete pod test-terminating -n "${TEST_NAMESPACE}" >/dev/null 2>&1 | ||
|
||
return 0 | ||
else | ||
echo " ERROR: Failed to reach \"Ready\" condition after $timeout_in_sec seconds" | ||
echo " ↓↓↓↓↓↓↓↓↓ Pod description ↓↓↓↓↓↓↓↓" | ||
echo "" | ||
kubectl describe pod -n "${TEST_NAMESPACE}" test-terminating | ||
echo "" | ||
echo " ↑↑↑↑↑↑↑↑↑ Pod description ↑↑↑↑↑↑↑↑" | ||
kubectl delete pod test-terminating -n "${TEST_NAMESPACE}" >/dev/null 2>&1 | ||
return 1 | ||
fi | ||
} | ||
|
||
YQ_PATH=${YQ_PATH:-yq} | ||
TEST_NAMESPACE=${TEST_NAMESPACE:-default} | ||
|
||
if [ -z "${ENV:-}" ]; then | ||
ENV=minikube | ||
fi | ||
|
||
if [ "$ENV" != "minikube" ] && [ "$ENV" != "openshift" ]; then | ||
echo "ERROR:: Allowed values for ENV are either \"minikube\" (default) or \"openshift\"." | ||
exit 1 | ||
fi | ||
|
||
if [ ! -f "$NON_TERMINATING_MODULE_BIN" ]; then | ||
echo "ERROR: Go binary not found at $NON_TERMINATING_MODULE_BIN" | ||
echo "Please ensure the devfile/registry repository is cloned and the binary is built." | ||
exit 1 | ||
fi | ||
|
||
if [ ! -f "$DEVFILE_PATH" ]; then | ||
echo "ERROR: Devfile not found at path $DEVFILE_PATH" | ||
exit 1 | ||
fi | ||
|
||
echo "=======================" | ||
echo "Testing single sample: ${DEVFILE_PATH}" | ||
|
||
# if devfile in path has a parent flatten it | ||
if $YQ_PATH eval 'has("parent")' "$DEVFILE_PATH" -r | grep -q "true"; then | ||
echo "INFO:: Found parent for $DEVFILE_PATH" | ||
"$NON_TERMINATING_MODULE_BIN" "$DEVFILE_PATH" | ||
fi | ||
|
||
IFS=" " read -r -a components_num <<<"$(getContainerComponentsNum "$DEVFILE_PATH")" | ||
|
||
# if there are zero components of type container skip | ||
if ((components_num == 0)); then | ||
echo "WARNING: Devfile with no container component found (""$DEVFILE_PATH""). Skipping." | ||
echo "=======================" | ||
exit 0 | ||
fi | ||
|
||
# if there is more than one component of type container skip (we may want to cover this case in the future) | ||
if ((components_num > 1)); then | ||
echo "WARNING: Devfile with more than one container component found (""$DEVFILE_PATH""). Skipping." | ||
echo "=======================" | ||
exit 0 | ||
fi | ||
|
||
name=$(getName "$DEVFILE_PATH") | ||
image=$(getFirstContainerComponentImage "$DEVFILE_PATH") | ||
|
||
declare -a command=() | ||
IFS=" " read -r -a command <<<"$(getFirstContainerComponentCommand "$DEVFILE_PATH")" | ||
|
||
declare -a command_args=() | ||
IFS=" " read -r -a command_args <<<"$(getFirstContainerComponentArgs "$DEVFILE_PATH")" | ||
|
||
if ((${#command[@]} > 0)); then | ||
command_string="${command[*]}" | ||
else | ||
command_string="null" | ||
fi | ||
|
||
if ((${#command_args[@]} > 0)); then | ||
command_args_string="${command_args[*]}" | ||
else | ||
command_args_string="null" | ||
fi | ||
|
||
echo "Sample: $name" | ||
echo "Image: $image" | ||
echo "Command: $command_string" | ||
echo "Args: $command_args_string" | ||
|
||
isNonTerminating "${image}" "${command_string}" "${command_args_string}" | ||
|
||
# remove image to save space | ||
if [ "$ENV" = "minikube" ]; then | ||
echo " COMMAND: \"minikube ssh -- docker image rm ${image} --force\"" | ||
minikube ssh -- docker image rm ${image} --force >/dev/null 2>&1 | ||
fi | ||
|
||
echo "=======================" | ||
echo "Non-terminating test completed successfully!" | ||
|
||
exit 0 |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,38 @@ | ||||||||||||||
#!/usr/bin/env bash | ||||||||||||||
|
||||||||||||||
set -x | ||||||||||||||
|
||||||||||||||
SAMPLE_PATH="$(pwd)" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
DEVFILE_PATH=${DEVFILE_PATH:-"$SAMPLE_PATH/devfile.yaml"} | ||||||||||||||
|
||||||||||||||
REGISTRY_PATH=${REGISTRY_PATH:-"../registry"} | ||||||||||||||
|
||||||||||||||
args="" | ||||||||||||||
|
||||||||||||||
if [ ! -z "${1}" ]; then | ||||||||||||||
args="-odoPath ${1} ${args}" | ||||||||||||||
fi | ||||||||||||||
|
||||||||||||||
if [ ! -f "$DEVFILE_PATH" ]; then | ||||||||||||||
echo "ERROR: Devfile not found at path $DEVFILE_PATH" | ||||||||||||||
exit 1 | ||||||||||||||
fi | ||||||||||||||
|
||||||||||||||
if [ ! -d "$REGISTRY_PATH/tests/odov3" ]; then | ||||||||||||||
echo "ERROR: Registry test directory not found at $REGISTRY_PATH/tests/odov3" | ||||||||||||||
echo "Please ensure the devfile/registry repository is cloned." | ||||||||||||||
exit 1 | ||||||||||||||
fi | ||||||||||||||
|
||||||||||||||
SAMPLE_NAME=$(yq eval '.metadata.name' "$DEVFILE_PATH") | ||||||||||||||
|
||||||||||||||
cd "$REGISTRY_PATH/tests/odov3" | ||||||||||||||
|
||||||||||||||
ginkgo run --procs 1 \ | ||||||||||||||
--timeout 3h \ | ||||||||||||||
--slow-spec-threshold 120s \ | ||||||||||||||
. -- -stacksPath "$SAMPLE_PATH" -stackDirs "." ${args} | ||||||||||||||
|
||||||||||||||
echo "=======================" | ||||||||||||||
echo "ODO v3 test completed!" | ||||||||||||||
echo "=======================" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could just use
current-repo
path directly rather than coping into a new sample directory.