diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6ab8a1f..faf66aa 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,8 +94,16 @@ jobs: path: versions.json if-no-files-found: error + schema-check: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2 + + - run: npx -p ajv-cli@3.3.0 ajv compile -s schema.json + upload-to-s3: - needs: [package-tests, full-test] + needs: [package-tests, full-test, schema-check] if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest timeout-minutes: 60 @@ -141,5 +149,7 @@ jobs: run: rm -fv versions.json - name: Download the current versions.json from S3 run: curl -LO https://julialang-s3.julialang.org/bin/versions.json + - name: Validate versions.json against schema + run: npx -p ajv-cli@3.3.0 ajv -s schema.json -d versions.json - name: Run the post-build tests on the versions.json that we downloaded from S3 run: julia --project test/more_tests.jl versions.json diff --git a/schema.json b/schema.json index c79c1c6..1f6c806 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,34 @@ { "$schema": "http://json-schema.org/draft-06/schema#", "type": "object", + "minProperties": 1, + "propertyNames": { + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" + }, + "allOf": [ + { + "patternProperties": { + "^[0-9]+\\.[0-9]+\\.[0-9]+-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta))$": { + "properties": { + "stable": { + "const": false + } + } + } + } + }, + { + "patternProperties": { + "^[0-9]+\\.[0-9]+\\.[0-9]+$": { + "properties": { + "stable": { + "const": true + } + } + } + } + } + ], "additionalProperties": { "$ref": "#/definitions/WelcomeValue" }, @@ -11,6 +39,8 @@ "properties": { "files": { "type": "array", + "minItems": 1, + "uniqueItems": true, "items": { "$ref": "#/definitions/File" } @@ -39,19 +69,24 @@ "$ref": "#/definitions/Arch" }, "sha256": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{64}$" }, "git-tree-sha1": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{40}$" }, "git-tree-sha256": { - "type": "string" + "type": "string", + "pattern": "^[0-9A-Fa-f]{64}$" }, "size": { - "type": "integer" + "type": "integer", + "minimum": 1 }, "version": { - "type": "string" + "type": "string", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-(?:alpha[0-9]*|beta[0-9]*|rc[0-9]+|pre\\.(?:alpha|beta)))?$" }, "os": { "$ref": "#/definitions/OS" @@ -65,12 +100,25 @@ "qt-uri-extensions": [ ".dmg", ".exe", - ".gz", + ".tar.gz", ".zip" + ], + "allOf": [ + { + "pattern": "^https://[^/?#]+/" + }, + { + "pattern": "^https://\\S+$" + }, + { + "pattern": "/[^/?#]+\\.(?:dmg|exe|tar\\.gz|zip)$" + } ] }, "asc": { - "type": "string" + "type": "string", + "minLength": 1, + "pattern": "^-----BEGIN PGP SIGNATURE-----\\n(?:[A-Za-z0-9-]+: [^\\n]*\\n)*\\n(?:[A-Za-z0-9+/]{1,76}=*\\n)+=[A-Za-z0-9+/]{4}\\n-----END PGP SIGNATURE-----\\n?$" }, "extension": { "$ref": "#/definitions/FileExtension" @@ -87,6 +135,203 @@ "url", "version" ], + "allOf": [ + { + "anyOf": [ + { + "properties": { + "extension": { + "const": "dmg" + }, + "url": { + "pattern": "\\.dmg$" + } + } + }, + { + "properties": { + "extension": { + "const": "exe" + }, + "url": { + "pattern": "\\.exe$" + } + } + }, + { + "properties": { + "extension": { + "const": "tar.gz" + }, + "url": { + "pattern": "\\.tar\\.gz$" + } + } + }, + { + "properties": { + "extension": { + "const": "zip" + }, + "url": { + "pattern": "\\.zip$" + } + } + } + ] + }, + { + "anyOf": [ + { + "properties": { + "kind": { + "const": "installer" + }, + "extension": { + "const": "exe" + } + } + }, + { + "properties": { + "kind": { + "const": "archive" + }, + "extension": { + "enum": [ + "dmg", + "tar.gz", + "zip" + ] + } + } + } + ] + }, + { + "anyOf": [ + { + "properties": { + "os": { + "const": "mac" + }, + "triplet": { + "enum": [ + "x86_64-apple-darwin14", + "aarch64-apple-darwin14" + ] + } + } + }, + { + "properties": { + "os": { + "const": "winnt" + }, + "triplet": { + "enum": [ + "x86_64-w64-mingw32", + "i686-w64-mingw32" + ] + } + } + }, + { + "properties": { + "os": { + "const": "linux" + }, + "triplet": { + "enum": [ + "x86_64-linux-gnu", + "i686-linux-gnu", + "powerpc64le-linux-gnu", + "aarch64-linux-gnu", + "armv7l-linux-gnueabihf", + "x86_64-linux-musl" + ] + } + } + }, + { + "properties": { + "os": { + "const": "freebsd" + }, + "triplet": { + "const": "x86_64-unknown-freebsd11.1" + } + } + } + ] + }, + { + "anyOf": [ + { + "properties": { + "arch": { + "const": "x86_64" + }, + "triplet": { + "enum": [ + "x86_64-apple-darwin14", + "x86_64-w64-mingw32", + "x86_64-linux-gnu", + "x86_64-unknown-freebsd11.1", + "x86_64-linux-musl" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "i686" + }, + "triplet": { + "enum": [ + "i686-w64-mingw32", + "i686-linux-gnu" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "powerpc64le" + }, + "triplet": { + "const": "powerpc64le-linux-gnu" + } + } + }, + { + "properties": { + "arch": { + "const": "aarch64" + }, + "triplet": { + "enum": [ + "aarch64-linux-gnu", + "aarch64-apple-darwin14" + ] + } + } + }, + { + "properties": { + "arch": { + "const": "armv7l" + }, + "triplet": { + "const": "armv7l-linux-gnueabihf" + } + } + } + ] + } + ], "title": "File" }, "Arch": {