diff --git a/Earthfile b/Earthfile index 45acb573b..5c342f333 100644 --- a/Earthfile +++ b/Earthfile @@ -57,8 +57,4 @@ edit-docs: LOCALLY RUN ./earthly/docs/dev/local.py cat-ci-docs:latest - -# check-lint-openapi - OpenAPI linting from a given directory -check-lint-openapi: - FROM spectral-ci+spectral-base - DO spectral-ci+BUILD_SPECTRAL --dir="./examples/openapi" --file_type="json" \ No newline at end of file + \ No newline at end of file diff --git a/earthly/cddl/Earthfile b/earthly/cddl/Earthfile new file mode 100644 index 000000000..9628d3c0d --- /dev/null +++ b/earthly/cddl/Earthfile @@ -0,0 +1,8 @@ +VERSION 0.8 + +# cspell: words cddlc + +cddl-base: + FROM ruby:3.3.0-alpine + + RUN gem install cddlc \ No newline at end of file diff --git a/earthly/docs/Earthfile b/earthly/docs/Earthfile index 7f4018cf6..8cedfe96e 100644 --- a/earthly/docs/Earthfile +++ b/earthly/docs/Earthfile @@ -68,6 +68,21 @@ common: SAVE ARTIFACT /std +# The file we use for local-docs: +local-docs: + FROM scratch + + COPY --dir dev . + SAVE ARTIFACT /dev + +# SYNC_STD_CFG : Syncs the standard config files locally. +SYNC_LOCAL_DOCS: + FUNCTION + FROM scratch + COPY --dir +local-docs/dev /dev + + SAVE ARTIFACT /dev/local.py AS LOCAL local.py + # Common src setup SRC: FUNCTION diff --git a/earthly/flutter/Earthfile b/earthly/flutter/Earthfile index 6b18d86b3..2556bad7a 100644 --- a/earthly/flutter/Earthfile +++ b/earthly/flutter/Earthfile @@ -39,6 +39,9 @@ flutter-base: COPY +flutter-src/flutter /usr/local ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:$HOME/.pub-cache/bin:${PATH}" + # Flutter prints warnings when used by root user but omits them if has CI env flag found. + # script: https://github.com/flutter/flutter/blob/master/bin/internal/shared.sh#L214 + ENV CI="true" RUN flutter config --no-analytics RUN flutter --version RUN flutter doctor -v diff --git a/earthly/rust/scripts/std_checks.py b/earthly/rust/scripts/std_checks.py index 03068e20b..615142400 100755 --- a/earthly/rust/scripts/std_checks.py +++ b/earthly/rust/scripts/std_checks.py @@ -104,7 +104,7 @@ def main(): results.add(exec_manager.cli_run("cargo machete", name="Unused Dependencies Check")) # Check if we have any supply chain issues with dependencies. results.add( - exec_manager.cli_run("cargo deny check --exclude-dev -W vulnerability", name="Supply Chain Issues Check") + exec_manager.cli_run("cargo deny check --exclude-dev -W vulnerability -W unmaintained", name="Supply Chain Issues Check") ) results.print() diff --git a/earthly/rust/stdcfgs/deny.toml b/earthly/rust/stdcfgs/deny.toml index 77f0259f1..cb0005992 100644 --- a/earthly/rust/stdcfgs/deny.toml +++ b/earthly/rust/stdcfgs/deny.toml @@ -16,11 +16,7 @@ targets = [ [advisories] version = 2 -ignore = [ - { id = "RUSTSEC-2020-0168", reason = "`mach` is used by wasmtime and we have no control over that." }, - { id = "RUSTSEC-2021-0145", reason = "we don't target windows, and don't use a custom global allocator." }, - { id = "RUSTSEC-2024-0370", reason = "`proc-macro-error` is used by crates we rely on, we can't control what they use."}, -] +ignore = [] [bans] multiple-versions = "warn" @@ -58,6 +54,9 @@ allow-git = [ "https://github.com/input-output-hk/catalyst-mithril.git", "https://github.com/bytecodealliance/wasmtime", "https://github.com/aldanor/hdf5-rust", + "https://github.com/txpipe/vrf", + "https://github.com/txpipe/kes", + "https://github.com/txpipe/curve25519-dalek", ] [licenses] diff --git a/earthly/rust/stdcfgs/rustfmt.toml b/earthly/rust/stdcfgs/rustfmt.toml index b0f20832c..905bde2d0 100644 --- a/earthly/rust/stdcfgs/rustfmt.toml +++ b/earthly/rust/stdcfgs/rustfmt.toml @@ -36,7 +36,7 @@ max_width = 100 # Comments: normalize_comments = true -normalize_doc_attributes = true +normalize_doc_attributes = false wrap_comments = true comment_width = 90 # small excess is okay but prefer 80 format_code_in_doc_comments = true diff --git a/earthly/spectral/Earthfile b/earthly/spectral/Earthfile index 168468658..ed1a90f37 100644 --- a/earthly/spectral/Earthfile +++ b/earthly/spectral/Earthfile @@ -3,29 +3,20 @@ VERSION 0.8 # cspell: words ruleset spectral-base: - FROM stoplight/spectral + FROM stoplight/spectral:6.13.1 WORKDIR /work - COPY . . - RUN chmod +x ./minify-json.sh - SAVE ARTIFACT minify-json.sh -BUILD_SPECTRAL: +LINT: FUNCTION - - # Specify what file type to lint - ARG file_type = "json" + + # FIle type to be linted, default linting only JSON files + ARG file_type = json + # Directory to lint ARG dir = . - ARG src = . # Rule set for spectral - ARG rule_set=.spectral.yml - - COPY $src . - - COPY +spectral-base/minify-json.sh minify-json.sh - # If file type is json, minify the JSON - RUN ./minify-json.sh + ARG rule_set = .spectral.yml RUN spectral \ lint \ - $dir/"**/*.{yml,json}" \ - --ruleset $rule_set \ No newline at end of file + $dir/"**/*.$file_type" \ + --ruleset $rule_set diff --git a/earthly/spectral/minify-json.sh b/earthly/spectral/minify-json.sh deleted file mode 100644 index 7b2515334..000000000 --- a/earthly/spectral/minify-json.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# Minify all JSON in the directory if the file type is json -# Check if FILE_TYPE and DIR are not empty -if [[ -n "${file_type}" ]] && [[ -n "${dir}" ]]; then - # Minify all JSON in the directory if the file type is json - if [[ "${file_type}" == "json" ]]; then - # Loop through each JSON file in the directory - for json_file in "${dir}"/*.json; do - # Check if the file is a regular file - if [[ -f "${json_file}" ]]; then - # Minify the JSON file using jq and overwrite the original file - jq -c . "${json_file}" > "${json_file}.tmp" && mv "${json_file}.tmp" "${json_file}" - echo "Compacted: ${json_file}" - fi - done - else - echo "File type is not JSON." - fi -else - echo "FILE_TYPE or DIR is empty." -fi diff --git a/.spectral.yml b/examples/openapi/.spectral.yml similarity index 100% rename from .spectral.yml rename to examples/openapi/.spectral.yml diff --git a/examples/openapi/Earthfile b/examples/openapi/Earthfile new file mode 100644 index 000000000..39b63750b --- /dev/null +++ b/examples/openapi/Earthfile @@ -0,0 +1,8 @@ +VERSION 0.8 +IMPORT ../../earthly/spectral AS spectral-ci + +# check-lint-openapi - OpenAPI linting from a given directory +check-lint-openapi: + FROM spectral-ci+spectral-base + COPY . . + DO spectral-ci+LINT --dir=. --rule_set=.spectral.yml diff --git a/examples/openapi/example.json b/examples/openapi/example.json index 6c83323fd..d7fd27a8c 100644 --- a/examples/openapi/example.json +++ b/examples/openapi/example.json @@ -1,321 +1,317 @@ { - "openapi": "3.0.2", - "info": { - "title": "Example API", - "description": "This OpenAPI specification defines an example API with various endpoints for managing user data. It provides detailed information about the API, including contact information and version details.", - "version": "1.0", - "contact": { - "name": "Catalyst-ci", - "url": "https://www.example.com/support", - "email": "support@example.com" - } - }, - "servers": [ - { - "url": "https://api.example.com", - "description": "The primary server for this API, hosted at https://api.example.com. It serves as the main entry point for accessing the provided endpoints." - } - ], - "tags": [ - { - "name": "user", - "description": "Endpoints related to user management, including retrieving user lists and creating new users." - } - ], - "paths": { - "/users": { - "get": { - "tags": ["user"], - "operationId": "getUsers", - "summary": "Get a list of users", - "description": "Retrieves a list of users from the system.", - "responses": { - "200": { - "description": "Successfully retrieved user data. The response includes a list of users with pagination support.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "schema": { - "type": "array", - "maxItems": 1000, - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "400": { - "description": "Invalid request. Check the request payload.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "401": { - "description": "Unauthorized. The request requires user authentication.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "429": { - "description": "Rate limit exceeded. Too many requests within a specific time frame.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - }, - "Retry-After": { - "$ref": "#/components/headers/Retry-After" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "500": { - "description": "Internal server error. Contact system administrator if the issue persists.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - } - } - }, - "post": { - "tags": ["user"], - "operationId": "createUser", - "summary": "Create a new user", - "description": "Creates a new user with the provided information. Requires valid user data in the request payload.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "responses": { - "200": { - "description": "User created successfully. Returns the created user details.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "400": { - "description": "Invalid request. Check the request payload.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "401": { - "description": "Unauthorized. The request requires user authentication.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "429": { - "description": "Rate limit exceeded. Too many requests within a specific time frame.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - }, - "Retry-After": { - "$ref": "#/components/headers/Retry-After" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - }, - "500": { - "description": "Internal server error. Contact system administrator if the issue persists.", - "headers": { - "RateLimit-Limit": { - "$ref": "#/components/headers/RateLimit-Limit" - }, - "RateLimit-Reset": { - "$ref": "#/components/headers/RateLimit-Reset" - } - }, - "content": { - "application/json": { - "example": { - "message": "Invalid request payload" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "User": { - "description": "Represents a user in the system with details such as user ID, username, password, email, and roles.", - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "minimum": 0, - "maximum": 10000000 - }, - "username": { - "type": "string", - "format": "text", - "maxLength": 10 - }, - "password": { - "type": "string", - "format": "password", - "minLength": 8, - "maxLength": 50 - }, - "email": { - "type": "string", - "format": "email", - "maxLength": 20 - }, - "roles": { - "type": "string", - "enum": ["user", "admin"] - } - } - } - }, - "securitySchemes": { - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "X-API-Key" - } - }, - "headers": { - "RateLimit-Limit": { - "description": "Maximum number of requests allowed within a specific time frame.", - "schema": { - "type": "integer", - "format": "int32", - "minimum": 1, - "maximum": 1000 - } - }, - "RateLimit-Reset": { - "description": "Time in seconds until the rate limit resets.", - "schema": { - "type": "integer", - "format": "int32", - "minimum": 1, - "maximum": 1000 - } - }, - "Retry-After": { - "description": "Time in seconds the client should wait before making another request.", - "schema": { - "type": "integer", - "format": "int32", - "minimum": 1, - "maximum": 1000 - } - } - } - }, - "security": [ - { - "apiKey": ["your-api-key"] - } - ] + "openapi": "3.0.2", + "info": { + "title": "Example API", + "description": "This OpenAPI specification defines an example API with various endpoints for managing user data. It provides detailed information about the API, including contact information and version details.", + "version": "1.0", + "contact": { + "name": "Catalyst-ci", + "url": "https://www.example.com/support", + "email": "support@example.com" + } + }, + "servers": [ + { + "url": "https://api.example.com", + "description": "The primary server for this API, hosted at https://api.example.com. It serves as the main entry point for accessing the provided endpoints." + } + ], + "tags": [ + { + "name": "user", + "description": "Endpoints related to user management, including retrieving user lists and creating new users." + } + ], + "paths": { + "/users": { + "get": { + "tags": ["user"], + "operationId": "getUsers", + "summary": "Get a list of users", + "description": "Retrieves a list of users from the system.", + "responses": { + "200": { + "description": "Successfully retrieved user data. The response includes a list of users with pagination support.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "schema": { + "type": "object", + "maxItems": 1000, + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "400": { + "description": "Invalid request. Check the request payload.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + }, + "401": { + "description": "Unauthorized. The request requires user authentication.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + + } + }, + "429": { + "description": "Rate limit exceeded. Too many requests within a specific time frame.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + }, + "Retry-After": { + "$ref": "#/components/headers/Retry-After" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + }, + "500": { + "description": "Internal server error. Contact system administrator if the issue persists.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + } + } + }, + "post": { + "tags": ["user"], + "operationId": "createUser", + "summary": "Create a new user", + "description": "Creates a new user with the provided information. Requires valid user data in the request payload.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "responses": { + "200": { + "description": "User created successfully. Returns the created user details.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "400": { + "description": "Invalid request. Check the request payload.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + }, + "401": { + "description": "Unauthorized. The request requires user authentication.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + }, + "429": { + "description": "Rate limit exceeded. Too many requests within a specific time frame.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + }, + "Retry-After": { + "$ref": "#/components/headers/Retry-After" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + }, + "500": { + "description": "Internal server error. Contact system administrator if the issue persists.", + "headers": { + "RateLimit-Limit": { + "$ref": "#/components/headers/RateLimit-Limit" + }, + "RateLimit-Reset": { + "$ref": "#/components/headers/RateLimit-Reset" + } + }, + "content": { + "application/json": { + "example": { + "message": "Invalid request payload" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "description": "Represents a user in the system with details such as user ID, username, password, email, and roles.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 10000000 + }, + "username": { + "type": "string", + "format": "text", + "maxLength": 10 + }, + "password": { + "type": "string", + "format": "password", + "minLength": 8, + "maxLength": 50 + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 20 + }, + "roles": { + "type": "string", + "enum": ["user", "admin"] + } + } + } + }, + "securitySchemes": { + "apiKey": { + "type": "apiKey", + "in": "header", + "name": "X-API-Key" + } + }, + "headers": { + "RateLimit-Limit": { + "description": "Maximum number of requests allowed within a specific time frame.", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 1, + "maximum": 1000 + } + }, + "RateLimit-Reset": { + "description": "Time in seconds until the rate limit resets.", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 1, + "maximum": 1000 + } + }, + "Retry-After": { + "description": "Time in seconds the client should wait before making another request.", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 1, + "maximum": 1000 + } + } + } + }, + "security": [ + { + "apiKey": ["your-api-key"] + } + ] } diff --git a/examples/rust/deny.toml b/examples/rust/deny.toml index 77f0259f1..cb0005992 100644 --- a/examples/rust/deny.toml +++ b/examples/rust/deny.toml @@ -16,11 +16,7 @@ targets = [ [advisories] version = 2 -ignore = [ - { id = "RUSTSEC-2020-0168", reason = "`mach` is used by wasmtime and we have no control over that." }, - { id = "RUSTSEC-2021-0145", reason = "we don't target windows, and don't use a custom global allocator." }, - { id = "RUSTSEC-2024-0370", reason = "`proc-macro-error` is used by crates we rely on, we can't control what they use."}, -] +ignore = [] [bans] multiple-versions = "warn" @@ -58,6 +54,9 @@ allow-git = [ "https://github.com/input-output-hk/catalyst-mithril.git", "https://github.com/bytecodealliance/wasmtime", "https://github.com/aldanor/hdf5-rust", + "https://github.com/txpipe/vrf", + "https://github.com/txpipe/kes", + "https://github.com/txpipe/curve25519-dalek", ] [licenses] diff --git a/examples/rust/rustfmt.toml b/examples/rust/rustfmt.toml index b0f20832c..905bde2d0 100644 --- a/examples/rust/rustfmt.toml +++ b/examples/rust/rustfmt.toml @@ -36,7 +36,7 @@ max_width = 100 # Comments: normalize_comments = true -normalize_doc_attributes = true +normalize_doc_attributes = false wrap_comments = true comment_width = 90 # small excess is okay but prefer 80 format_code_in_doc_comments = true