From 2852d54f098ac28123a7fa256a54a2bb73509e21 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Mon, 12 Jan 2026 12:05:13 -0800 Subject: [PATCH] Allow extra properties Quick vibe code to close #6 --- README.md | 19 +++++++++++- action.yaml | 5 +++ docker/entrypoint.sh | 73 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a9a5ad6..9505776 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,10 @@ jobs: uses: actions/checkout@v4 - name: 🛡️ Validate Zenodo Metadata - uses: vsoch/zenodo-validator@main + uses: vsoch/zenodo-validator@main with: path: '.zenodo.json' + allowed_extra_properties: 'pub_id' # Optional: allow extra properties ``` @@ -42,6 +43,7 @@ docker run --rm \ -e INPUT_PATH=.zenodo.json \ -e INPUT_SCHEMA_PATH=/schema.json \ -e INPUT_ERROR_FORMAT=text \ + -e INPUT_ALLOWED_EXTRA_PROPERTIES=pub_id \ zenodo-validator ``` @@ -60,6 +62,21 @@ And you can also use the image provided: `ghcr.io/vsoch/zenodo-validator`. | :--- | :--- | :--- | | `path` 📍 | Where is your `.zenodo.json`? | `.zenodo.json` | | `error_format` 🎨 | `text`, `json`, or `pretty-json` | `text` | +| `allowed_extra_properties` ✨ | Comma-separated list of extra property names to allow (e.g., `pub_id,custom_field`) | `''` (empty) | + +### 🔓 Allowing Extra Properties + +Some Invenio instances (like [RODARE](https://rodare.hzdr.de)) require additional properties beyond the standard Zenodo schema. You can explicitly allow these properties using the `allowed_extra_properties` input: + +```yaml +- name: 🛡️ Validate Zenodo Metadata + uses: vsoch/zenodo-validator@main + with: + path: '.rodare.json' + allowed_extra_properties: 'pub_id' +``` + +This will allow the specified properties while still validating all other fields against the Zenodo schema. Multiple properties can be specified as a comma-separated list: `'pub_id,custom_field,another_field'`. --- diff --git a/action.yaml b/action.yaml index f9e2b09..b5c9700 100644 --- a/action.yaml +++ b/action.yaml @@ -13,6 +13,10 @@ inputs: description: 'Output format (text, json, pretty-json)' required: false default: 'text' + allowed_extra_properties: + description: 'Comma-separated list of extra property names to allow (e.g., "pub_id,custom_field")' + required: false + default: '' runs: using: 'docker' @@ -21,3 +25,4 @@ runs: INPUT_PATH: ${{ inputs.path }} INPUT_SCHEMA_PATH: ${{ inputs.schema_path }} INPUT_ERROR_FORMAT: ${{ inputs.error_format }} + INPUT_ALLOWED_EXTRA_PROPERTIES: ${{ inputs.allowed_extra_properties }} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index d9162fb..a15191a 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -22,10 +22,81 @@ fi echo "🔮 Summoning the JSON spirits to check your work..." echo "📜 Using Schema: $SCHEMA_PATH" echo "🎨 Output Format: $INPUT_ERROR_FORMAT" + +# Handle allowed extra properties +FINAL_SCHEMA_PATH="$SCHEMA_PATH" +if [ -n "$INPUT_ALLOWED_EXTRA_PROPERTIES" ]; then + echo "✨ Allowing extra properties: $INPUT_ALLOWED_EXTRA_PROPERTIES" + FINAL_SCHEMA_PATH="/tmp/modified_schema.json" + + # Use Python to modify the schema and add allowed extra properties + if ! SCHEMA_PATH_ESC="$SCHEMA_PATH" \ + FINAL_SCHEMA_PATH_ESC="$FINAL_SCHEMA_PATH" \ + ALLOWED_PROPS_ESC="$INPUT_ALLOWED_EXTRA_PROPERTIES" \ + python3 << 'PYTHON_EOF' +import json +import os +import sys + +try: + schema_path = os.environ['SCHEMA_PATH_ESC'] + final_schema_path = os.environ['FINAL_SCHEMA_PATH_ESC'] + allowed_props_str = os.environ['ALLOWED_PROPS_ESC'] + + # Read the original schema + with open(schema_path, 'r') as f: + schema = json.load(f) + + # Ensure schema has the expected structure + if not isinstance(schema, dict): + print('❌ ERROR: Schema must be a JSON object', file=sys.stderr) + sys.exit(1) + + # Parse comma-separated list of allowed properties + allowed_props = [prop.strip() for prop in allowed_props_str.split(',') if prop.strip()] + + if not allowed_props: + print('❌ ERROR: No valid property names found in allowed_extra_properties', file=sys.stderr) + sys.exit(1) + + # Ensure properties object exists + if 'properties' not in schema: + schema['properties'] = {} + + # Add each allowed property to the schema's properties object + # Use empty schema {} which allows any type + for prop in allowed_props: + if prop not in schema['properties']: + schema['properties'][prop] = {} + + # Write the modified schema + with open(final_schema_path, 'w') as f: + json.dump(schema, f, indent=2) + + print(f'✅ Modified schema written to {final_schema_path}') +except KeyError as e: + print(f'❌ ERROR: Missing environment variable: {e}', file=sys.stderr) + sys.exit(1) +except FileNotFoundError: + print(f'❌ ERROR: Schema file not found: {schema_path}', file=sys.stderr) + sys.exit(1) +except json.JSONDecodeError as e: + print(f'❌ ERROR: Invalid JSON in schema file: {e}', file=sys.stderr) + sys.exit(1) +except Exception as e: + print(f'❌ ERROR: Failed to modify schema: {e}', file=sys.stderr) + sys.exit(1) +PYTHON_EOF + then + echo "❌ Failed to modify schema for extra properties" + exit 1 + fi +fi + echo "" # Run check-jsonschema with the corrected flag: --output-format -if check-jsonschema --schemafile "$SCHEMA_PATH" "$FILE_TO_VALIDATE" --output-format "$INPUT_ERROR_FORMAT"; then +if check-jsonschema --schemafile "$FINAL_SCHEMA_PATH" "$FILE_TO_VALIDATE" --output-format "$INPUT_ERROR_FORMAT"; then echo "" echo "🥳 HOORAY! Your .zenodo.json is shiny and valid!" echo "🏆 You're a hero of Open Science! 🚀✨"