Skip to content

Commit 2dc5b12

Browse files
committed
Feat: Add metadata validation workflow and scripts
Signed-off-by: alyssacgoins <agoins@redhat.com>
1 parent 00758af commit 2dc5b12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1337
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
3+
# Determine which components should be validated by a given validation script.
4+
#
5+
# Usage:
6+
# get_components_for_validation.sh <BASE_COMMIT> <HEAD_COMMIT> <VALIDATION_SCRIPT_DIR>
7+
#
8+
# Outputs a GitHub Actions output variable named `new_components_list` containing
9+
# a comma-separated list of component directories to validate.
10+
11+
set -euo pipefail
12+
13+
BASE_COMMIT=${1:-}
14+
HEAD_COMMIT=${2:-}
15+
VALIDATION_SCRIPT_DIR=${3:-}
16+
17+
# Validate required parameters
18+
if [[ -z "${BASE_COMMIT}" || -z "${HEAD_COMMIT}" || -z "${VALIDATION_SCRIPT_DIR}" ]]; then
19+
echo "Usage: $0 <BASE_COMMIT> <HEAD_COMMIT> <VALIDATION_SCRIPT_DIR>" >&2
20+
exit 1
21+
fi
22+
23+
COMMIT_RANGE="${BASE_COMMIT}..${HEAD_COMMIT}"
24+
SCRIPT_DIR="scripts/${VALIDATION_SCRIPT_DIR}"
25+
26+
echo "Retrieving components to run against the following script: ${VALIDATION_SCRIPT_DIR}"
27+
echo "Using BASE_COMMIT: ${BASE_COMMIT}"
28+
echo "Using HEAD_COMMIT: ${HEAD_COMMIT}"
29+
30+
# If diff is detected within the input script directory, validate all components.
31+
SCRIPT_DIFF=$(git diff --name-only --diff-filter=ACM "${COMMIT_RANGE}" -- "${SCRIPT_DIR}" || true)
32+
if [[ -n "${SCRIPT_DIFF}" ]]; then
33+
ALL_COMPONENT_FILES=$(find components -mindepth 2 -maxdepth 2 -type d | \
34+
sort -u | \
35+
tr '\n' ',' | \
36+
sed 's/,$//')
37+
38+
if [[ -z "${ALL_COMPONENT_FILES//[[:space:]]/}" ]]; then
39+
echo "Changes detected in ${VALIDATION_SCRIPT_DIR}, but there are no existing components to validate."
40+
else
41+
echo "Changes detected in ${VALIDATION_SCRIPT_DIR}. All existing components will be validated: ${ALL_COMPONENT_FILES}"
42+
fi
43+
44+
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
45+
echo "new_components_list=${ALL_COMPONENT_FILES}" >> "${GITHUB_OUTPUT}"
46+
else
47+
echo "new_components_list=${ALL_COMPONENT_FILES}"
48+
fi
49+
50+
else
51+
# If no script diff is detected, check for new components.
52+
GIT_DIFF=$(git diff --name-only --diff-filter=A "${COMMIT_RANGE}" -- "components" || true)
53+
NEW_COMPONENTS=()
54+
FORMATTED_COMPONENTS=""
55+
56+
# Retrieve list of component categories.
57+
COMPONENT_TYPES=$(find components -mindepth 2 -maxdepth 2 -type d | \
58+
sed 's/^components\///' | \
59+
sort -u)
60+
61+
# Identify all new components in each category by checking all existing components against GIT_DIFF.
62+
for dir in ${COMPONENT_TYPES}; do
63+
echo "DIR: components/${dir}"
64+
if [[ " ${GIT_DIFF} " =~ components/"${dir}" ]]; then
65+
NEW_COMPONENTS+=("components/${dir}")
66+
fi
67+
done
68+
69+
# Format the list of new components for output.
70+
if ((${#NEW_COMPONENTS[@]} > 0)); then
71+
FORMATTED_COMPONENTS=$(printf '%s\n' "${NEW_COMPONENTS[@]}" | \
72+
sort -u | \
73+
tr '\n' ',' | \
74+
sed 's/,$//')
75+
else
76+
FORMATTED_COMPONENTS=""
77+
fi
78+
79+
if [[ -n "${FORMATTED_COMPONENTS}" ]]; then
80+
echo "The following new components were found and will be validated: ${FORMATTED_COMPONENTS}"
81+
else
82+
echo "No new components detected."
83+
fi
84+
85+
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
86+
echo "new_components_list=${FORMATTED_COMPONENTS}" >> "${GITHUB_OUTPUT}"
87+
else
88+
echo "new_components_list=${FORMATTED_COMPONENTS}"
89+
fi
90+
91+
fi
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: validate-metadata-schema
2+
env:
3+
PYTHON_VERSION: 3.11
4+
COMPONENT_SCRIPT_PATH: $GITHUB_WORKSPACE/.github/resources/scripts/get_components_for_validation.sh
5+
VALIDATION_SCRIPT_PATH: $GITHUB_WORKSPACE/scripts/validate_metadata/validate_metadata.py
6+
on:
7+
pull_request:
8+
paths:
9+
- 'components/**'
10+
- 'scripts/**'
11+
12+
jobs:
13+
validate-component-metadata-schema:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v5
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v6
22+
with:
23+
python-version: ${{ env.PYTHON_VERSION }}
24+
25+
- name: Install Test dependencies
26+
run: |
27+
pip install -r scripts/validate_metadata/requirements.txt
28+
29+
- name: Retrieve new components
30+
id: get-new-components
31+
run: ${{ env.COMPONENT_SCRIPT_PATH }} "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" validate_metadata
32+
33+
- name: Validate new components
34+
if: ${{ steps.get-new-components.outputs.new_components_list != '' }}
35+
run: |
36+
NEW_COMPONENTS_ARRAY="${{ steps.get-new-components.outputs.new_components_list }}"
37+
38+
# 2. Set IFS to a comma, so that the shell will split the string by commas.
39+
IFS=','
40+
41+
for component in $NEW_COMPONENTS_ARRAY; do
42+
COMPONENT_PATH="$GITHUB_WORKSPACE/$component"
43+
echo "Processing component: $component"
44+
python "${{ env.VALIDATION_SCRIPT_PATH }}" --component $COMPONENT_PATH
45+
done
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""Entry point for running validate_metadata as a module.
2+
"""
3+
4+
from .validate_metadata import main
5+
6+
if __name__ == "__main__":
7+
main()
8+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PyYAML==6.0.3
2+
semver==3.0.4
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
approvers:
2+
- sample-approver
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
tier: third_party
2+
name: happy-path-component
3+
stability: alpha | beta | stable
4+
dependencies:
5+
kubeflow:
6+
- name: Pipelines
7+
version: '>=2.5'
8+
- name: Trainer
9+
version: '>=2.0'
10+
external_services:
11+
- name: Argo Workflows
12+
version: "3.6"
13+
tags:
14+
- training
15+
- evaluation
16+
lastVerified: 2025-03-15T00:00:00Z
17+
ci:
18+
skip_dependency_probe: false
19+
pytest: optional
20+
links:
21+
documentation: https://kubeflow.org/components/happy-path-component
22+
issue_tracker: https://github.com/kubeflow/kfp-components/issues
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
approvers:
2+
- sample-approver
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: component_valid
2+
tier: third-party
3+
stability: alpha
4+
dependencies:
5+
kubeflow:
6+
- name: Pipelines
7+
version: '2.5.0'
8+
- name: Trainer
9+
version: '2.0.0'
10+
external_services:
11+
- name: Argo Workflows
12+
version: "3.6.0"
13+
tags:
14+
- training
15+
- evaluation
16+
lastVerified: 2025-03-15T00:00:00Z
17+
ci:
18+
skip_dependency_probe: false
19+
links:
20+
documentation: https://kubeflow.org/components/happy-path-component
21+
issue_tracker: https://github.com/kubeflow/kfp-components/issues

scripts/validate_metadata/test_data/component_directories_metadata/not_a_dir.txt

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: invalid-ci
2+
tier: core
3+
stability: alpha
4+
dependencies:
5+
kubeflow:
6+
- name: Pipelines
7+
version: '>=2.5.0'
8+
- name: Trainer
9+
version: '>=2.0.0'
10+
external_services:
11+
- name: Argo Workflows
12+
version: "3.6.0"
13+
tags:
14+
- training
15+
- evaluation
16+
lastVerified: 2025-03-15T00:00:00Z
17+
ci: invalid-ci-value
18+
links:
19+
documentation: https://kubeflow.org/components/happy-path-component
20+
issue_tracker: https://github.com/kubeflow/kfp-components/issues

0 commit comments

Comments
 (0)