mirror of
https://github.com/adidas/api-guidelines.git
synced 2025-10-25 15:19:19 +00:00
Merge pull request #85 from adidas/feature/update-spectral-ruleset
Feature/update spectral ruleset
This commit is contained in:
BIN
.gitbook/assets/adidas_company_logo_BWp.png
Normal file
BIN
.gitbook/assets/adidas_company_logo_BWp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
BIN
.gitbook/assets/adidas_company_logo_BWr.png
Normal file
BIN
.gitbook/assets/adidas_company_logo_BWr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
591
.spectral.yml
591
.spectral.yml
@@ -1,316 +1,275 @@
|
||||
extends: ["spectral:oas"]
|
||||
rules:
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# General OAS rules
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
operation-operationId: false
|
||||
operation-tags: false
|
||||
operation-2xx-response: error
|
||||
|
||||
adidas-paths-kebab-case:
|
||||
description: All YAML/JSON paths MUST follow kebab-case
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} is not kebab-case: {{error}}"
|
||||
given: $.paths[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces
|
||||
|
||||
adidas-path-parameters-camelCase-alphanumeric:
|
||||
description: Path parameters MUST follow camelCase
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} path parameter is not camelCase: {{error}}"
|
||||
given: $..parameters[?(@.in == 'path')].name
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^[a-z][a-zA-Z0-9]+$"
|
||||
|
||||
adidas-definitions-camelCase-alphanumeric:
|
||||
description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-properties-camelCase-alphanumeric:
|
||||
description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions..properties[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-request-GET-no-body:
|
||||
description: "A 'GET' request MUST NOT accept a 'body` parameter"
|
||||
severity: error
|
||||
given: $.paths..get.parameters..in
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^body$/"
|
||||
|
||||
adidas-headers-no-x-headers:
|
||||
description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)."
|
||||
severity: warn
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "HTTP headers SHOULD NOT include 'X-' prefix."
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^(x|X)-/"
|
||||
|
||||
adidas-headers-hyphenated-pascal-case:
|
||||
description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation
|
||||
severity: error
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation"
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Only OAS2 rules
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
adidas-oas2-protocol-https-only:
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas2
|
||||
recommended: true
|
||||
severity: error
|
||||
type: "style"
|
||||
message: "Schemes MUST be https and no other value is allowed."
|
||||
given: $
|
||||
then:
|
||||
field: schemes
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: ["https"]
|
||||
maxItems: 1
|
||||
|
||||
adidas-oas2-request-support-json:
|
||||
description: Every request SHOULD support `application/json` media type
|
||||
formats:
|
||||
- oas2
|
||||
severity: warn
|
||||
message: "{{description}}: {{error}}"
|
||||
recommended: true
|
||||
given: "$..consumes"
|
||||
then:
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
contains:
|
||||
type: string
|
||||
enum:
|
||||
- application/json
|
||||
|
||||
adidas-oas2-example-exists-in-parameters:
|
||||
description: All models MUST have a valid example.
|
||||
severity: error
|
||||
recommended: true
|
||||
formats:
|
||||
- oas2
|
||||
message: "{{ property }} MUST have a valid example."
|
||||
given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]"
|
||||
then:
|
||||
function: truthy
|
||||
|
||||
# example-exists-in-definitions:
|
||||
# description: All models MUST have a valid example.
|
||||
# severity: error
|
||||
# recommended: true
|
||||
# formats:
|
||||
# - oas2
|
||||
# message: "{{ property }} MUST have a valid example."
|
||||
# given: "$..definitions..[?(!@.example || !@..$ref)]"
|
||||
# then:
|
||||
# function: falsy
|
||||
# "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example && ( @.type || @.format || @.$ref ))]"
|
||||
|
||||
adidas-oas2-response-success-hal: # schemes and/or produces
|
||||
description: "All success responses MUST be of media type `application/hal+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas2
|
||||
message: "Response documents MUST follow application/hal+json: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
adidas-oas2-response-error-problem: # schemas and/or produces
|
||||
description: All error responses MUST be of media type `application/problem+json`
|
||||
severity: error
|
||||
formats:
|
||||
- oas2
|
||||
given: $.paths..responses[?( @property >= 400 && @property < 600 )]
|
||||
recommended: true
|
||||
type: "style"
|
||||
message: "Error response document MUST follow application/problem+json: {{error}}"
|
||||
then:
|
||||
field: schema.example
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/ProblemDetail.yaml"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Only OAS3 rules
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
adidas-oas3-request-support-json:
|
||||
description: Every request MUST support `application/json` media type
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "{{description}}: {{error}}"
|
||||
given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
|
||||
then:
|
||||
function: falsy
|
||||
|
||||
adidas-oas3-valid-example-in-parameters:
|
||||
description: Examples must be valid against their defined schema.
|
||||
message: "{{error}}"
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
severity: 0
|
||||
type: validation
|
||||
given: "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example
|
||||
&& ( @.type || @.format || @.$ref ))]"
|
||||
then:
|
||||
function: schemaPath
|
||||
functionOptions:
|
||||
field: example
|
||||
schemaPath: "$"
|
||||
|
||||
adidas-oas3-valid-example-in-definitions:
|
||||
description: Examples must be valid against their defined schema.
|
||||
message: "{{error}}"
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
severity: 0
|
||||
type: validation
|
||||
given: "$..definitions..[?(@property !== 'properties' && @.example && (@.type ||
|
||||
@.format || @.$ref))]"
|
||||
then:
|
||||
function: schemaPath
|
||||
functionOptions:
|
||||
field: example
|
||||
schemaPath: "$"
|
||||
|
||||
adidas-oas3-protocol-https-only: # checks how does the servers array values start
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "Servers MUST be https and no other protocol is allowed."
|
||||
given: $.servers..url
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^https:/"
|
||||
|
||||
adidas-oas3-response-success-hal:
|
||||
description: "All success responses MUST be of media type `application/hal+json` "
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~
|
||||
recommended: true
|
||||
# type: "style"
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
|
||||
# sync and async patterns that can return hal OR problem+json
|
||||
adidas-oas3-response-success-OK:
|
||||
description: "All success responses MUST be of media type `application/hal+json` or `application/problem+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 )].content[*]~
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json or application/problem+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
- application/problem+json
|
||||
|
||||
adidas-oas3-response-success-hal-body: # schemes and/or produces
|
||||
description: "All success responses MUST follow `application/hal+json` schema"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST follow application/hal+json schema: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Not implemented
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Other rules which are redundant or not feasible
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# fields-date-iso8601:
|
||||
# description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html)
|
||||
# severity: error
|
||||
# fields-language-iso639:
|
||||
# description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html)
|
||||
# severity: error
|
||||
# fields-country-iso3166:
|
||||
# description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
|
||||
# severity: error
|
||||
# fields-currency-iso4217:
|
||||
# description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217)
|
||||
# severity: error
|
||||
# response-303-async-link-header:
|
||||
# description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header
|
||||
# severity: hint
|
||||
extends: [[spectral:oas, all], [spectral:asyncapi, all]]
|
||||
documentationUrl: https://github.com/adidas/api-guidelines/blob/master/ruleset.md
|
||||
rules:
|
||||
operation-tags: off
|
||||
operation-operationId: off
|
||||
operation-success-response: error
|
||||
|
||||
# ----------------------------#
|
||||
# Adidas OAS v2.0, v3.0 rules #
|
||||
# ----------------------------#
|
||||
|
||||
adidas-paths-kebab-case:
|
||||
description: All YAML/JSON paths MUST follow kebab-case
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} is not kebab-case: {{error}}"
|
||||
given: $.paths[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces
|
||||
|
||||
adidas-path-parameters-camelCase-alphanumeric:
|
||||
description: Path parameters MUST follow camelCase
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} path parameter is not camelCase: {{error}}"
|
||||
given: $..parameters[?(@.in == 'path')].name
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^[a-z][a-zA-Z0-9]+$"
|
||||
|
||||
adidas-definitions-camelCase-alphanumeric:
|
||||
description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-properties-camelCase-alphanumeric:
|
||||
description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions..properties[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-request-GET-no-body:
|
||||
description: "A 'GET' request MUST NOT accept a 'body` parameter"
|
||||
severity: error
|
||||
given: $.paths..get.parameters..in
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^body$/"
|
||||
|
||||
adidas-headers-no-x-headers:
|
||||
description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)."
|
||||
severity: warn
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "HTTP headers SHOULD NOT include 'X-' prefix."
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^(x|X)-/"
|
||||
|
||||
adidas-headers-hyphenated-pascal-case:
|
||||
description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation
|
||||
severity: error
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation"
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/"
|
||||
|
||||
# ----------------------#
|
||||
# Adidas OAS v2.0 rules #
|
||||
# ----------------------#
|
||||
|
||||
adidas-oas2-protocol-https-only:
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas2
|
||||
recommended: true
|
||||
severity: error
|
||||
type: "style"
|
||||
message: "Schemes MUST be https and no other value is allowed."
|
||||
given: $
|
||||
then:
|
||||
field: schemes
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: ["https"]
|
||||
maxItems: 1
|
||||
|
||||
adidas-oas2-request-support-json:
|
||||
description: Every request SHOULD support `application/json` media type
|
||||
formats:
|
||||
- oas2
|
||||
severity: warn
|
||||
message: "{{description}}: {{error}}"
|
||||
recommended: true
|
||||
given: "$..consumes"
|
||||
then:
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
contains:
|
||||
type: string
|
||||
enum:
|
||||
- application/json
|
||||
|
||||
adidas-oas2-example-exists-in-parameters:
|
||||
description: All models MUST have a valid example.
|
||||
severity: error
|
||||
recommended: true
|
||||
formats:
|
||||
- oas2
|
||||
message: "{{ property }} MUST have a valid example."
|
||||
given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]"
|
||||
then:
|
||||
function: truthy
|
||||
|
||||
# example-exists-in-definitions covery by oas2-valid-media-example
|
||||
|
||||
adidas-oas2-response-success-hal: # schemes and/or produces
|
||||
description: "All success responses MUST be of media type `application/hal+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas2
|
||||
message: "Response documents MUST follow application/hal+json: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
adidas-oas2-response-error-problem: # schemas and/or produces
|
||||
description: All error responses MUST be of media type `application/problem+json`
|
||||
severity: error
|
||||
formats:
|
||||
- oas2
|
||||
given: $.paths..responses[?( @property >= 400 && @property < 600 )]
|
||||
recommended: true
|
||||
type: "style"
|
||||
message: "Error response document MUST follow application/problem+json: {{error}}"
|
||||
then:
|
||||
field: schema.example
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/ProblemDetail.yaml"
|
||||
|
||||
# ----------------------#
|
||||
# Adidas OAS v3.0 rules #
|
||||
# ----------------------#
|
||||
|
||||
adidas-oas3-request-support-json:
|
||||
description: Every request MUST support `application/json` media type
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "{{description}}: {{error}}"
|
||||
given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
|
||||
then:
|
||||
function: falsy
|
||||
|
||||
# adidas-oas3-valid-example-in-parameters && adidas-oas3-valid-example-in-definitions covered by oas3-valid-media-example
|
||||
|
||||
adidas-oas3-protocol-https-only:
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "Servers MUST be https and no other protocol is allowed."
|
||||
given: $.servers..url
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^https:/"
|
||||
|
||||
adidas-oas3-response-success-hal:
|
||||
description: "All success responses MUST be of media type `application/hal+json` "
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
|
||||
# sync and async patterns that can return hal OR problem+json
|
||||
adidas-oas3-response-success-OK:
|
||||
description: "All success responses MUST be of media type `application/hal+json` or `application/problem+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 )].content[*]~
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json or application/problem+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
- application/problem+json
|
||||
|
||||
adidas-oas3-response-success-hal-body: # schemes and/or produces
|
||||
description: "All success responses MUST follow `application/hal+json` schema"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST follow application/hal+json schema: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Not implemented
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Other rules which are redundant or not feasible
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# fields-date-iso8601:
|
||||
# description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html)
|
||||
# severity: error
|
||||
# fields-language-iso639:
|
||||
# description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html)
|
||||
# severity: error
|
||||
# fields-country-iso3166:
|
||||
# description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
|
||||
# severity: error
|
||||
# fields-currency-iso4217:
|
||||
# description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217)
|
||||
# severity: error
|
||||
# response-303-async-link-header:
|
||||
# description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header
|
||||
# severity: hint
|
||||
|
||||
54
README.md
54
README.md
@@ -1,6 +1,8 @@
|
||||
# adidas API Guidelines
|
||||
|
||||

