From 20419484f7c4a6a1766ecd68b69bcc6f7e7d4434 Mon Sep 17 00:00:00 2001 From: Rodrigo Horie Date: Thu, 5 Feb 2026 17:56:28 -0300 Subject: [PATCH] Add CI Checks for syntactically valid OpenAPI Specification --- .github/workflows/api_schema_check.yml | 40 ++++++++++++++++++++++---- Makefile | 4 +++ requirements/requirements_dev.txt | 1 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.github/workflows/api_schema_check.yml b/.github/workflows/api_schema_check.yml index d2f940c360..60b63055c5 100644 --- a/.github/workflows/api_schema_check.yml +++ b/.github/workflows/api_schema_check.yml @@ -45,15 +45,45 @@ jobs: make docker-runner 2>&1 | tee schema-diff.txt exit ${PIPESTATUS[0]} - - name: Add schema diff to job summary + - name: Validate OpenAPI schema + id: schema-validation + continue-on-error: true + run: | + AWX_DOCKER_ARGS='-e GITHUB_ACTIONS' \ + AWX_DOCKER_CMD='make validate-openapi-schema' \ + make docker-runner 2>&1 | tee schema-validation.txt + exit ${PIPESTATUS[0]} + + - name: Add schema validation and diff to job summary if: always() # show text and if for some reason, it can't be generated, state that it can't be. run: | - echo "## API Schema Change Detection Results" >> $GITHUB_STEP_SUMMARY + echo "## API Schema Check Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY + + # Show validation status + echo "### OpenAPI Validation" >> $GITHUB_STEP_SUMMARY + if [ -f schema-validation.txt ] && grep -q "✓ Schema is valid" schema-validation.txt; then + echo "✅ **Status:** PASSED - Schema is valid OpenAPI 3.0.3" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **Status:** FAILED - Schema validation failed" >> $GITHUB_STEP_SUMMARY + if [ -f schema-validation.txt ]; then + echo "" >> $GITHUB_STEP_SUMMARY + echo "
Validation errors" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + cat schema-validation.txt >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "
" >> $GITHUB_STEP_SUMMARY + fi + fi + echo "" >> $GITHUB_STEP_SUMMARY + + # Show schema changes + echo "### Schema Changes" >> $GITHUB_STEP_SUMMARY if [ -f schema-diff.txt ]; then if grep -q "^+" schema-diff.txt || grep -q "^-" schema-diff.txt; then - echo "### Schema changes detected" >> $GITHUB_STEP_SUMMARY + echo "**Changes detected** between this PR and the base branch" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Truncate to first 1000 lines to stay under GitHub's 1MB summary limit TOTAL_LINES=$(wc -l < schema-diff.txt) @@ -65,8 +95,8 @@ jobs: head -n 1000 schema-diff.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY else - echo "### No schema changes detected" >> $GITHUB_STEP_SUMMARY + echo "No schema changes detected" >> $GITHUB_STEP_SUMMARY fi else - echo "### Unable to generate schema diff" >> $GITHUB_STEP_SUMMARY + echo "Unable to generate schema diff" >> $GITHUB_STEP_SUMMARY fi diff --git a/Makefile b/Makefile index cf5395a218..fca4ea01e4 100644 --- a/Makefile +++ b/Makefile @@ -579,6 +579,10 @@ detect-schema-change: genschema # diff exits with 1 when files differ - capture but don't fail -diff -u -b reference-schema.json schema.json +validate-openapi-schema: genschema + @echo "Validating OpenAPI schema from schema.json..." + @python3 -c "from openapi_spec_validator import validate; import json; spec = json.load(open('schema.json')); validate(spec); print('✓ OpenAPI Schema is valid!')" + docker-compose-clean: awx/projects $(DOCKER_COMPOSE) -f tools/docker-compose/_sources/docker-compose.yml rm -sf diff --git a/requirements/requirements_dev.txt b/requirements/requirements_dev.txt index 7c6a84ceb3..6ba0017fa3 100644 --- a/requirements/requirements_dev.txt +++ b/requirements/requirements_dev.txt @@ -2,6 +2,7 @@ build django-debug-toolbar>=6.0 # Django 5.2 compatibility django-test-migrations drf-spectacular>=0.27.0 # Modern OpenAPI 3.0 schema generator +openapi-spec-validator # OpenAPI 3.0 schema validation # pprofile - re-add once https://github.com/vpelletier/pprofile/issues/41 is addressed ipython>=7.31.1 # https://github.com/ansible/awx/security/dependabot/30 unittest2