Skip to content

Commit

Permalink
feat: define common interfaces in a versioned schema (#202)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
eeberhard authored Jan 9, 2025
1 parent f849109 commit 5b0f46f
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 57 deletions.
28 changes: 18 additions & 10 deletions .github/actions/bundle-schema/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
58 changes: 34 additions & 24 deletions .github/workflows/bundle-schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 \
Expand All @@ -62,4 +73,3 @@ jobs:
) || echo "::warning::Error creating the PR: $MESSAGE"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

7 changes: 3 additions & 4 deletions schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -41,5 +41,4 @@ Available `schema_collection` options are:
- `applications`
- `component-descriptions`
- `controller-descriptions`
- `parameters`
- `signals`
- `interfaces`
1 change: 1 addition & 0 deletions schemas/interfaces/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# CHANGELOG
4 changes: 4 additions & 0 deletions schemas/interfaces/README.md
Original file line number Diff line number Diff line change
@@ -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.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
29 changes: 29 additions & 0 deletions schemas/interfaces/schema/interfaces.schema.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
11 changes: 5 additions & 6 deletions schemas/serve-html.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
11 changes: 5 additions & 6 deletions schemas/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
14 changes: 8 additions & 6 deletions utils/bundleHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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!');
});
}
});
Expand Down

0 comments on commit 5b0f46f

Please sign in to comment.