From be23a37c2e48d0851f27e6dab545284f8a71bf7e Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 17 May 2026 11:14:35 +1000 Subject: [PATCH] feat: JSON Schema validation for metadata.yaml as pre-commit hook Adds schema/metadata.json (JSON Schema draft-07) as the authoritative schema for all rpms/*/metadata.yaml files. Key constraints: - additionalProperties: false at both the top level and builds items, so unknown fields are rejected outright - name allows dots (fixes neovim-glibc-2.17) - github is optional (fixes claude-code, which has no GitHub repo) - repository enum includes fedora/42, fedora/43, fedora/44 - dist_tag boolean field documented in schema Pre-commit hook (check-jsonschema 0.37.2) runs against every file matching ^rpms/[^/]+/metadata\.yaml$ on every commit. Also fixes rpms/claude-code/metadata.yaml: removes the unknown claude_ai field and normalises field order. --- .pre-commit-config.yaml | 8 +++ rpms/claude-code/metadata.yaml | 31 +++++---- schema/metadata.json | 111 +++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 schema/metadata.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f6f76cf..a4922d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,6 +31,14 @@ repos: "-s", ] + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.37.2 + hooks: + - id: check-jsonschema + name: Validate RPM package metadata + files: ^rpms/[^/]+/metadata\.yaml$ + args: [--schemafile, schema/metadata.json] + - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.7 hooks: diff --git a/rpms/claude-code/metadata.yaml b/rpms/claude-code/metadata.yaml index 01a8210..a099e9f 100644 --- a/rpms/claude-code/metadata.yaml +++ b/rpms/claude-code/metadata.yaml @@ -1,19 +1,18 @@ -arch: amd64 -builds: -- image: git.unkin.net/unkin/almalinux8-rpmbuilder:latest - release: 1 - repository: - - almalinux/el8 - version: 2.1.126 -- image: git.unkin.net/unkin/almalinux9-rpmbuilder:latest - release: 1 - repository: - - almalinux/el9 - version: 2.1.126 -claude_ai: true +name: claude-code description: Claude Code - Anthropic's agentic AI coding tool +arch: amd64 +platform: linux +maintainer: Anthropic homepage: https://claude.ai/code license: Proprietary -maintainer: Anthropic -name: claude-code -platform: linux +builds: +- repository: + - almalinux/el8 + image: git.unkin.net/unkin/almalinux8-rpmbuilder:latest + release: 1 + version: 2.1.126 +- repository: + - almalinux/el9 + image: git.unkin.net/unkin/almalinux9-rpmbuilder:latest + release: 1 + version: 2.1.126 diff --git a/schema/metadata.json b/schema/metadata.json new file mode 100644 index 0000000..61ed7d3 --- /dev/null +++ b/schema/metadata.json @@ -0,0 +1,111 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Schema for rpms/*/metadata.yaml files", + "properties": { + "arch": { + "enum": [ + "amd64", + "arm64", + "x86_64" + ], + "type": "string" + }, + "builds": { + "items": { + "additionalProperties": false, + "properties": { + "image": { + "minLength": 1, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-_.:/@]+$", + "type": "string" + }, + "release": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "number" + } + ] + }, + "repository": { + "items": { + "enum": [ + "almalinux/el8", + "almalinux/el9", + "fedora/42", + "fedora/43", + "fedora/44" + ], + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "version": { + "minLength": 1, + "pattern": "^[0-9]+(\\.[0-9]+)*(-[a-zA-Z0-9]+)*$", + "type": "string" + } + }, + "required": [ + "repository", + "image", + "release", + "version" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "description": { + "minLength": 1, + "type": "string" + }, + "dist_tag": { + "type": "boolean" + }, + "github": { + "minLength": 1, + "pattern": "^[a-zA-Z0-9\\-_]+/[a-zA-Z0-9\\-_.]+$", + "type": "string" + }, + "github_release_pattern": { + "minLength": 1, + "type": "string" + }, + "homepage": { + "minLength": 1, + "pattern": "^https?://.+", + "type": "string" + }, + "license": { + "minLength": 1, + "type": "string" + }, + "maintainer": { + "minLength": 1, + "type": "string" + }, + "name": { + "minLength": 1, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-_.]*$", + "type": "string" + }, + "platform": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "description", + "builds" + ], + "title": "RPM Package Metadata", + "type": "object" +}