|
||||
|
||||
|
||||
<figure><picture><source srcset=".gitbook/assets/adidas_company_logo_BWr.png" media="(prefers-color-scheme: dark)"><img src=".gitbook/assets/adidas_company_logo_BWp.png" alt=""></picture><figcaption></figcaption></figure>
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
@@ -8,7 +10,7 @@
|
||||
|
||||
### Motivation
|
||||
|
||||
The goal of this document is to facilitate the work and minimize the effort of all API users at adidas while protecting their investment and encouraging API adoption.
|
||||
The goal of this document is to facilitate the work and minimize the effort of all API users at adidas while protecting their investment and encouraging API First adoption.
|
||||
|
||||
These guidelines lay down the foundation for collaboration, stability, and extensibility.
|
||||
|
||||
@@ -19,13 +21,15 @@ The API Guidelines are split into two main parts:
|
||||
* [General Guidelines](general-guidelines/general-guidelines.md)
|
||||
* API type-specific Guidelines
|
||||
* [REST APIs Guidelines](rest-api-guidelines/rest.md)
|
||||
* [Asynchronous APIs Guidelines](asynchronous-api-guidelines/index.md)
|
||||
* [Asynchronous APIs Guidelines](https://github.com/cesareomacias/api-guidelines/blob/master/asynchronous-api-guidelines/index.md)
|
||||
|
||||
The general guidelines section discusses the core principles relevant to any kind of API. The API type-specific section further defines the guidelines specific to a given architectural style or API technique (such as REST, Kafka or GraphQL APIs).
|
||||
The general guidelines section discusses the core principles relevant to any kind of API. 
|
||||
|
||||
The API type-specific section further defines the guidelines specific to a given architectural style or API technique (such as REST, Kafka or GraphQL APIs).
|
||||
|
||||
### How to read the Guidelines
|
||||
|
||||
These Guidelines are available for online reading at [GitBook](https://adidas.gitbook.io/api-guidelines/). The source code can be found on [GitHub](https://github.com/adidas/api-guidelines).
|
||||
These guidelines are available for online reading at [GitBook](https://adidas.gitbook.io/api-guidelines/). The source code can be found on [GitHub](https://github.com/adidas/api-guidelines).
|
||||
|
||||
The CAPITALIZED words throughout these guidelines have a special meaning:
|
||||
|
||||
@@ -35,41 +39,47 @@ The CAPITALIZED words throughout these guidelines have a special meaning:
|
||||
> this document are to be interpreted as described in RFC2119.
|
||||
> ```
|
||||
|
||||
Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details.
|
||||
Refer to [RFC2119](https://www.rfc-editor.org/rfc/rfc2119) for details.
|
||||
|
||||
### Validating your API Guidelines against OpenAPI Specification
|
||||
|
||||
In the `ruleset.md` file you can find a digest of API Guidelines rules which you can use to validate your API description documents. If you are using OpenAPI Specification as the API description format you can also leverage the `.spectral.yaml` ruleset to automatically verify your specification compliance using [Spectral](github.com/stoplightio/spectral/).
|
||||
In the `ruleset.md` file you can find a digest of API Guidelines rules which you can use to validate your API description documents.
|
||||
|
||||
To install Spectral you will need Node.js and a package manager (npm or yarn).
|
||||
If you are using OpenAPI or AsyncAPI specification as API description format, you can also leverage the `adidas-spectral.yaml` ruleset to automatically lint your specification compliance using [Spectral](https://meta.stoplight.io/docs/spectral/674b27b261c3c-overview).
|
||||
|
||||
Note: The version used with the spectral specifications was 5.3.0
|
||||
> To install Spectral, you will need Node.js and a package manager (npm or yarn).
|
||||
|
||||
```
|
||||
npm install -g @stoplight/spectral@5.3.0
|
||||
```bash
|
||||
npm install -g @stoplight/spectral-cli
|
||||
|
||||
# OR
|
||||
|
||||
yarn global add @stoplight/spectral@5.3.0
|
||||
yarn global add @stoplight/spectral-cli
|
||||
```
|
||||
|
||||
Once installed, to verify your OAS file with spectral execute `spectral lint <oas-file> -r <adidas-api-guidelines-folder>/.spectral.yaml` where `<adidas-api-guidelines-folder>/.spectral.yaml` indicated the location `.spectral.yaml` file.
|
||||
Once installed, to verify your _oas_ or _async_ file with spectral execute:
|
||||
|
||||
For further documentation on Spectral refer to their [documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/README.md).
|
||||
```bash
|
||||
spectral lint <api-specification-file> --ruleset adidas-spectral.yaml
|
||||
```
|
||||
|
||||
### Questions & Comments
|
||||
### Contact Us
|
||||
|
||||
_Please contact_ [_jesusjavier.dediego@adidas.com_](mailto:jesusjavier.dediego@adidas.com) _in case of questions._
|
||||
In case you have any questions or comments, please utilize the appropriate GitHub collaboration tools, such as issues, pull requests, and discussions.
|
||||
|
||||
If you want to contact adidas API Team regarding these guidelines, you can mail us at
|
||||
|
||||
 _**api-team@adidas.com**_
|
||||
|
||||
## Intended Use Cases
|
||||
|
||||
This project is intended to provide the guidelines for design & development of APIs at adidas.
|
||||
|
||||
adidas is not responsible for the usage of this software for different purposes that the ones described in the use cases.
|
||||
Adidas is not responsible for the usage of this software for different purposes that the ones described in the use cases.
|
||||
|
||||
## Last Review
|
||||
|
||||
May 2024
|
||||
February 2025
|
||||
|
||||
## License and Software Information
|
||||
|
||||
@@ -77,12 +87,6 @@ May 2024
|
||||
|
||||
adidas AG publishes this software and accompanied documentation (if any) subject to the terms of the MIT license with the aim of helping the community with our tools and libraries which we think can be also useful for other people. You will find a copy of the MIT license in the root folder of this package. All rights not explicitly granted to you under the MIT license remain the sole and exclusive property of adidas AG.
|
||||
|
||||
NOTICE: The software has been designed solely for the purpose of providing API design and development guidelines. The software is NOT designed, tested or verified for productive use whatsoever, nor or for any use related to high risk environments, such as health care, highly or fully autonomous driving, power plants, or other critical infrastructures or services.
|
||||
|
||||
If you want to contact adidas regarding the software, you can mail us at _software.engineering@adidas.com_.
|
||||
NOTICE: The software has been designed solely for the purpose of providing API design and development guidelines. The software is NOT designed, tested or verified for productive use whatsoever, nor or for any use related to high-risk environments, such as health care, highly or fully autonomous driving, power plants, or other critical infrastructures or services.
|
||||
|
||||
For further information open the [adidas terms and conditions](https://github.com/adidas/adidas-contribution-guidelines/wiki/Terms-and-conditions) page.
|
||||
|
||||
### License
|
||||
|
||||
[MIT](https://github.com/adidas/api-guidelines/blob/master/LICENSE)
|
||||
|
||||
275
adidas-spectral.yaml
Normal file
275
adidas-spectral.yaml
Normal file
@@ -0,0 +1,275 @@
|
||||
extends: [[spectral:oas, all], [spectral:asyncapi, all]]
|
||||
documentationUrl: https://github.com/adidas/api-guidelines/blob/master/ruleset.md
|
||||
rules:
|
||||
operation-tags: off
|
||||
operation-operationId: off
|
||||
operation-success-response: error
|
||||
|
||||
# ----------------------------#
|
||||
# Adidas OAS v2.0, v3.0 rules #
|
||||
# ----------------------------#
|
||||
|
||||
adidas-paths-kebab-case:
|
||||
description: All YAML/JSON paths MUST follow kebab-case
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} is not kebab-case: {{error}}"
|
||||
given: $.paths[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces
|
||||
|
||||
adidas-path-parameters-camelCase-alphanumeric:
|
||||
description: Path parameters MUST follow camelCase
|
||||
severity: warn
|
||||
recommended: true
|
||||
message: "{{property}} path parameter is not camelCase: {{error}}"
|
||||
given: $..parameters[?(@.in == 'path')].name
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "^[a-z][a-zA-Z0-9]+$"
|
||||
|
||||
adidas-definitions-camelCase-alphanumeric:
|
||||
description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-properties-camelCase-alphanumeric:
|
||||
description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
|
||||
severity: error
|
||||
recommended: true
|
||||
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
|
||||
given: $.definitions..properties[*]~
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^[a-z$_]{1}[A-Z09$_]*/"
|
||||
|
||||
adidas-request-GET-no-body:
|
||||
description: "A 'GET' request MUST NOT accept a 'body` parameter"
|
||||
severity: error
|
||||
given: $.paths..get.parameters..in
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^body$/"
|
||||
|
||||
adidas-headers-no-x-headers:
|
||||
description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)."
|
||||
severity: warn
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "HTTP headers SHOULD NOT include 'X-' prefix."
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
notMatch: "/^(x|X)-/"
|
||||
|
||||
adidas-headers-hyphenated-pascal-case:
|
||||
description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation
|
||||
severity: error
|
||||
given: "$..parameters[?(@.in == 'header')].name"
|
||||
message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation"
|
||||
recommended: true
|
||||
type: style
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/"
|
||||
|
||||
# ----------------------#
|
||||
# Adidas OAS v2.0 rules #
|
||||
# ----------------------#
|
||||
|
||||
adidas-oas2-protocol-https-only:
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas2
|
||||
recommended: true
|
||||
severity: error
|
||||
type: "style"
|
||||
message: "Schemes MUST be https and no other value is allowed."
|
||||
given: $
|
||||
then:
|
||||
field: schemes
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: ["https"]
|
||||
maxItems: 1
|
||||
|
||||
adidas-oas2-request-support-json:
|
||||
description: Every request SHOULD support `application/json` media type
|
||||
formats:
|
||||
- oas2
|
||||
severity: warn
|
||||
message: "{{description}}: {{error}}"
|
||||
recommended: true
|
||||
given: "$..consumes"
|
||||
then:
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
type: array
|
||||
contains:
|
||||
type: string
|
||||
enum:
|
||||
- application/json
|
||||
|
||||
adidas-oas2-example-exists-in-parameters:
|
||||
description: All models MUST have a valid example.
|
||||
severity: error
|
||||
recommended: true
|
||||
formats:
|
||||
- oas2
|
||||
message: "{{ property }} MUST have a valid example."
|
||||
given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]"
|
||||
then:
|
||||
function: truthy
|
||||
|
||||
# example-exists-in-definitions covery by oas2-valid-media-example
|
||||
|
||||
adidas-oas2-response-success-hal: # schemes and/or produces
|
||||
description: "All success responses MUST be of media type `application/hal+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas2
|
||||
message: "Response documents MUST follow application/hal+json: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
adidas-oas2-response-error-problem: # schemas and/or produces
|
||||
description: All error responses MUST be of media type `application/problem+json`
|
||||
severity: error
|
||||
formats:
|
||||
- oas2
|
||||
given: $.paths..responses[?( @property >= 400 && @property < 600 )]
|
||||
recommended: true
|
||||
type: "style"
|
||||
message: "Error response document MUST follow application/problem+json: {{error}}"
|
||||
then:
|
||||
field: schema.example
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/ProblemDetail.yaml"
|
||||
|
||||
# ----------------------#
|
||||
# Adidas OAS v3.0 rules #
|
||||
# ----------------------#
|
||||
|
||||
adidas-oas3-request-support-json:
|
||||
description: Every request MUST support `application/json` media type
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "{{description}}: {{error}}"
|
||||
given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
|
||||
then:
|
||||
function: falsy
|
||||
|
||||
# adidas-oas3-valid-example-in-parameters && adidas-oas3-valid-example-in-definitions covered by oas3-valid-media-example
|
||||
|
||||
adidas-oas3-protocol-https-only:
|
||||
description: "ALL requests MUST go through `https` protocol only"
|
||||
formats:
|
||||
- oas3
|
||||
recommended: true
|
||||
severity: error
|
||||
message: "Servers MUST be https and no other protocol is allowed."
|
||||
given: $.servers..url
|
||||
then:
|
||||
function: pattern
|
||||
functionOptions:
|
||||
match: "/^https:/"
|
||||
|
||||
adidas-oas3-response-success-hal:
|
||||
description: "All success responses MUST be of media type `application/hal+json` "
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
|
||||
# sync and async patterns that can return hal OR problem+json
|
||||
adidas-oas3-response-success-OK:
|
||||
description: "All success responses MUST be of media type `application/hal+json` or `application/problem+json`"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 )].content[*]~
|
||||
recommended: true
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST be of application/hal+json or application/problem+json media types: {{error}}"
|
||||
then:
|
||||
function: enumeration
|
||||
functionOptions:
|
||||
values:
|
||||
- application/hal+json
|
||||
- application/problem+json
|
||||
|
||||
adidas-oas3-response-success-hal-body: # schemes and/or produces
|
||||
description: "All success responses MUST follow `application/hal+json` schema"
|
||||
severity: error
|
||||
given: $.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]
|
||||
recommended: true
|
||||
type: "style"
|
||||
formats:
|
||||
- oas3
|
||||
message: "Response documents MUST follow application/hal+json schema: {{error}}"
|
||||
then:
|
||||
field: schema
|
||||
function: schema
|
||||
functionOptions:
|
||||
schema:
|
||||
$ref: "./supermodel/adidas/api/HAL.yaml"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Not implemented
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Other rules which are redundant or not feasible
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# fields-date-iso8601:
|
||||
# description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html)
|
||||
# severity: error
|
||||
# fields-language-iso639:
|
||||
# description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html)
|
||||
# severity: error
|
||||
# fields-country-iso3166:
|
||||
# description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
|
||||
# severity: error
|
||||
# fields-currency-iso4217:
|
||||
# description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217)
|
||||
# severity: error
|
||||
# response-303-async-link-header:
|
||||
# description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header
|
||||
# severity: hint
|
||||
BIN
adidaslogo.jpg
BIN
adidaslogo.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -50,10 +50,9 @@ Spectral can also be used from within JavaScript. For details on how to accompli
|
||||
|
||||
## Validating with Adidas API Guidelines
|
||||
|
||||
To check whether your API Specification complies with Adidas API Guidelines you will need the `.spectral.yaml` file from this repository ([here](https://github.com/adidas/api-guidelines/blob/master/.spectral.yml)).
|
||||
|
||||
To check whether your API Specification complies with Adidas API Guidelines you will need the `adidas-spectral.yaml` file from this repository ([here](https://github.com/adidas/api-guidelines/blob/master/adidas-spectral.yaml)).
|
||||
```
|
||||
spectral lint <oas-file> -r <adidas-api-guidelines-folder>/.spectral.yaml
|
||||
spectral lint <oas-file> --ruleset adidas-spectral.yaml
|
||||
```
|
||||
|
||||
### Validation problems
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "api-guidelines",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"description": "adidas API guidelines",
|
||||
"repository": "git@github.com:adidas/api-guidelines.git",
|
||||
"author": "software.engineering@adidas.com",
|
||||
"repository": "https://github.com/adidas/api-guidelines",
|
||||
"author": "api-team@adidas.com",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@stoplight/spectral": "^5.3.0",
|
||||
"@stoplight/spectral": "^6.13.1",
|
||||
"@supermodel/cli": "^0.46.29"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
# API Testing CI Environment
|
||||
|
||||
This guide describes steps necessary for testing an API described in a swagger file with the [Dredd API Testing Framework](https://github.com/apiaryio/dredd) in a CI Environment \(Jenkins, TeamCity\).
|
||||
This guide describes steps necessary for testing an API described in a swagger file with the [Dredd API Testing Framework](https://github.com/apiaryio/dredd) in a CI Environment (Jenkins, TeamCity).
|
||||
|
||||
## Environment Prerequisites
|
||||
|
||||
The following must be available in the CI environment before testing:
|
||||
|
||||
1. **Node.js** runtime MUST be available in the CI environment:
|
||||
1. **Node.js** runtime MUST be available in the CI environment:
|
||||
|
||||
```text
|
||||
$ node -v
|
||||
v14.15.5
|
||||
```
|
||||
```
|
||||
$ node -v
|
||||
v14.15.5
|
||||
```
|
||||
2. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment:
|
||||
|
||||
3. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment:
|
||||
```
|
||||
$ npm install -g dredd --no-optional
|
||||
```
|
||||
|
||||
```text
|
||||
$ npm install -g dredd --no-optional
|
||||
```
|
||||
|
||||
```text
|
||||
$ dredd --version
|
||||
dredd v14.0.0
|
||||
```
|
||||
```
|
||||
$ dredd --version
|
||||
dredd v14.0.0
|
||||
```
|
||||
|
||||
## Testing an API
|
||||
|
||||
@@ -30,23 +29,22 @@ The following must be available in the CI environment before testing:
|
||||
|
||||
To test an API within the CI environment provisioned as mentioned in the environment prerequisites, you will need the following:
|
||||
|
||||
1. A `swagger.yaml` file with the description of API being tested
|
||||
1. A `swagger.yaml` file with the description of API being tested
|
||||
|
||||
The OpenAPI Specifciation file should be fetched from [API Design Platform](design-plaform.md). In the case of SwaggerHub API Design Platform, the file can be fetched manually or via their API. Refer to [Integrating with the SwaggerHub API](https://swagger.io/blog/api-development/integrating-with-the-swaggerhub-api/), for details how to use SwaggerHub API.
|
||||
The OpenAPI Specifciation file should be fetched from [API Design Platform](https://github.com/cesareomacias/api-guidelines/blob/master/rest-api-guidelines/guides/design-plaform.md). In the case of SwaggerHub API Design Platform, the file can be fetched manually or via their API. Refer to [Integrating with the SwaggerHub API](https://swagger.io/blog/api-development/integrating-with-the-swaggerhub-api/), for details how to use SwaggerHub API.
|
||||
|
||||
Alternativelly this can also be a remote file e.g. SwaggerHub URL, if the API is public its OAS file and reachable from the testing host.
|
||||
Alternativelly this can also be a remote file e.g. SwaggerHub URL, if the API is public its OAS file and reachable from the testing host.
|
||||
2. The host (address) of the service being tested
|
||||
|
||||
2. The host \(address\) of the service being tested
|
||||
|
||||
```text
|
||||
$ export API_HOST=http://deheremap7336.emea.adsint.biz:8004`
|
||||
```
|
||||
```
|
||||
$ export API_HOST=http://deheremap7336.emea.adsint.biz:8004`
|
||||
```
|
||||
|
||||
### Running the Test
|
||||
|
||||
Run:
|
||||
|
||||
```text
|
||||
```
|
||||
$ dredd swagger.yaml $API_HOST
|
||||
```
|
||||
|
||||
@@ -54,8 +52,8 @@ $ dredd swagger.yaml $API_HOST
|
||||
|
||||
The Dredd will perform the tests and exits usually if the tests have passed. You can check the test result as with any other Unix tools with:
|
||||
|
||||
```text
|
||||
```
|
||||
$ echo $?
|
||||
```
|
||||
|
||||
Everything else but `0` should break the build. The test results will be visible in the CLI \(log\)
|
||||
Everything else but `0` should break the build. The test results will be visible in the CLI (log)
|
||||
|
||||
Reference in New Issue
Block a user