mirror of
https://github.com/super-linter/super-linter.git
synced 2024-12-01 13:10:57 -05:00
commit
6f942ee634
17 changed files with 368 additions and 46 deletions
13
.automation/test/cfn/README.md
Normal file
13
.automation/test/cfn/README.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# AWS CloudFormation Test Cases
|
||||||
|
This folder holds the test cases for **CloudFormation**.
|
||||||
|
|
||||||
|
## Additional Docs
|
||||||
|
No Additional information is needed for this test case.
|
||||||
|
|
||||||
|
## Good Test Cases
|
||||||
|
The test cases denoted: `LANGUAGE_good_FILE.EXTENSION` are all valid, and should pass successfully when linted.
|
||||||
|
- **Note:** They are linted utilizing the default linter rules.
|
||||||
|
|
||||||
|
## Bad Test Cases
|
||||||
|
The test cases denoted: `LANGUAGE_bad_FILE.EXTENSION` are **NOT** valid, and should trigger errors when linted.
|
||||||
|
- **Note:** They are linted utilizing the default linter rules.
|
35
.automation/test/cfn/cfn_bad_1.json
Normal file
35
.automation/test/cfn/cfn_bad_1.json
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "A sample template",
|
||||||
|
"Resources": {
|
||||||
|
"DNS": {
|
||||||
|
"Type": "AWS::Route53::HostedZonee",
|
||||||
|
"Properties": {
|
||||||
|
"HostedZoneConfig": {
|
||||||
|
"Comment": "Myhostedzoneforexample.com"
|
||||||
|
},
|
||||||
|
"Name": "example.com",
|
||||||
|
"VPCs": [
|
||||||
|
{
|
||||||
|
"VPCId": "vpc-abcd1234",
|
||||||
|
"VPCRegion": "ap-northeast-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"VPCId": "vpc-efgh5678",
|
||||||
|
"VPCRegion": "us-west-2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"HostedZoneTags": [
|
||||||
|
{
|
||||||
|
"Key": "SampleKey1",
|
||||||
|
"Value": "SampleValue1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Key": "SampleKey2",
|
||||||
|
"Value": "SampleValue2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
.automation/test/cfn/cfn_bad_2.yaml
Normal file
23
.automation/test/cfn/cfn_bad_2.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
AWSTemplateFormatVersion: "2010-09-09"
|
||||||
|
Description: A sample template
|
||||||
|
Resources:
|
||||||
|
DNS:
|
||||||
|
Type: "AWS::Route53::HostedZonee"
|
||||||
|
Properties:
|
||||||
|
HostedZoneConfig:
|
||||||
|
Comment: 'My hosted zone for example.com'
|
||||||
|
Name: 'example.com'
|
||||||
|
VPCs:
|
||||||
|
-
|
||||||
|
VPCId: 'vpc-abcd1234'
|
||||||
|
VPCRegion: 'ap-northeast-1'
|
||||||
|
-
|
||||||
|
VPCId: 'vpc-efgh5678'
|
||||||
|
VPCRegion: 'us-west-2'
|
||||||
|
HostedZoneTags:
|
||||||
|
-
|
||||||
|
Key: 'SampleKey1'
|
||||||
|
Value: 'SampleValue1'
|
||||||
|
-
|
||||||
|
Key: 'SampleKey2'
|
||||||
|
Value: 'SampleValue2'
|
16
.automation/test/cfn/cfn_bad_3.json
Normal file
16
.automation/test/cfn/cfn_bad_3.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"Resources" : {
|
||||||
|
"myDNSRecord" : {
|
||||||
|
"Type" : "AWS::Route53::RecordSet",
|
||||||
|
"Properties" : {
|
||||||
|
"HostedZoneId" : "Z8VLZEXAMPLE",
|
||||||
|
"Name" : "test.example.com",
|
||||||
|
"ResourceRecords" : [
|
||||||
|
"192.0.2.99"
|
||||||
|
],
|
||||||
|
"Ttl" : 300,
|
||||||
|
"Type" : "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
.automation/test/cfn/cfn_bad_4.yaml
Normal file
10
.automation/test/cfn/cfn_bad_4.yaml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Resources:
|
||||||
|
myDNSRecord:
|
||||||
|
Type: AWS::Route53::RecordSet
|
||||||
|
Properties:
|
||||||
|
HostedZoneId : Z8VLZEXAMPLE
|
||||||
|
Name: test.example.com
|
||||||
|
ResourceRecords:
|
||||||
|
- 192.0.2.99
|
||||||
|
Ttl: 900
|
||||||
|
Type: A
|
35
.automation/test/cfn/cfn_good_1.json
Normal file
35
.automation/test/cfn/cfn_good_1.json
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "A sample template",
|
||||||
|
"Resources": {
|
||||||
|
"DNS": {
|
||||||
|
"Type": "AWS::Route53::HostedZone",
|
||||||
|
"Properties": {
|
||||||
|
"HostedZoneConfig": {
|
||||||
|
"Comment": "Myhostedzoneforexample.com"
|
||||||
|
},
|
||||||
|
"Name": "example.com",
|
||||||
|
"VPCs": [
|
||||||
|
{
|
||||||
|
"VPCId": "vpc-abcd1234",
|
||||||
|
"VPCRegion": "ap-northeast-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"VPCId": "vpc-efgh5678",
|
||||||
|
"VPCRegion": "us-west-2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"HostedZoneTags": [
|
||||||
|
{
|
||||||
|
"Key": "SampleKey1",
|
||||||
|
"Value": "SampleValue1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Key": "SampleKey2",
|
||||||
|
"Value": "SampleValue2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
.automation/test/cfn/cfn_good_2.yaml
Normal file
23
.automation/test/cfn/cfn_good_2.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
AWSTemplateFormatVersion: "2010-09-09"
|
||||||
|
Description: A sample template
|
||||||
|
Resources:
|
||||||
|
DNS:
|
||||||
|
Type: "AWS::Route53::HostedZone"
|
||||||
|
Properties:
|
||||||
|
HostedZoneConfig:
|
||||||
|
Comment: 'My hosted zone for example.com'
|
||||||
|
Name: 'example.com'
|
||||||
|
VPCs:
|
||||||
|
-
|
||||||
|
VPCId: 'vpc-abcd1234'
|
||||||
|
VPCRegion: 'ap-northeast-1'
|
||||||
|
-
|
||||||
|
VPCId: 'vpc-efgh5678'
|
||||||
|
VPCRegion: 'us-west-2'
|
||||||
|
HostedZoneTags:
|
||||||
|
-
|
||||||
|
Key: 'SampleKey1'
|
||||||
|
Value: 'SampleValue1'
|
||||||
|
-
|
||||||
|
Key: 'SampleKey2'
|
||||||
|
Value: 'SampleValue2'
|
16
.automation/test/cfn/cfn_good_3.json
Normal file
16
.automation/test/cfn/cfn_good_3.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"Resources" : {
|
||||||
|
"myDNSRecord" : {
|
||||||
|
"Type" : "AWS::Route53::RecordSet",
|
||||||
|
"Properties" : {
|
||||||
|
"HostedZoneId" : "Z8VLZEXAMPLE",
|
||||||
|
"Name" : "test.example.com",
|
||||||
|
"ResourceRecords" : [
|
||||||
|
"192.0.2.99"
|
||||||
|
],
|
||||||
|
"TTL" : 300,
|
||||||
|
"Type" : "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
.automation/test/cfn/cfn_good_4.yaml
Normal file
10
.automation/test/cfn/cfn_good_4.yaml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Resources:
|
||||||
|
myDNSRecord:
|
||||||
|
Type: AWS::Route53::RecordSet
|
||||||
|
Properties:
|
||||||
|
HostedZoneId : Z8VLZEXAMPLE
|
||||||
|
Name: test.example.com
|
||||||
|
ResourceRecords:
|
||||||
|
- 192.0.2.99
|
||||||
|
TTL: 900
|
||||||
|
Type: A
|
2
.github/linters/.cfnlintrc.yml
vendored
Normal file
2
.github/linters/.cfnlintrc.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include_checks:
|
||||||
|
- I
|
|
@ -53,7 +53,7 @@ RUN mkdir -p /opt/microsoft/powershell/7 \
|
||||||
# Run Pip3 Installs #
|
# Run Pip3 Installs #
|
||||||
#####################
|
#####################
|
||||||
RUN pip3 --no-cache-dir install --upgrade --no-cache-dir \
|
RUN pip3 --no-cache-dir install --upgrade --no-cache-dir \
|
||||||
yamllint pylint yq
|
yamllint pylint yq cfn-lint shyaml
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Run NPM Installs #
|
# Run NPM Installs #
|
||||||
|
|
12
README.md
12
README.md
|
@ -35,16 +35,22 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base
|
||||||
| *Language* | *Linter* |
|
| *Language* | *Linter* |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) |
|
| **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) |
|
||||||
|
| **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint/) |
|
||||||
| **CSS** | [stylelint](https://stylelint.io/) |
|
| **CSS** | [stylelint](https://stylelint.io/) |
|
||||||
| **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) |
|
| **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) |
|
||||||
| **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) |
|
| **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) |
|
||||||
| **Dockerfile** | [dockerfilelint](https://github.com/replicatedhq/dockerfilelint.git) |
|
| **Dockerfile** | [dockerfilelint](https://github.com/replicatedhq/dockerfilelint.git) |
|
||||||
|
| **ENV** | [dotenv-linter](https://github.com/dotenv-linter/dotenv-linter) |
|
||||||
| **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) |
|
| **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) |
|
||||||
| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) |
|
| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) |
|
||||||
| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) |
|
| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) |
|
||||||
|
| **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) |
|
||||||
| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) |
|
| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) |
|
||||||
|
| **OpenAPI** | [spectral](https://github.com/stoplightio/spectral) |
|
||||||
| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) |
|
| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) |
|
||||||
| **PHP** | [PHP](https://www.php.net/) |
|
| **PHP** | [PHP](https://www.php.net/) |
|
||||||
|
| **PowerShell** | [PSScriptAnalyzer](https://github.com/PowerShell/Psscriptanalyzer) |
|
||||||
|
| **Protocol Buffers** | [protolint](https://github.com/yoheimuta/protolint) |
|
||||||
| **Python3** | [pylint](https://www.pylint.org/) |
|
| **Python3** | [pylint](https://www.pylint.org/) |
|
||||||
| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) |
|
| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) |
|
||||||
| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) |
|
| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) |
|
||||||
|
@ -52,11 +58,6 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base
|
||||||
| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) |
|
| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) |
|
||||||
| **XML** | [LibXML](http://xmlsoft.org/) |
|
| **XML** | [LibXML](http://xmlsoft.org/) |
|
||||||
| **YAML** | [YamlLint](https://github.com/adrienverge/yamllint) |
|
| **YAML** | [YamlLint](https://github.com/adrienverge/yamllint) |
|
||||||
| **PowerShell** | [PSScriptAnalyzer](https://github.com/PowerShell/Psscriptanalyzer) |
|
|
||||||
| **ENV** | [dotenv-linter](https://github.com/dotenv-linter/dotenv-linter) |
|
|
||||||
| **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) |
|
|
||||||
| **OpenAPI** | [spectral](https://github.com/stoplightio/spectral) |
|
|
||||||
| **Protocol Buffers** | [protolint](https://github.com/yoheimuta/protolint) |
|
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
To use this **GitHub** Action you will need to complete the following:
|
To use this **GitHub** Action you will need to complete the following:
|
||||||
|
@ -168,6 +169,7 @@ and won't run anything unexpected.
|
||||||
| **VALIDATE_CLOJURE** | `true` | Flag to enable or disable the linting process of the language. |
|
| **VALIDATE_CLOJURE** | `true` | Flag to enable or disable the linting process of the language. |
|
||||||
| **VALIDATE_KOTLIN** | `true` | Flag to enable or disable the linting process of the language. |
|
| **VALIDATE_KOTLIN** | `true` | Flag to enable or disable the linting process of the language. |
|
||||||
| **VALIDATE_OPENAPI** | `true` | Flag to enable or disable the linting process of the language. |
|
| **VALIDATE_OPENAPI** | `true` | Flag to enable or disable the linting process of the language. |
|
||||||
|
| **VALIDATE_CLOUDFORMATION** | `true` | Flag to enable or disable the linting process of the language. |
|
||||||
| **VALIDATE_PROTOBUF** | `true` | Flag to enable or disable the linting process of the language. |
|
| **VALIDATE_PROTOBUF** | `true` | Flag to enable or disable the linting process of the language. |
|
||||||
| **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s). |
|
| **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s). |
|
||||||
| **ACTIONS_RUNNER_DEBUG** | `false` | Flag to enable additional information about the linter, versions, and additional output. |
|
| **ACTIONS_RUNNER_DEBUG** | `false` | Flag to enable additional information about the linter, versions, and additional output. |
|
||||||
|
|
2
TEMPLATES/.cfnlintrc.yml
Normal file
2
TEMPLATES/.cfnlintrc.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include_checks:
|
||||||
|
- I
|
|
@ -7,6 +7,7 @@ Below are examples and documentation for each language and the various methods t
|
||||||
- [Shell](#shell)
|
- [Shell](#shell)
|
||||||
- [Ansible](#ansible)
|
- [Ansible](#ansible)
|
||||||
- [YAML](#yaml)
|
- [YAML](#yaml)
|
||||||
|
- [AWS CloudFormation templates](#cfn)
|
||||||
- [Python](#python3)
|
- [Python](#python3)
|
||||||
- [JSON](#json)
|
- [JSON](#json)
|
||||||
- [Markdown](#markdown)
|
- [Markdown](#markdown)
|
||||||
|
@ -239,6 +240,42 @@ var = "terrible code down here..."
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
## AWS CloudFormation templates
|
||||||
|
- [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint/)
|
||||||
|
|
||||||
|
### cfn-lint Config file
|
||||||
|
- `.github/linters/.cfnlintrc.yml`
|
||||||
|
- You can pass multiple rules and overwrite default rules
|
||||||
|
- File should be located at: `.github/linters/.cfnlintrc.yml`
|
||||||
|
|
||||||
|
### cfn-lint disable single line
|
||||||
|
- There is currently **No** way to disable rules inline of the file(s)
|
||||||
|
|
||||||
|
### cfn-lint disable code block
|
||||||
|
You can disable both [template](https://github.com/aws-cloudformation/cfn-python-lint/#template-based-metadata) or [resource](https://github.com/aws-cloudformation/cfn-python-lint/#resource-based-metadata) via [metadata](https://github.com/aws-cloudformation/cfn-python-lint/#metadata):
|
||||||
|
```yaml
|
||||||
|
Resources:
|
||||||
|
myInstance:
|
||||||
|
Type: AWS::EC2::Instance
|
||||||
|
Metadata:
|
||||||
|
cfn-lint:
|
||||||
|
config:
|
||||||
|
ignore_checks:
|
||||||
|
- E3030
|
||||||
|
Properties:
|
||||||
|
InstanceType: nt.x4superlarge
|
||||||
|
ImageId: ami-abc1234
|
||||||
|
```
|
||||||
|
|
||||||
|
### cfn-lint disable entire file
|
||||||
|
If you need to ignore an entire file, you can update the `.github/linters/.cfnlintrc.yml` to ignore certain files and locations
|
||||||
|
```yaml
|
||||||
|
ignore_templates:
|
||||||
|
- codebuild.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
## JSON
|
## JSON
|
||||||
- [jsonlint](https://github.com/zaach/jsonlint)
|
- [jsonlint](https://github.com/zaach/jsonlint)
|
||||||
|
|
||||||
|
|
|
@ -100,18 +100,26 @@ function BuildFileList()
|
||||||
#echo "FILE_TYPE:[$FILE_TYPE]"
|
#echo "FILE_TYPE:[$FILE_TYPE]"
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# Get the YML files #
|
# Get the CFN files #
|
||||||
#####################
|
#####################
|
||||||
if [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ]; then
|
if [ "$FILE_TYPE" == "json" ] || [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ] && DetectCloudFormationFile "$FILE"; then
|
||||||
################################
|
################################
|
||||||
# Append the file to the array #
|
# Append the file to the array #
|
||||||
################################
|
################################
|
||||||
FILE_ARRAY_YML+=("$FILE")
|
FILE_ARRAY_CFN+=("$FILE")
|
||||||
############################
|
##########################################################
|
||||||
# Check if file is OpenAPI #
|
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
|
||||||
############################
|
##########################################################
|
||||||
if DetectOpenAPIFile "$FILE"; then
|
READ_ONLY_CHANGE_FLAG=1
|
||||||
FILE_ARRAY_OPENAPI+=("$FILE")
|
|
||||||
|
#####################################
|
||||||
|
# Check if the file is CFN template #
|
||||||
|
#####################################
|
||||||
|
if DetectCloudFormationFile "$FILE"; then
|
||||||
|
################################
|
||||||
|
# Append the file to the array #
|
||||||
|
################################
|
||||||
|
FILE_ARRAY_CFN+=("$FILE")
|
||||||
fi
|
fi
|
||||||
##########################################################
|
##########################################################
|
||||||
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
|
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
|
||||||
|
@ -129,8 +137,21 @@ function BuildFileList()
|
||||||
# Check if file is OpenAPI #
|
# Check if file is OpenAPI #
|
||||||
############################
|
############################
|
||||||
if DetectOpenAPIFile "$FILE"; then
|
if DetectOpenAPIFile "$FILE"; then
|
||||||
|
################################
|
||||||
|
# Append the file to the array #
|
||||||
|
################################
|
||||||
FILE_ARRAY_OPENAPI+=("$FILE")
|
FILE_ARRAY_OPENAPI+=("$FILE")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# Check if the file is CFN template #
|
||||||
|
#####################################
|
||||||
|
if DetectCloudFormationFile "$FILE"; then
|
||||||
|
################################
|
||||||
|
# Append the file to the array #
|
||||||
|
################################
|
||||||
|
FILE_ARRAY_CFN+=("$FILE")
|
||||||
|
fi
|
||||||
##########################################################
|
##########################################################
|
||||||
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
|
# Set the READ_ONLY_CHANGE_FLAG since this could be exec #
|
||||||
##########################################################
|
##########################################################
|
||||||
|
|
|
@ -29,6 +29,9 @@ MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to th
|
||||||
# Python Vars
|
# Python Vars
|
||||||
PYTHON_FILE_NAME='.python-lint' # Name of the file
|
PYTHON_FILE_NAME='.python-lint' # Name of the file
|
||||||
PYTHON_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PYTHON_FILE_NAME" # Path to the python lint rules
|
PYTHON_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PYTHON_FILE_NAME" # Path to the python lint rules
|
||||||
|
# Cloudformation Vars
|
||||||
|
CFN_FILE_NAME='.cfnlintrc.yml' # Name of the file
|
||||||
|
CFN_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CFN_FILE_NAME" # Path to the python lint rules
|
||||||
# Ruby Vars
|
# Ruby Vars
|
||||||
RUBY_FILE_NAME="${RUBY_CONFIG_FILE:-.ruby-lint.yml}" # Name of the file
|
RUBY_FILE_NAME="${RUBY_CONFIG_FILE:-.ruby-lint.yml}" # Name of the file
|
||||||
RUBY_LINTER_RULES="$DEFAULT_RULES_LOCATION/$RUBY_FILE_NAME" # Path to the ruby lint rules
|
RUBY_LINTER_RULES="$DEFAULT_RULES_LOCATION/$RUBY_FILE_NAME" # Path to the ruby lint rules
|
||||||
|
@ -77,7 +80,9 @@ CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME"
|
||||||
LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck"
|
LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck"
|
||||||
"pylint" "perl" "rubocop" "coffeelint" "eslint" "standard"
|
"pylint" "perl" "rubocop" "coffeelint" "eslint" "standard"
|
||||||
"ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint"
|
"ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint"
|
||||||
"stylelint" "dotenv-linter" "powershell" "ktlint" "protolint" "clj-kondo" "spectral")
|
"stylelint" "dotenv-linter" "powershell" "ktlint" "protolint" "clj-kondo"
|
||||||
|
"spectral" "cfn-lint")
|
||||||
|
|
||||||
|
|
||||||
#############################
|
#############################
|
||||||
# Language array for prints #
|
# Language array for prints #
|
||||||
|
@ -85,7 +90,7 @@ LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck"
|
||||||
LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'PHP' 'RUBY' 'PYTHON'
|
LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'PHP' 'RUBY' 'PYTHON'
|
||||||
'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES'
|
'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES'
|
||||||
'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM'
|
'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM'
|
||||||
'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI')
|
'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' 'CFN')
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# GitHub ENV Vars #
|
# GitHub ENV Vars #
|
||||||
|
@ -104,6 +109,7 @@ VALIDATE_BASH="${VALIDATE_BASH}" # Boolean to validate lang
|
||||||
VALIDATE_PERL="${VALIDATE_PERL}" # Boolean to validate language
|
VALIDATE_PERL="${VALIDATE_PERL}" # Boolean to validate language
|
||||||
VALIDATE_PHP="${VALIDATE_PHP}" # Boolean to validate language
|
VALIDATE_PHP="${VALIDATE_PHP}" # Boolean to validate language
|
||||||
VALIDATE_PYTHON="${VALIDATE_PYTHON}" # Boolean to validate language
|
VALIDATE_PYTHON="${VALIDATE_PYTHON}" # Boolean to validate language
|
||||||
|
VALIDATE_CLOUDFORMATION="${VALIDATE_CLOUDFORMATION}" # Boolean to validate language
|
||||||
VALIDATE_RUBY="${VALIDATE_RUBY}" # Boolean to validate language
|
VALIDATE_RUBY="${VALIDATE_RUBY}" # Boolean to validate language
|
||||||
VALIDATE_COFFEE="${VALIDATE_COFFEE}" # Boolean to validate language
|
VALIDATE_COFFEE="${VALIDATE_COFFEE}" # Boolean to validate language
|
||||||
VALIDATE_ANSIBLE="${VALIDATE_ANSIBLE}" # Boolean to validate language
|
VALIDATE_ANSIBLE="${VALIDATE_ANSIBLE}" # Boolean to validate language
|
||||||
|
@ -164,6 +170,7 @@ FILE_ARRAY_PERL=() # Array of files to check
|
||||||
FILE_ARRAY_PHP=() # Array of files to check
|
FILE_ARRAY_PHP=() # Array of files to check
|
||||||
FILE_ARRAY_RUBY=() # Array of files to check
|
FILE_ARRAY_RUBY=() # Array of files to check
|
||||||
FILE_ARRAY_PYTHON=() # Array of files to check
|
FILE_ARRAY_PYTHON=() # Array of files to check
|
||||||
|
FILE_ARRAY_CFN=() # Array of files to check
|
||||||
FILE_ARRAY_COFFEESCRIPT=() # Array of files to check
|
FILE_ARRAY_COFFEESCRIPT=() # Array of files to check
|
||||||
FILE_ARRAY_JAVASCRIPT_ES=() # Array of files to check
|
FILE_ARRAY_JAVASCRIPT_ES=() # Array of files to check
|
||||||
FILE_ARRAY_JAVASCRIPT_STANDARD=() # Array of files to check
|
FILE_ARRAY_JAVASCRIPT_STANDARD=() # Array of files to check
|
||||||
|
@ -192,6 +199,7 @@ ERRORS_FOUND_PERL=0 # Count of errors found
|
||||||
ERRORS_FOUND_PHP=0 # Count of errors found
|
ERRORS_FOUND_PHP=0 # Count of errors found
|
||||||
ERRORS_FOUND_RUBY=0 # Count of errors found
|
ERRORS_FOUND_RUBY=0 # Count of errors found
|
||||||
ERRORS_FOUND_PYTHON=0 # Count of errors found
|
ERRORS_FOUND_PYTHON=0 # Count of errors found
|
||||||
|
ERRORS_FOUND_CFN=0 # Count of errors found
|
||||||
ERRORS_FOUND_COFFEESCRIPT=0 # Count of errors found
|
ERRORS_FOUND_COFFEESCRIPT=0 # Count of errors found
|
||||||
ERRORS_FOUND_ANSIBLE=0 # Count of errors found
|
ERRORS_FOUND_ANSIBLE=0 # Count of errors found
|
||||||
ERRORS_FOUND_JAVASCRIPT_STANDARD=0 # Count of errors found
|
ERRORS_FOUND_JAVASCRIPT_STANDARD=0 # Count of errors found
|
||||||
|
@ -442,6 +450,57 @@ DetectOpenAPIFile()
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
################################################################################
|
||||||
|
#### Function DetectCloudFormationFile #########################################
|
||||||
|
DetectCloudFormationFile()
|
||||||
|
{
|
||||||
|
################
|
||||||
|
# Pull in Vars #
|
||||||
|
################
|
||||||
|
FILE="$1" # File that we need to validate
|
||||||
|
|
||||||
|
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html
|
||||||
|
# AWSTemplateFormatVersion is optional
|
||||||
|
#######################################
|
||||||
|
# Check if file has AWS Template info #
|
||||||
|
#######################################
|
||||||
|
if grep 'AWSTemplateFormatVersion' "$FILE" > /dev/null; then
|
||||||
|
# Found it
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
###################################################
|
||||||
|
# Check if file has AWSTemplateFormatVersion info #
|
||||||
|
###################################################
|
||||||
|
if shyaml --quiet get-type AWSTemplateFormatVersion > /dev/null < "$FILE"; then
|
||||||
|
# Found it
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# check if file has resources #
|
||||||
|
###############################
|
||||||
|
if jq -e 'has("Resources")' > /dev/null 2>&1 < "$FILE"; then
|
||||||
|
# Check if AWS Alexa or custom
|
||||||
|
if jq ".Resources[].Type" 2>/dev/null | grep -q -E "(AWS|Alexa|Custom)" < "$FILE"; then
|
||||||
|
# Found it
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################
|
||||||
|
# See if it contains resources #
|
||||||
|
################################
|
||||||
|
if shyaml values-0 Resources | grep -q -E "Type: (AWS|Alexa|Custom)" < "$FILE"; then
|
||||||
|
# Found it
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# No identifiers of a CFN template found #
|
||||||
|
##########################################
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#### Function GetGitHubVars ####################################################
|
#### Function GetGitHubVars ####################################################
|
||||||
|
@ -645,6 +704,7 @@ Footer()
|
||||||
[ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] || \
|
[ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] || \
|
||||||
[ "$ERRORS_FOUND_RUBY" -ne 0 ] || \
|
[ "$ERRORS_FOUND_RUBY" -ne 0 ] || \
|
||||||
[ "$ERRORS_FOUND_CSS" -ne 0 ] || \
|
[ "$ERRORS_FOUND_CSS" -ne 0 ] || \
|
||||||
|
[ "$ERRORS_FOUND_CFN" -ne 0 ] || \
|
||||||
[ "$ERRORS_FOUND_ENV" -ne 0 ] || \
|
[ "$ERRORS_FOUND_ENV" -ne 0 ] || \
|
||||||
[ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || \
|
[ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || \
|
||||||
[ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || \
|
[ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || \
|
||||||
|
@ -715,6 +775,8 @@ GetLinterRules "$TERRAFORM_FILE_NAME" "$TERRAFORM_LINTER_RULES"
|
||||||
GetLinterRules "$POWERSHELL_FILE_NAME" "$POWERSHELL_LINTER_RULES"
|
GetLinterRules "$POWERSHELL_FILE_NAME" "$POWERSHELL_LINTER_RULES"
|
||||||
# Get CSS rules
|
# Get CSS rules
|
||||||
GetLinterRules "$CSS_FILE_NAME" "$CSS_LINTER_RULES"
|
GetLinterRules "$CSS_FILE_NAME" "$CSS_LINTER_RULES"
|
||||||
|
# Get CFN rules
|
||||||
|
GetLinterRules "$CFN_FILE_NAME" "$CFN_LINTER_RULES"
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
# Check if were in verbose mode #
|
# Check if were in verbose mode #
|
||||||
|
@ -813,6 +875,17 @@ if [ "$VALIDATE_PYTHON" == "true" ]; then
|
||||||
LintCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" "${FILE_ARRAY_PYTHON[@]}"
|
LintCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" "${FILE_ARRAY_PYTHON[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###############
|
||||||
|
# CFN LINTING #
|
||||||
|
###############
|
||||||
|
if [ "$VALIDATE_CLOUDFORMATION" == "true" ]; then
|
||||||
|
#################################
|
||||||
|
# Lint the CloudFormation files #
|
||||||
|
#################################
|
||||||
|
# LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY"
|
||||||
|
LintCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" "${FILE_ARRAY_CFN[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
################
|
################
|
||||||
# PERL LINTING #
|
# PERL LINTING #
|
||||||
################
|
################
|
||||||
|
@ -927,6 +1000,7 @@ if [ "$VALIDATE_TYPESCRIPT_ES" == "true" ]; then
|
||||||
#############################
|
#############################
|
||||||
LintCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" "${FILE_ARRAY_TYPESCRIPT_ES[@]}"
|
LintCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" "${FILE_ARRAY_TYPESCRIPT_ES[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# TYPESCRIPT LINTING #
|
# TYPESCRIPT LINTING #
|
||||||
######################
|
######################
|
||||||
|
|
|
@ -209,10 +209,11 @@ function TestCodebase()
|
||||||
####################
|
####################
|
||||||
# Pull in the vars #
|
# Pull in the vars #
|
||||||
####################
|
####################
|
||||||
FILE_TYPE="$1" # Pull the variable and remove from array path (Example: JSON)
|
FILE_TYPE="$1" # Pull the variable and remove from array path (Example: JSON)
|
||||||
LINTER_NAME="$2" # Pull the variable and remove from array path (Example: jsonlint)
|
LINTER_NAME="$2" # Pull the variable and remove from array path (Example: jsonlint)
|
||||||
LINTER_COMMAND="$3" # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file)
|
LINTER_COMMAND="$3" # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file)
|
||||||
FILE_EXTENSIONS="$4" # Pull the variable and remove from array path (Example: *.json)
|
FILE_EXTENSIONS="$4" # Pull the variable and remove from array path (Example: *.json)
|
||||||
|
INDVIDUAL_TEST_FOLDER="$5" # Folder for specific tests
|
||||||
|
|
||||||
################
|
################
|
||||||
# print header #
|
# print header #
|
||||||
|
@ -274,7 +275,7 @@ function TestCodebase()
|
||||||
# Get list of all files to lint #
|
# Get list of all files to lint #
|
||||||
#################################
|
#################################
|
||||||
# shellcheck disable=SC2207,SC2086
|
# shellcheck disable=SC2207,SC2086
|
||||||
LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" 2>&1))
|
LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find "$INDVIDUAL_TEST_FOLDER" -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" 2>&1))
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
# Set IFS back to default #
|
# Set IFS back to default #
|
||||||
|
@ -442,31 +443,33 @@ function RunTestCases()
|
||||||
#######################
|
#######################
|
||||||
# Test case languages #
|
# Test case languages #
|
||||||
#######################
|
#######################
|
||||||
TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$"
|
# TestCodebase "Language" "Linter" "Linter-command" "Regex to find files" "Test Folder"
|
||||||
TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$"
|
TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$" "yml"
|
||||||
TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$"
|
TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" "json"
|
||||||
TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$"
|
TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$" "xml"
|
||||||
TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$"
|
TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$" "markdown"
|
||||||
TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$"
|
TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$" "shell"
|
||||||
TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$"
|
TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" "python"
|
||||||
TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$"
|
TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$" "perl"
|
||||||
TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$"
|
TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$" "php"
|
||||||
TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$"
|
TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$" "ruby"
|
||||||
TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$"
|
TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$" "golang"
|
||||||
TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$"
|
TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" "coffeescript"
|
||||||
TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard $JAVASCRIPT_STANDARD_LINTER_RULES" ".*\.\(js\)\$"
|
TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" "javascript"
|
||||||
TestCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$"
|
TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard $JAVASCRIPT_STANDARD_LINTER_RULES" ".*\.\(js\)\$" "javascript"
|
||||||
TestCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$"
|
TestCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" "typescript"
|
||||||
TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$"
|
TestCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$" "typescript"
|
||||||
TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint"
|
TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$" "docker"
|
||||||
TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$"
|
TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint" "ansible"
|
||||||
TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$"
|
TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" "terraform"
|
||||||
TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$"
|
TestCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" "cfn"
|
||||||
TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$"
|
TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "powershell"
|
||||||
TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$"
|
TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "css"
|
||||||
TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$"
|
TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" "env"
|
||||||
TestCodebase "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$"
|
TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "clojure"
|
||||||
TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$"
|
TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "kotlin"
|
||||||
|
TestCodebase "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$" "protobuf"
|
||||||
|
TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" "openapi"
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# Footer prints #
|
# Footer prints #
|
||||||
|
|
Loading…
Reference in a new issue