diff --git a/artifacts/linting_rules/.github/workflows/megalinter.yml b/artifacts/linting_rules/.github/workflows/megalinter.yml
new file mode 100644
index 00000000..6bda7009
--- /dev/null
+++ b/artifacts/linting_rules/.github/workflows/megalinter.yml
@@ -0,0 +1,78 @@
+---
+# MegaLinter GitHub Action configuration file
+# More info at https://megalinter.io
+# CAMARA Project - Github Action for Pull Reqests
+# 31.01.2024 - initial version
+
+name: MegaLinter
+
+on: # yamllint disable-line rule:truthy
+ # Pull Requests to main
+ pull_request:
+ branches: [master, main]
+
+env: # Comment env block if you do not want to apply fixes
+ # Apply linter fixes configuration
+ APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool)
+ APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all)
+ APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request)
+
+concurrency:
+ group: ${{ github.ref }}-${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: MegaLinter
+ runs-on: ubuntu-latest
+ permissions:
+ # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR
+ # Remove the ones you do not need
+ contents: write
+ issues: write
+ pull-requests: write
+ steps:
+ # Git Checkout
+ - name: Checkout Code
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
+ - name: Install Spectral
+ run: npm install -g @stoplight/spectral
+ - name: Install Spectral functions
+ run: npm install -g @stoplight/spectral-functions
+ # - name: Run spectral:oas Spectral Linting
+ # run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml
+ # Replace openapi.yaml file with your API specification file
+
+ # MegaLinter
+ - name: MegaLinter
+ id: ml
+ # You can override MegaLinter flavor used to have faster performances
+ # More info at https://megalinter.io/flavors/
+ uses: oxsecurity/megalinter/flavors/java@v7.3.0
+ env:
+ # All available variables are described in documentation
+ # https://megalinter.io/configuration/
+ PRINT_ALPACA: false
+ # VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources
+ VALIDATE_ALL_CODEBASE: true
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY
+ DISABLE: COPYPASTE,MARKDOWN
+ DISABLE_LINTERS: SPELL_CSPELL,SPELL_LYCHEE,YAML_PRETTIER,REPOSITORY_GRYPE, REPOSITORY_SEMGREP,REPOSITORY_DEVSKIM,REPOSITORY_KICS,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_CHECKOV,REPOSITORY_GITLEAKS,YAML_V8R,JAVA_PMD,JAVA_CHECKSTYLE
+ YAML_YAMLLINT_CONFIG_FILE: ".yamllint.yaml"
+ OPENAPI_SPECTRAL_CONFIG_FILE: ".spectral.yml"
+ YAML_YAMLLINT_FILTER_REGEX_INCLUDE: "(code/)"
+ OPENAPI_SPECTRAL_FILTER_REGEX_INCLUDE: "(code/)"
+
+ # Upload MegaLinter artifacts
+ - name: Archive production artifacts
+ if: ${{ success() }} || ${{ failure() }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: MegaLinter reports
+ path: |
+ megalinter-reports
+ mega-linter.log
diff --git a/artifacts/linting_rules/.github/workflows/spectral_oas_lint.yml b/artifacts/linting_rules/.github/workflows/spectral_oas_lint.yml
new file mode 100644
index 00000000..a828fd58
--- /dev/null
+++ b/artifacts/linting_rules/.github/workflows/spectral_oas_lint.yml
@@ -0,0 +1,36 @@
+---
+# CAMARA Project - workflow configuration to manually run CAMARA OAS rules
+# see https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow
+# 31.01.2024 - initial version
+
+name: Spectral manual run
+
+on: workflow_dispatch
+
+concurrency:
+ group: ${{ github.ref }}-${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: Spectral linting
+ runs-on: ubuntu-latest
+ permissions:
+ # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR
+ # Remove the ones you do not need
+ contents: write
+ issues: write
+ pull-requests: write
+ steps:
+ # Git Checkout
+ - name: Checkout Code
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
+ - name: Install Spectral
+ run: npm install -g @stoplight/spectral
+ - name: Install Spectral functions
+ run: npm install -g @stoplight/spectral-functions
+ - name: Run Spectral linting
+ run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml
diff --git a/artifacts/linting_rules/.spectral.yml b/artifacts/linting_rules/.spectral.yml
new file mode 100644
index 00000000..0b16508e
--- /dev/null
+++ b/artifacts/linting_rules/.spectral.yml
@@ -0,0 +1,258 @@
+# CAMARA Project - linting ruleset - documentation avaialable here:
+# https://github.com/camaraproject/Commonalities/blob/main/documentation/Linting-rules.md
+# 31.01.2024 - initial version
+
+extends: "spectral:oas"
+functions:
+ - camara-reserved-words
+ - camara-language-avoid-telco
+ - camara-security-no-secrets-in-path-or-query-parameters
+functionsDir: "./lint_function"
+rules:
+ # Built-in OpenAPI Specification ruleset. Each rule then can be enabled individually.
+ # The severity keyword is optional in rule definition and can be error, warn, info, hint, or off. The default value is warn.
+ contact-properties: false
+ duplicated-entry-in-enum: true
+ info-contact: true
+ info-description: true
+ info-license: true
+ license-url: true
+ no-$ref-siblings: error
+ no-eval-in-markdown: true
+ no-script-tags-in-markdown: true
+ openapi-tags: false
+ openapi-tags-alphabetical: false
+ openapi-tags-uniqueness: error
+ operation-description: true
+ operation-operationId: true
+ operation-operationId-unique: error
+ operation-operationId-valid-in-url: true
+ operation-parameters: true
+ operation-singular-tag: true
+ operation-success-response: true
+ operation-tags: true
+ operation-tag-defined: true
+ path-declarations-must-exist: true
+ path-keys-no-trailing-slash: true
+ path-not-include-query: true
+ path-params: error
+ tag-description: false
+ typed-enum: true
+ oas3-api-servers: true
+ oas3-examples-value-or-externalValue: true
+ oas3-operation-security-defined: false
+ oas3-parameter-description: false
+ oas3-schema: true
+ oas3-server-not-example.com: false
+ oas3-server-trailing-slash: true
+ oas3-unused-component: true
+ oas3-valid-media-example: true
+ oas3-valid-schema-example: true
+ # oas3-server-variables: true
+
+ # Custom Rules Utilizing Spectral's Built-in Functions and JavaScript Implementations
+
+ camara-language-avoid-telco:
+ message: "{{error}}"
+ severity: hint
+ description: |
+ This rule checks for telco-specific terminology in your API definitions and suggests more inclusive terms.
+ given: "$..*.*"
+ then:
+ function: camara-language-avoid-telco
+ recommended: false # Set to true/false to enable/disable this rule
+
+ camara-oas-version:
+ message: "OpenAPI Version Error: The OpenAPI specification must adhere to version 3.0.3."
+ severity: error
+ description: |
+ This rule validates the OpenAPI version in your specification and requires compliance with version 3.0.3.
+ given: "$"
+ then:
+ field: openapi
+ function: pattern
+ functionOptions:
+ match: 3.0.3
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-path-param-id:
+ message: "Path Parameter Naming Warning: Use 'resource_id' instead of just 'id' in path parameters."
+ severity: warn
+ description: |
+ This rule ensures consistent and descriptive naming for path parameters in your OpenAPI specification.
+ Please use 'resource_id' instead of just 'id' for your path parameters.
+ given: "$..parameters[?(@.in == 'path')]"
+ then:
+ field: name
+ function: pattern
+ functionOptions:
+ notMatch: \b(id|Id|ID|iD)\b
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-security-no-secrets-in-path-or-query-parameters:
+ message: "Sensitive data found in path: {{error}} Consider avoiding the use of Sesentive data "
+ severity: warn
+ description: |
+ This rule checks for sensitive data ('MSISDN' and 'IMSI') in API paths and suggests avoiding their use.
+ given:
+ - "$.paths"
+ then:
+ function: camara-security-no-secrets-in-path-or-query-parameters
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-http-methods:
+ description: "Ensure that all path URLs have valid HTTP methods (GET, PUT, POST, DELETE, PATCH, OPTIONS)."
+ message: "Invalid HTTP method for '{{path}}'. Must be one of get, put, post, delete, patch, options."
+ severity: error
+ given: $.paths[*][*]~
+ then:
+ function: pattern
+ functionOptions:
+ match: "^(get|put|post|delete|patch|options)$"
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-get-no-request-body:
+ message: There must be no request body for Get and DELETE
+ severity: error
+ given:
+ - "$.paths.*.get"
+ - "$.paths.*.delete"
+ then:
+ field: requestBody
+ function: falsy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-reserved-words:
+ message: "Reserved words found {{error}} Consider avoiding the use of reserved word "
+ severity: warn
+ description: |
+ This rule checks Reserved words must not be used in the following parts of an API specification [Paths, Request Body properties, Component, Operation Id, Security Schema]
+ given:
+ - "$.paths" # Paths
+ - "$..parameters[*]" # Path or Query Parameter Names:
+ - "$..components.schemas.*.properties.*" # Request and Response body parameter
+ - "$.paths.*." # Path and Operation Names:
+ - "$.components.securitySchemes" # Security Schemes:
+ - "$.components.*.*" # Component Names:
+ - "$.paths.*.*.operationId" # OperationIds:
+ then:
+ function: camara-reserved-words
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-routes-description:
+ message: "Functionality method description Warning: Each method should have description."
+ severity: warn
+ description: |
+ This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a description.
+ Ensure that you have added a 'summary' field for each operation in your OpenAPI specification.
+ given:
+ - "$.paths.*.post"
+ - "$.paths.*.get"
+ - "$.paths.*.delete"
+ - "$.paths.*.put"
+ - "$.paths.*.patch"
+ - "$.paths.*.options"
+ then:
+ field: description
+ function: truthy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-parameters-descriptions:
+ message: "Parameter description is missing or empty: {{error}}"
+ severity: warn
+ description: |
+ This Spectral rule ensures that each path parameter in the API specification has a descriptive and meaningful description.
+ given:
+ - "$.paths..parameters.*"
+ then:
+ field: description
+ function: truthy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-response-descriptions:
+ message: "Parameter description is missing or empty: {{error}}"
+ severity: warn
+ description: |
+ This Spectral rule ensures that each responese object in the API specification has a descriptive and meaningful description.
+ given:
+ - "$.paths..responses.*"
+ then:
+ field: description
+ function: truthy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-properties-descriptions:
+ message: "Property description is missing or empty: {{error}}"
+ severity: warn
+ description: |
+ This Spectral rule ensures that each propoerty within objects in the API specification has a descriptive and meaningful description.
+ given:
+ - "$.components.*.*"
+ - "$.components.*.*.properties.*"
+ then:
+ field: description
+ function: truthy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-operation-summary:
+ message: "Operation Summary Warning: Each operation should include a short summary for better understanding."
+ severity: warn
+ description: |
+ This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a meaningful summary.
+ Ensure that you have added a 'summary' field for each operation in your OpenAPI specification.
+ given:
+ - "$.paths.*.post"
+ - "$.paths.*.get"
+ - "$.paths.*.delete"
+ - "$.paths.*.put"
+ - "$.paths.*.patch"
+ - "$.paths.*.options"
+ then:
+ field: summary
+ function: truthy
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-discriminator-use:
+ description: |
+ Ensure that API definition YAML files with oneOf or anyOf sections include a discriminator object for serialization, deserialization, and validation.
+ severity: hint
+ given: "$..[?(@.oneOf || @.anyOf)]"
+ then:
+ field: discriminator
+ function: truthy
+ description: "Discriminator object is required when using oneOf or anyOf."
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-operationid-casing-convention:
+ message: Operation Id must be in Camel case "{{error}}"
+ severity: hint
+ description: |
+ This rule checks Operation ids should follow a specific case convention: camel case.
+ given: "$.paths.*.*.operationId"
+ then:
+ function: casing
+ functionOptions:
+ type: camel
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-schema-casing-convention:
+ description: This rule checks schema should follow a specific case convention pascal case.
+ message: "{{property}} should be pascal case (UppperCamelCase)"
+ severity: warn
+ given: $.components.schemas[*]~
+ then:
+ function: casing
+ functionOptions:
+ type: pascal
+ recommended: true # Set to true/false to enable/disable this rule
+
+ camara-parameter-casing-convention:
+ description: Paths should be kebab-case.
+ severity: error
+ 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
+ recommended: true # Set to true/false to enable/disable this rule
diff --git a/artifacts/linting_rules/.yamllint.yaml b/artifacts/linting_rules/.yamllint.yaml
new file mode 100644
index 00000000..081ef093
--- /dev/null
+++ b/artifacts/linting_rules/.yamllint.yaml
@@ -0,0 +1,35 @@
+---
+# CAMARA Project - YAML linting configuration for yamllint https://yamllint.readthedocs.io/en/latest/rules.html
+# 31.01.2024 - initial version
+
+yaml-files:
+ - '*.yaml'
+ - '*.yml'
+ - '.yamllint'
+
+rules:
+ braces: enable
+ brackets: enable
+ colons: enable
+ commas: enable
+ comments:
+ min-spaces-from-content: 1
+ level: error
+ comments-indentation:
+ level: error
+ document-end: disable
+ document-start: disable
+ empty-lines: enable
+ empty-values: disable
+ hyphens: enable
+ indentation: enable
+ key-duplicates: enable
+ key-ordering: disable
+ line-length: disable
+ new-line-at-end-of-file: enable
+ new-lines: disable
+ octal-values: disable
+ quoted-strings: disable
+ trailing-spaces: enable
+ truthy:
+ level: error
diff --git a/artifacts/linting_rules/lint_function/camara-language-avoid-telco.js b/artifacts/linting_rules/lint_function/camara-language-avoid-telco.js
new file mode 100644
index 00000000..061b5431
--- /dev/null
+++ b/artifacts/linting_rules/lint_function/camara-language-avoid-telco.js
@@ -0,0 +1,40 @@
+// CAMARA Project - support function for Spectral linter
+// 31.01.2024 - initial version
+
+const replacements = [
+ { original: 'UE', recommended: 'device' },
+ { original: 'MSISDN', recommended: 'phone number' },
+ { original: 'mobile network', recommended: 'network' }
+];
+
+export default async function (input) {
+ const errors = [];
+ const suggestions = [];
+
+ // Iterate over properties of the input object
+ for (const path in input) {
+ const value = input[path];
+
+ // Check if the value is a string
+ if (typeof value === 'string') {
+ for (const replacement of replacements) {
+ const original = replacement.original;
+ const recommended = replacement.recommended;
+
+ // Use a regular expression to match 'original' as a standalone word
+ const regex = new RegExp(`\\b${original}\\b`, 'g');
+
+ // Check if 'original' exists in the value
+ if (regex.test(value)) {
+ errors.push(replacement);
+ suggestions.push(` Telco-specific terminology found in input: Consider replacing '${original}' with '${recommended}'.`);
+ }
+ }
+ }
+ }
+
+ // Check if any word from 'replacements' is in the suggestions
+ if (errors.length > 0) {
+ console.log(`Hint camara-language-avoid-telco ` + suggestions.join(', '));
+ }
+};
diff --git a/artifacts/linting_rules/lint_function/camara-reserved-words.js b/artifacts/linting_rules/lint_function/camara-reserved-words.js
new file mode 100644
index 00000000..c28e63ab
--- /dev/null
+++ b/artifacts/linting_rules/lint_function/camara-reserved-words.js
@@ -0,0 +1,98 @@
+// CAMARA Project - support function for Spectral linter
+// 31.01.2024 - initial version
+
+const reservedWords = [
+ 'abstract',
+ 'apiclient',
+ 'apiexception',
+ 'apiresponse',
+ 'assert',
+ 'boolean',
+ 'break',
+ 'byte',
+ 'case',
+ 'catch',
+ 'char',
+ 'class',
+ 'configuration',
+ 'const',
+ 'continue',
+ 'do',
+ 'double',
+ 'else',
+ 'extends',
+ 'file',
+ 'final',
+ 'finally',
+ 'float',
+ 'for',
+ 'goto',
+ 'if',
+ 'implements',
+ 'import',
+ 'instanceof',
+ 'int',
+ 'interface',
+ 'list',
+ 'localdate',
+ 'localreturntype',
+ 'localtime',
+ 'localvaraccept',
+ 'localvaraccepts',
+ 'localvarauthnames',
+ 'localvarcollectionqueryparams',
+ 'localvarcontenttype',
+ 'localvarcontenttypes',
+ 'localvarcookieparams',
+ 'localvarformparams',
+ 'localvarheaderparams',
+ 'localvarpath',
+ 'localvarpostbody',
+ 'localvarqueryparams',
+ 'long',
+ 'native',
+ 'new',
+ 'null',
+ 'object',
+ 'offsetdatetime',
+ 'package',
+ 'private',
+ 'protected',
+ 'public',
+ 'return',
+ 'short',
+ 'static',
+ 'strictfp',
+ 'stringutil',
+ 'super',
+ 'switch',
+ 'synchronized',
+ 'this',
+ 'throw',
+ 'throws',
+ 'transient',
+ 'try',
+ 'void',
+ 'volatile',
+ 'while'
+];
+// Reserved word 'enum' and 'default' are removed from above reserved word array as they are common in openAPI keyword
+export default async function lintReservedWords(input) {
+ // Iterate over properties of the input object
+ for (const path in input) {
+ if (typeof path === 'string') {
+
+ for (const word of reservedWords) {
+ const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word
+
+ if (regex.test(path)) {
+ const warningRuleName = 'camara-reserved-words';
+ const description = `Reserved words found in input: Consider avoiding the use of reserved word '${word}'`;
+ // const location = `${path}`;
+
+ console.log(`warning ${warningRuleName} ${description} ${path}`);
+ }
+ }
+ }
+ }
+}
diff --git a/artifacts/linting_rules/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js b/artifacts/linting_rules/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js
new file mode 100644
index 00000000..ebbff2a4
--- /dev/null
+++ b/artifacts/linting_rules/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js
@@ -0,0 +1,26 @@
+// CAMARA Project - support function for Spectral linter
+// 31.01.2024 - initial version
+
+const sensitiveData = ['MSISDN','IMSI','phoneNumber'];
+
+export default async function (input) {
+
+ // Iterate over properties of the input object
+ for (const path in input) {
+
+ if (typeof path === 'string') {
+ for (const word of sensitiveData ) {
+ const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word
+
+ if (regex.test(path)) {
+
+ const warningRuleName = 'camara-security-no-secrets-in-path-or-query-parameters';
+ const description = `sensitiveData Data found in path: Consider avoiding the use of sensitiveData data '${word}'`;
+ const location = `paths.${path}`;
+ console.log(`warning ${warningRuleName} ${description} ${location}`);
+
+ }
+ }
+ }
+ }
+}
diff --git a/documentation/API-linting-Implementation-Guideline.md b/documentation/API-linting-Implementation-Guideline.md
new file mode 100644
index 00000000..f26256b0
--- /dev/null
+++ b/documentation/API-linting-Implementation-Guideline.md
@@ -0,0 +1,81 @@
+# CAMARA OpenAPI Linting Rules Implementaion Guideline [ How to integrate the rules into CAMARA repository ]
+
+## Introduction
+
+This guide provides instructions how to implement linting rules for the CAMARA APIs using two methods: **[GitHub Actions](API-linting-Implementation-Guideline.md#github-actions-integration)** and **[local deployment](API-linting-Implementation-Guideline.md#github-actions-integration)**, both methods use [Spectral tool](https://docs.stoplight.io/docs/spectral/674b27b261c3c-overview).
+All needed files are stored in [artifacts subfolder](https://github.com/camaraproject/Commonalities/tree/API-linting-Implementation-Guideline/artifacts/linting_rules).
+
+The target method is linting rules integration with CAMARA API subproject repositories using GitHub Actions.
+
+
+## Spectral Configuration
+
+The Spectral configuration consists of .spectral.yml file, which contains all the rules defined for CAMARA OpenAPI specification as described in [Linting-rules.md](Linting-rules.md)
+
+This file consolidates all rules:
+
+1. Spectral Core OpenAPI specification linting ruleset:
+
+ `Ruleset extension: extends: "spectral:oas"`
+
+2. Spectral rules with built-in functions
+3. Spectral rules with custom JavaScript functions
+
+
+## GitHub Actions Integration
+
+1. Add **[.spectral.yml](https://github.com/camaraproject/Commonalities/blob/main/artifacts/linting_rules/.spectral.yml)** (rules) file to -> root location of repository
+
+2. Create **lint-function** folder
+
+ Make a folder named `lint_function` at root location and add custom [JavaScript function files](https://github.com/camaraproject/Commonalities/tree/API-linting-Implementation-Guideline/artifacts/linting_rules/lint_function) that are imported in .spectral.yml (some rules require custom JavaScript functions to execute).
+
+3. Add **[spectral_oas_lint.yml](https://github.com/camaraproject/Commonalities/blob/main/artifacts/linting_rules/.github/workflows/spectral_oas_lint.yml)** to GitHub action workflows in `.github/workflows` folder
+ which includes the configuration of Spectral workflow for GitHub actions.
+
+4. Add [megalinter.yml](https://github.com/camaraproject/Commonalities/blob/main/artifacts/linting_rules/.github/workflows/megalinter.yml) to GitHub action workflows in `.github/workflows` folder
+ which includes the configuration of Megalinter and Spectral for GitHub actions.
+
+### Manually running linting workflow
+
+**spectral_oas_lint.yml** includes configuration of the OAS linting workflow to be run manually as described in [GitHub Actions documentation](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow).
+
+The rules will be applied to all files with *.yaml extension in '/code/API_definitions/' folder of the repository.
+Write access to the repository is required to perform these steps.
+
+The output from Spectral can be seen by expanding the step **Run Spectral Linting** of given worflow run Actions section of GitHub repository.
+
+
+### Megalinter integration
+
+[Megalinter](https://megalinter.io/latest/) is an Open-Source tool for CI/CD workflows that analyzes the consistency of code, configurations and scripts in repository sources. Megalinter supports Spectral linting.
+The Megalinter job will be automatically activated once you submit a pull request on the [main/master] branch of the CAMARA repository, as configured in megalinter.yml.
+
+The Megalinter configuration consists of the megalinter.yml file containing the necessary settings to run Megalinter and Spectral jobs on GitHub actions.
+
+Additionally, Megalinter also supports linting of YAML files. To enable this, users need to add the following ruleset files to the root location.
+
+- YAML Linting: .yamllint.yaml
+
+
+
+
+## API Linting configuration steps for local deployment
+
+1. Install Spectral locally:
+
+ npm install -g @stoplight/spectral
+
+2. Install Spectral functions locally:
+
+ npm install --save @stoplight/spectral-functions
+
+3. Save files locally:
+
+ Save ".spectral.yml" file (contains Linting rules) and lint_function folder (contains JavaScript customized functions) at the root location.
+
+4. Apply spectral rules on API specification loacally:
+
+ spectral lint openapi.yaml --verbose --ruleset .spectral.yml
+
+ *Replace **'openapi.yaml'** with the path to your OpenAPI specification file.*