From 5b0f46fe62999dc291c8bf5e37e5ac3484840801 Mon Sep 17 00:00:00 2001 From: Enrico Eberhard <32450951+eeberhard@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:53:34 +0100 Subject: [PATCH] feat: define common interfaces in a versioned schema (#202) * refactor: move all unversioned subschemas into common interfaces directory * feat: common interfaces.schema.jon * ci: use matrix strategy for handling schemas * chore: update schema helper scripts * chore: update readme * fix: add check around hardcoded assumption in bundle utils * ci: improve reliability of workflows --- .github/actions/bundle-schema/action.yml | 28 +++++---- .github/workflows/bundle-schema.yml | 58 +++++++++++-------- schemas/README.md | 7 +-- schemas/interfaces/CHANGELOG.md | 1 + schemas/interfaces/README.md | 4 ++ .../common}/encoded_state_type.schema.json | 0 .../schema/common}/parameter.schema.json | 0 .../schema/common}/parameter_type.schema.json | 0 .../schema/common}/predicate.schema.json | 0 .../schema/common}/service.schema.json | 0 .../schema/common}/signal.schema.json | 0 .../schema/common}/signal_type.schema.json | 2 +- .../interfaces/schema/interfaces.schema.json | 29 ++++++++++ schemas/serve-html.sh | 11 ++-- schemas/validate.sh | 11 ++-- utils/bundleHelper.js | 14 +++-- 16 files changed, 108 insertions(+), 57 deletions(-) create mode 100644 schemas/interfaces/CHANGELOG.md create mode 100644 schemas/interfaces/README.md rename schemas/{parameters/schema => interfaces/schema/common}/encoded_state_type.schema.json (100%) rename schemas/{parameters/schema => interfaces/schema/common}/parameter.schema.json (100%) rename schemas/{parameters/schema => interfaces/schema/common}/parameter_type.schema.json (100%) rename schemas/{predicates/schema => interfaces/schema/common}/predicate.schema.json (100%) rename schemas/{services/schema => interfaces/schema/common}/service.schema.json (100%) rename schemas/{signals/schema => interfaces/schema/common}/signal.schema.json (100%) rename schemas/{signals/schema => interfaces/schema/common}/signal_type.schema.json (74%) create mode 100644 schemas/interfaces/schema/interfaces.schema.json diff --git a/.github/actions/bundle-schema/action.yml b/.github/actions/bundle-schema/action.yml index ac3e74bf..879dea21 100644 --- a/.github/actions/bundle-schema/action.yml +++ b/.github/actions/bundle-schema/action.yml @@ -21,13 +21,18 @@ runs: # Check if the version has been updated - id: versions run: | - NEW_VERSION=$(jq -r '.["$id"]' ${{ inputs.schema-path }}) - echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT - IFS='/' read -a id_array <<< "$NEW_VERSION" - echo "version_only=${id_array[1]}" >> $GITHUB_OUTPUT + SCHEMA_ID=$(jq -r '.["$id"]' ${{ inputs.schema-path }}) + # remove the first slash + SCHEMA_ID="${SCHEMA_ID#/*}" + # remove the schema name at the end of the ID to leave just the version + SCHEMA_VERSION="${SCHEMA_ID%/*}" + echo "new_schema_id=${SCHEMA_ID}" >> $GITHUB_OUTPUT + echo "new_schema_version=${SCHEMA_VERSION}" >> $GITHUB_OUTPUT git checkout HEAD^ - PREV_VERSION=$( jq -r '.["$id"]' ${{ inputs.schema-path }}) - echo "prev_version=${PREV_VERSION}" >> $GITHUB_OUTPUT + PREV_SCHEMA_ID=$( jq -r '.["$id"]' ${{ inputs.schema-path }}) + # remove the first slash + PREV_SCHEMA_ID="${PREV_SCHEMA_ID#/*}" + echo "prev_schema_id=${PREV_SCHEMA_ID}" >> $GITHUB_OUTPUT shell: bash - uses: actions/checkout@v3 # Bundle JSON schema @@ -43,17 +48,20 @@ runs: npm ci pip3 install javascript - name: Bundle & Push schemas - if: ${{ steps.versions.outputs.new_version != steps.versions.outputs.prev_version }} + if: ${{ steps.versions.outputs.new_schema_id != steps.versions.outputs.prev_schema_id }} shell: bash run: | node utils/bundleHelper.js ${{ inputs.schema-path }} ${{ inputs.schema }} - mkdir -p docs/static/schemas/${{ steps.versions.outputs.version_only }} - mv ${{ inputs.schema }} docs/static/schemas${{ steps.versions.outputs.new_version }} + echo "Ensuring directory branch name: docs/static/schemas/${{ steps.versions.outputs.new_schema_version }}" + mkdir -p docs/static/schemas/${{ steps.versions.outputs.new_schema_version }} + echo "Moving schema to path docs/static/schemas/${{ steps.versions.outputs.new_schema_id }}" + mv ${{ inputs.schema }} docs/static/schemas/${{ steps.versions.outputs.new_schema_id }} git config --global user.name github-actions[bot] git config --global user.email github-actions[bot]@users.noreply.github.com git fetch git checkout ${{ inputs.branch-name }} git pull git add . - git diff-index --quiet HEAD || git commit -m "docs: ${{ inputs.schema }} ${{ steps.versions.outputs.version_only }}" + git diff-index --quiet HEAD || git commit -m "docs: ${{ inputs.schema }} ${{ steps.versions.outputs.new_schema_version }}" + echo "Pushing commit to ${{ inputs.branch-name }}" git push diff --git a/.github/workflows/bundle-schema.yml b/.github/workflows/bundle-schema.yml index 94ff9058..c746edfc 100644 --- a/.github/workflows/bundle-schema.yml +++ b/.github/workflows/bundle-schema.yml @@ -8,9 +8,11 @@ on: - 'schemas/**' jobs: - bundle-push-schemas: + setup: runs-on: ubuntu-latest - name: bundle-and-push-schemas + name: Set up a branch to update schemas + outputs: + branch_name: ${{ steps.branch-name.outputs.branch_name }} steps: - name: Check out repository code uses: actions/checkout@v3 @@ -25,35 +27,44 @@ jobs: echo "branch_name=${BRANCH_NAME}" >> $GITHUB_OUTPUT git checkout -b ${BRANCH_NAME} git push -u origin ${BRANCH_NAME} - - name: Bundle & Push JSON schema for application schemas - uses: ./.github/actions/bundle-schema - with: - schema-path: ./schemas/applications/schema/application.schema.json - schema: application.schema.json - branch-name: ${{ steps.branch-name.outputs.branch_name }} - - name: Bundle & Push JSON schema for component-descriptions schemas - uses: ./.github/actions/bundle-schema - with: - schema-path: ./schemas/component-descriptions/schema/component.schema.json - schema: component.schema.json - branch-name: ${{ steps.branch-name.outputs.branch_name }} - - name: Bundle & Push JSON schema for controller schemas - uses: ./.github/actions/bundle-schema + + bundle-schemas: + runs-on: ubuntu-latest + needs: setup + strategy: + matrix: + include: + - schema: application + schema-path: ./schemas/applications/schema + - schema: component + schema-path: ./schemas/component-descriptions/schema + - schema: controller + schema-path: ./schemas/controller-descriptions/schema + - schema: interfaces + schema-path: ./schemas/interfaces/schema + name: Bundle the ${{ matrix.schema }} schema + steps: + - uses: ./.github/actions/bundle-schema with: - schema-path: ./schemas/controller-descriptions/schema/controller.schema.json - schema: controller.schema.json - branch-name: ${{ steps.branch-name.outputs.branch_name }} - - name: Checkout branch ci/update-schemas + schema-path: ${{ matrix.schema-path }}/${{ matrix.schema }}.schema.json + schema: ${{ matrix.schema }}.schema.json + branch-name: ${{ needs.setup.outputs.branch_name }} + + push-schemas: + runs-on: ubuntu-latest + needs: [setup, bundle-schemas] + steps: + - name: Checkout branch ${{ needs.setup.outputs.branch_name }} uses: actions/checkout@v3 with: - ref: ${{ steps.branch-name.outputs.branch_name }} - - name: Create pull request + ref: ${{ needs.setup.outputs.branch_name }} + - name: Create pull request on branch ${{ needs.setup.outputs.branch_name }} shell: bash run: | MESSAGE=$( gh pr create \ -B main \ - -H ${{ steps.branch-name.outputs.branch_name }} \ + -H ${{ needs.setup.outputs.branch_name }} \ --title 'ci: update schemas' \ --body 'This PR was automatically created by GitHub actions in response to schema changes. Please review and update any impacted code before merging the changes.' \ --reviewer domire8 \ @@ -62,4 +73,3 @@ jobs: ) || echo "::warning::Error creating the PR: $MESSAGE" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - diff --git a/schemas/README.md b/schemas/README.md index 09f4ee84..c243c6c1 100644 --- a/schemas/README.md +++ b/schemas/README.md @@ -16,9 +16,9 @@ of AICA component classes. The [controller-descriptions](./controller-descriptions) directory defines the JSON syntax for describing the properties of AICA controller plugins. -## Parameters and Signals schema +## Interfaces -The [parameters](./parameters) and [signals](./signals) directories contains common schema definitions used by both +The [interfaces](./interfaces) directory defines a schema with common interface definitions used by both the component and controller descriptions. ## Tools @@ -41,5 +41,4 @@ Available `schema_collection` options are: - `applications` - `component-descriptions` - `controller-descriptions` -- `parameters` -- `signals` +- `interfaces` diff --git a/schemas/interfaces/CHANGELOG.md b/schemas/interfaces/CHANGELOG.md new file mode 100644 index 00000000..a0cf709b --- /dev/null +++ b/schemas/interfaces/CHANGELOG.md @@ -0,0 +1 @@ +# CHANGELOG diff --git a/schemas/interfaces/README.md b/schemas/interfaces/README.md new file mode 100644 index 00000000..31719f06 --- /dev/null +++ b/schemas/interfaces/README.md @@ -0,0 +1,4 @@ +# JSON Schema for Common Interfaces + +This schema defines common interfaces that are reusable across other schemas. In particular, the definitions of +parameter, predicate, signal and service interfaces are used by both the component and controller description schemas. \ No newline at end of file diff --git a/schemas/parameters/schema/encoded_state_type.schema.json b/schemas/interfaces/schema/common/encoded_state_type.schema.json similarity index 100% rename from schemas/parameters/schema/encoded_state_type.schema.json rename to schemas/interfaces/schema/common/encoded_state_type.schema.json diff --git a/schemas/parameters/schema/parameter.schema.json b/schemas/interfaces/schema/common/parameter.schema.json similarity index 100% rename from schemas/parameters/schema/parameter.schema.json rename to schemas/interfaces/schema/common/parameter.schema.json diff --git a/schemas/parameters/schema/parameter_type.schema.json b/schemas/interfaces/schema/common/parameter_type.schema.json similarity index 100% rename from schemas/parameters/schema/parameter_type.schema.json rename to schemas/interfaces/schema/common/parameter_type.schema.json diff --git a/schemas/predicates/schema/predicate.schema.json b/schemas/interfaces/schema/common/predicate.schema.json similarity index 100% rename from schemas/predicates/schema/predicate.schema.json rename to schemas/interfaces/schema/common/predicate.schema.json diff --git a/schemas/services/schema/service.schema.json b/schemas/interfaces/schema/common/service.schema.json similarity index 100% rename from schemas/services/schema/service.schema.json rename to schemas/interfaces/schema/common/service.schema.json diff --git a/schemas/signals/schema/signal.schema.json b/schemas/interfaces/schema/common/signal.schema.json similarity index 100% rename from schemas/signals/schema/signal.schema.json rename to schemas/interfaces/schema/common/signal.schema.json diff --git a/schemas/signals/schema/signal_type.schema.json b/schemas/interfaces/schema/common/signal_type.schema.json similarity index 74% rename from schemas/signals/schema/signal_type.schema.json rename to schemas/interfaces/schema/common/signal_type.schema.json index 7dde4a39..36aa25f7 100644 --- a/schemas/signals/schema/signal_type.schema.json +++ b/schemas/interfaces/schema/common/signal_type.schema.json @@ -15,7 +15,7 @@ ] }, { - "$ref": "https://raw.githubusercontent.com/aica-technology/api/main/schemas/parameters/schema/encoded_state_type.schema.json" + "$ref": "encoded_state_type.schema.json" } ] } \ No newline at end of file diff --git a/schemas/interfaces/schema/interfaces.schema.json b/schemas/interfaces/schema/interfaces.schema.json new file mode 100644 index 00000000..d3609145 --- /dev/null +++ b/schemas/interfaces/schema/interfaces.schema.json @@ -0,0 +1,29 @@ +{ + "$id": "/draft/1-0-0/interfaces.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Common Interfaces", + "description": "This schema includes definitions for common interfaces across the AICA System", + "$defs": { + "encoded_state_type": { + "$ref": "common/encoded_state_type.schema.json" + }, + "parameter": { + "$ref": "common/parameter.schema.json" + }, + "parameter_type": { + "$ref": "common/parameter_type.schema.json" + }, + "predicate": { + "$ref": "common/predicate.schema.json" + }, + "service": { + "$ref": "common/service.schema.json" + }, + "signal": { + "$ref": "common/signal.schema.json" + }, + "signal_type": { + "$ref": "common/signal_type.schema.json" + } + } +} \ No newline at end of file diff --git a/schemas/serve-html.sh b/schemas/serve-html.sh index e7cb7810..c92706f9 100755 --- a/schemas/serve-html.sh +++ b/schemas/serve-html.sh @@ -7,6 +7,8 @@ if [ "$#" -ne 1 ]; then echo "Currently supported schema collections:" echo " - applications" echo " - component-descriptions" + echo " - controller-descriptions" + echo " - interfaces" echo exit 0 fi @@ -22,12 +24,9 @@ elif [ "$SCHEMA" == "component-descriptions" ]; then elif [ "$SCHEMA" == "controller-descriptions" ]; then echo "Using AICA controller description schema" SCHEMA_HTML="controller.schema.html" -elif [ "$SCHEMA" == "parameters" ]; then - echo "Using AICA parameter schema" - SCHEMA_HTML="parameter.schema.html" -elif [ "$SCHEMA" == "signals" ]; then - echo "Using AICA signal schema" - SCHEMA_HTML="signal.schema.html" +elif [ "$SCHEMA" == "interfaces" ]; then + echo "Using AICA interfaces schema" + SCHEMA_HTML="interfaces.schema.html" else echo "Invalid schema option: $SCHEMA" exit 0 diff --git a/schemas/validate.sh b/schemas/validate.sh index 2c438f3a..70b3d7c5 100755 --- a/schemas/validate.sh +++ b/schemas/validate.sh @@ -7,6 +7,8 @@ if [ "$#" -ne 2 ]; then echo "Currently supported schema collections:" echo " - applications" echo " - component-descriptions" + echo " - controller-descriptions" + echo " - interfaces" echo exit 0 fi @@ -22,12 +24,9 @@ elif [ "$SCHEMA" == "component-descriptions" ]; then elif [ "$SCHEMA" == "controller-descriptions" ]; then echo "Using AICA controller description schema" SCHEMA_ENTRYPOINT="controller.schema.json" -elif [ "$SCHEMA" == "parameters" ]; then - echo "Using AICA parameter schema" - SCHEMA_ENTRYPOINT="parameter.schema.json" -elif [ "$SCHEMA" == "signals" ]; then - echo "Using AICA signal schema" - SCHEMA_ENTRYPOINT="signal.schema.json" +elif [ "$SCHEMA" == "interfaces" ]; then + echo "Using AICA interfaces schema" + SCHEMA_ENTRYPOINT="interfaces.schema.json" else echo "Invalid schema option: $SCHEMA" exit 0 diff --git a/utils/bundleHelper.js b/utils/bundleHelper.js index 98904051..3680dd1e 100644 --- a/utils/bundleHelper.js +++ b/utils/bundleHelper.js @@ -9,18 +9,20 @@ $RefParser.bundle(filePath).then(async (schema) => { let jsonSchema = decodeURI(JSON.stringify(schema, null, 2)); jsonSchema = jsonSchema.replaceAll('%24', '$'); - if(outputFileName === "application.schema.json") { + if (outputFileName === "application.schema.json") { fs.writeFile(outputFileName, jsonSchema, 'utf8', (err) => { - if (err) throw err; - console.log('The file has been saved!'); + if (err) throw err; + console.log('The file has been saved!'); }); } else { let jsonSchemaObject = JSON.parse(jsonSchema); // Avoid nested reference (cannot be resolved by VSCode) - jsonSchemaObject['properties']['parameters']['items']['properties']['parameter_state_type']['$ref'] = '#/properties/inputs/items/properties/signal_types/items'; + if (jsonSchemaObject?.['properties']?.['parameters']?.['items']?.['properties']?.['parameter_state_type']?.['$ref']) { + jsonSchemaObject['properties']['parameters']['items']['properties']['parameter_state_type']['$ref'] = '#/properties/inputs/items/properties/signal_types/items'; + } fs.writeFile(outputFileName, JSON.stringify(jsonSchemaObject, null, 2), 'utf8', (err) => { - if (err) throw err; - console.log('The file has been saved!'); + if (err) throw err; + console.log('The file has been saved!'); }); } });