diff --git a/.github/workflows/lava-schema-check.yml b/.github/workflows/lava-schema-check.yml new file mode 100644 index 00000000..f87b1e2d --- /dev/null +++ b/.github/workflows/lava-schema-check.yml @@ -0,0 +1,28 @@ +name: Chech LAVA templates + +on: + workflow_call: + +jobs: + schema-check: + runs-on: ubuntu-latest + container: lavasoftware/lava-server:2024.09 + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Schema check + run: | + DEVICE_TYPE="my-device" + BUILD_FILE_NAME="build.tar.gz" + BUILD_DOWNLOAD_URL="https://example.com/downloads/1" + GITHUB_SHA="7e6f96ccf3e911a8a1a18accdbb91991aa0db66e" + + find ci/lava/ -name "*.yaml" -exec sed -i "s|{{DEVICE_TYPE}}|${DEVICE_TYPE}|g" '{}' \; + find ci/lava/ -name "*.yaml" -exec sed -i "s|{{GITHUB_SHA}}|${GITHUB_SHA}|g" '{}' \; + find ci/lava/ -name "*.yaml" -exec sed -i "s|{{BUILD_DOWNLOAD_URL}}|${BUILD_DOWNLOAD_URL}|g" '{}' \; + find ci/lava/ -name "*.yaml" -exec sed -i "s|{{BUILD_FILE_NAME}}|${BUILD_FILE_NAME}|g" '{}' \; + find ci/lava/ -name "*.yaml" -exec sed -i "s|{{GITHUB_RUN_ID}}|${GITHUB_RUN_ID}|g" '{}' \; + + python3 ci/schemacheck.py ./ci/lava/ diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 768c7c8f..eb200f79 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -21,4 +21,6 @@ jobs: path: ${{ github.event_path }} build-pr: uses: ./.github/workflows/build-yocto.yml + schema-check: + uses: ./.github/workflows/lava-schema-check.yml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index d3dde8bd..8b1b74e2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -14,9 +14,11 @@ permissions: jobs: build: uses: ./.github/workflows/build-yocto.yml + schema-check: + uses: ./.github/workflows/lava-schema-check.yml test: uses: ./.github/workflows/test.yml - needs: build + needs: [build, schema-check] secrets: inherit with: url: ${{ needs.build.outputs.artifacts_url }} diff --git a/ci/lava/README.md b/ci/lava/README.md new file mode 100644 index 00000000..ad85883d --- /dev/null +++ b/ci/lava/README.md @@ -0,0 +1,35 @@ +# Test setup + +`ci/lava` directory contains directories with names corresponding to build MACHINE names. +New directories should only be added after the build is available for a given MACHINE. +All files in the `ci/lava/` directory should have `.yaml` extension. +Each file should be a valid LAVA job template. + +LAVA templates are used to create test jobs during the CI runs in this repository. +This happens for the following triggers: + - pull_request + - push + - cron (nightly build) + +# LAVA job templates + +Job templates can use the following variables: + - `DEVICE_TYPE`: name of the LAVA device type or alias. Full list can be found on [LAVA master web interface](https://lava.infra.foundries.io/scheduler/device_types) + - `GITHUB_SHA`: Commit ID corresponding to the github action trigger + - `BUILD_FILE_NAME`: Name of the build artifact to be downloaded. It's constructed as: `core-image-base-${DEVICE_TYPE}.rootfs.qcomflash.tar.gz` + - `BUILD_DOWNLOAD_URL`: URL where the build artifacts can be found. This variable is constructed as: `${{inputs.url}}/${DEVICE_TYPE}/${BUILD_FILE_NAME}` where `{{inputs.url}}` comes from the build action. + - `GITHUB_RUN_ID`: ID of the current Github run. + +After variable substitution the file should form a valid LAVA job definition. + +# Template validation + +Template validation is performed as github action using `lavasoftware/lava-server` container. +Version of the container will be kept in sync with the LAVA server running the test jobs. +Validation script, `schemacheck.py`, uses LAVA code from `lava_common.schemas.validate` method and PyYAML parser. + +## Local template validation + +Templates can be validated locally using `lavasoftware/lava-server` container. + + docker run --rm -v $PWD:/home/ lavasoftware/lava-server:latest python3 /home/ci/schemacheck.py /home/ci/lava diff --git a/ci/schemacheck.py b/ci/schemacheck.py new file mode 100644 index 00000000..e8107802 --- /dev/null +++ b/ci/schemacheck.py @@ -0,0 +1,33 @@ +# Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. +# SPDX-License-Identifier: MIT + +import os +import sys +import yaml +import voluptuous +from lava_common.schemas import validate + +exitcode = 0 + +for root, dirs, files in os.walk(sys.argv[1]): + for fname in files: + if fname.endswith(".yaml"): + filename = os.path.join(root, fname) + + try: + f = open(filename, "rb") + y = yaml.safe_load(f) + f.close() + validate(y) + print(f"{filename} is valid") + except voluptuous.Invalid as e1: + print(f"{filename} is invalid") + print(e1.msg) + print(e1.path) + exitcode += 1 + except yaml.error.MarkedYAMLError as e2: + print(f"{filename} is invalid") + print(e2.problem) + print(e2.problem_mark) + exitcode += 1 +sys.exit(exitcode)