From f1d1b1cbe2de41c85a42a1f43f8a61b2cbc35c90 Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Fri, 19 Jun 2020 18:41:19 +0200 Subject: [PATCH 1/9] Add AWS CloudFormation templates linting --- .automation/test/cfn/README.md | 13 ++++ .automation/test/cfn/cfn_bad_1.json | 35 +++++++++++ .automation/test/cfn/cfn_bad_2.yaml | 23 +++++++ .automation/test/cfn/cfn_good_1.json | 35 +++++++++++ .automation/test/cfn/cfn_good_2.yaml | 23 +++++++ .github/linters/.cfnlintrc.yml | 2 + Dockerfile | 2 +- README.md | 50 ++++++++-------- TEMPLATES/.cfnlintrc.yml | 2 + docs/disabling-linters.md | 37 ++++++++++++ lib/linter.sh | 90 +++++++++++++++++++++++++++- 11 files changed, 285 insertions(+), 27 deletions(-) create mode 100644 .automation/test/cfn/README.md create mode 100644 .automation/test/cfn/cfn_bad_1.json create mode 100644 .automation/test/cfn/cfn_bad_2.yaml create mode 100644 .automation/test/cfn/cfn_good_1.json create mode 100644 .automation/test/cfn/cfn_good_2.yaml create mode 100644 .github/linters/.cfnlintrc.yml create mode 100644 TEMPLATES/.cfnlintrc.yml diff --git a/.automation/test/cfn/README.md b/.automation/test/cfn/README.md new file mode 100644 index 00000000..ace786b4 --- /dev/null +++ b/.automation/test/cfn/README.md @@ -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. diff --git a/.automation/test/cfn/cfn_bad_1.json b/.automation/test/cfn/cfn_bad_1.json new file mode 100644 index 00000000..926f6b89 --- /dev/null +++ b/.automation/test/cfn/cfn_bad_1.json @@ -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" + } + ] + } + } + } +} diff --git a/.automation/test/cfn/cfn_bad_2.yaml b/.automation/test/cfn/cfn_bad_2.yaml new file mode 100644 index 00000000..70ae5ee6 --- /dev/null +++ b/.automation/test/cfn/cfn_bad_2.yaml @@ -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' diff --git a/.automation/test/cfn/cfn_good_1.json b/.automation/test/cfn/cfn_good_1.json new file mode 100644 index 00000000..dc944bca --- /dev/null +++ b/.automation/test/cfn/cfn_good_1.json @@ -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" + } + ] + } + } + } +} diff --git a/.automation/test/cfn/cfn_good_2.yaml b/.automation/test/cfn/cfn_good_2.yaml new file mode 100644 index 00000000..ae8fdb83 --- /dev/null +++ b/.automation/test/cfn/cfn_good_2.yaml @@ -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' diff --git a/.github/linters/.cfnlintrc.yml b/.github/linters/.cfnlintrc.yml new file mode 100644 index 00000000..545080a4 --- /dev/null +++ b/.github/linters/.cfnlintrc.yml @@ -0,0 +1,2 @@ +include_checks: +- I diff --git a/Dockerfile b/Dockerfile index d0c3a70b..e332654c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,7 +53,7 @@ RUN mkdir -p /opt/microsoft/powershell/7 \ # Run Pip3 Installs # ##################### RUN pip3 --no-cache-dir install --upgrade --no-cache-dir \ - yamllint pylint yq + yamllint pylint yq cfn-lint #################### # Run NPM Installs # diff --git a/README.md b/README.md index 1b9b7e09..fb3ceb35 100644 --- a/README.md +++ b/README.md @@ -32,30 +32,31 @@ The design of the **Super-Linter** is currently to allow linting to occur in **G Developers on **GitHub** can call the **GitHub Action** to lint their code base with the following list of linters: -| *Language* | *Linter* | -| --- | --- | -| **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) | -| **CSS** | [stylelint](https://stylelint.io/) | -| **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) | -| **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | -| **Dockerfile** | [dockerfilelint](https://github.com/replicatedhq/dockerfilelint.git) | -| **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) | -| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | -| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | -| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) | -| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) | -| **PHP** | [PHP](https://www.php.net/) | -| **Python3** | [pylint](https://www.pylint.org/) | -| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | -| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) | -| **Terraform** | [tflint](https://github.com/terraform-linters/tflint) | -| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | -| **XML** | [LibXML](http://xmlsoft.org/) | -| **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) | +| *Language* | *Linter* | +| --- | --- | +| **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) | +| **CSS** | [stylelint](https://stylelint.io/) | +| **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) | +| **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | +| **Dockerfile** | [dockerfilelint](https://github.com/replicatedhq/dockerfilelint.git) | +| **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) | +| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | +| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | +| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) | +| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) | +| **PHP** | [PHP](https://www.php.net/) | +| **Python3** | [pylint](https://www.pylint.org/) | +| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | +| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) | +| **Terraform** | [tflint](https://github.com/terraform-linters/tflint) | +| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | +| **XML** | [LibXML](http://xmlsoft.org/) | +| **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) | +| **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint/) | ## How to use To use this **GitHub** Action you will need to complete the following: @@ -167,6 +168,7 @@ and won't run anything unexpected. | **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_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. | | **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. | | **DISABLE_ERRORS** | `false` | Flag to have the linter complete with exit code 0 even if errors were detected. | diff --git a/TEMPLATES/.cfnlintrc.yml b/TEMPLATES/.cfnlintrc.yml new file mode 100644 index 00000000..545080a4 --- /dev/null +++ b/TEMPLATES/.cfnlintrc.yml @@ -0,0 +1,2 @@ +include_checks: +- I diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index 408eba19..cc8071bf 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -7,6 +7,7 @@ Below are examples and documentation for each language and the various methods t - [Shell](#shell) - [Ansible](#ansible) - [YAML](#yaml) +- [AWS CloudFormation templates](#cfn) - [Python](#python3) - [JSON](#json) - [Markdown](#markdown) @@ -238,6 +239,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 - [jsonlint](https://github.com/zaach/jsonlint) diff --git a/lib/linter.sh b/lib/linter.sh index 6226455c..65f68b93 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -22,6 +22,9 @@ MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to th # Python Vars PYTHON_FILE_NAME='.python-lint' # Name of the file 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_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 @@ -67,7 +70,8 @@ CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" "pylint" "perl" "rubocop" "coffeelint" "eslint" "standard" "ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint" - "stylelint" "dotenv-linter" "powershell" "ktlint" "clj-kondo" "spectral") + "stylelint" "dotenv-linter" "powershell" "ktlint" "clj-kondo" "spectral" + "cfn-lint") ############################# # Language array for prints # @@ -75,7 +79,7 @@ LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'PHP' 'RUBY' 'PYTHON' 'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES' 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM' - 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'CLOJURE' 'OPENAPI') + 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'CLOJURE' 'OPENAPI' 'CFN') ################### # GitHub ENV Vars # @@ -94,6 +98,7 @@ VALIDATE_BASH="${VALIDATE_BASH}" # Boolean to validate lang VALIDATE_PERL="${VALIDATE_PERL}" # Boolean to validate language VALIDATE_PHP="${VALIDATE_PHP}" # 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_COFFEE="${VALIDATE_COFFEE}" # Boolean to validate language VALIDATE_ANSIBLE="${VALIDATE_ANSIBLE}" # Boolean to validate language @@ -146,6 +151,7 @@ FILE_ARRAY_PERL=() # Array of files to check FILE_ARRAY_PHP=() # Array of files to check FILE_ARRAY_RUBY=() # 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_JAVASCRIPT_ES=() # Array of files to check FILE_ARRAY_JAVASCRIPT_STANDARD=() # Array of files to check @@ -173,6 +179,7 @@ ERRORS_FOUND_PERL=0 # Count of errors found ERRORS_FOUND_PHP=0 # Count of errors found ERRORS_FOUND_RUBY=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_ANSIBLE=0 # Count of errors found ERRORS_FOUND_JAVASCRIPT_STANDARD=0 # Count of errors found @@ -605,6 +612,17 @@ DetectOpenAPIFile() fi } +#### Function DetectCloudFormationFile ######################################### +# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html +DetectCloudFormationFile() +{ + if grep 'AWSTemplateFormatVersion' "${1}" > /dev/null; then + return 0 + else + return 1 + fi +} + ################################################################################ #### Function GetGitHubVars #################################################### GetGitHubVars() @@ -791,6 +809,7 @@ GetValidationInfo() VALIDATE_PERL=$(echo "$VALIDATE_PERL" | awk '{print tolower($0)}') VALIDATE_PHP=$(echo "$VALIDATE_PHP" | awk '{print tolower($0)}') VALIDATE_PYTHON=$(echo "$VALIDATE_PYTHON" | awk '{print tolower($0)}') + VALIDATE_CLOUDFORMATION=$(echo "$VALIDATE_CLOUDFORMATION" | awk '{print tolower($0)}') VALIDATE_RUBY=$(echo "$VALIDATE_RUBY" | awk '{print tolower($0)}') VALIDATE_COFFEE=$(echo "$VALIDATE_COFFEE" | awk '{print tolower($0)}') VALIDATE_ANSIBLE=$(echo "$VALIDATE_ANSIBLE" | awk '{print tolower($0)}') @@ -820,6 +839,7 @@ GetValidationInfo() -n "$VALIDATE_PERL" || \ -n "$VALIDATE_PHP" || \ -n "$VALIDATE_PYTHON" || \ + -n "$VALIDATE_CLOUDFORMATION" || \ -n "$VALIDATE_RUBY" || \ -n "$VALIDATE_COFFEE" || \ -n "$VALIDATE_ANSIBLE" || \ @@ -951,6 +971,20 @@ GetValidationInfo() VALIDATE_PYTHON="true" fi + ############################################## + # Validate if we should check Cloudformation # + ############################################## + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_CLOUDFORMATION" ]]; then + # CFN flag was not set - default to false + VALIDATE_CLOUDFORMATION="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_CLOUDFORMATION="true" + fi + #################################### # Validate if we should check RUBY # #################################### @@ -1218,6 +1252,11 @@ GetValidationInfo() else PRINT_ARRAY+=("- Excluding [PYTHON] files in code base...") fi + if [[ "$VALIDATE_CLOUDFORMATION" == "true" ]]; then + PRINT_ARRAY+=("- Validating [CFN] files in code base...") + else + PRINT_ARRAY+=("- Excluding [CFN] files in code base...") + fi if [[ "$VALIDATE_RUBY" == "true" ]]; then PRINT_ARRAY+=("- Validating [RUBY] files in code base...") else @@ -1510,6 +1549,18 @@ BuildFileList() ########################################################## READ_ONLY_CHANGE_FLAG=1 ##################### + # Get the CFN files # + ##################### + elif [ "$FILE_TYPE" == "json" ] || [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ] && DetectCloudFormationFile "$FILE"; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_CFN+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ##################### # Get the XML files # ##################### elif [ "$FILE_TYPE" == "xml" ]; then @@ -1924,6 +1975,17 @@ LintCodebase() continue fi + # don't test normal json/yaml files wih cfn-lint + if [ "$LINTER_NAME" == "cfn-lint" ] && ! DetectCloudFormationFile "$GITHUB_WORKSPACE/$FILE"; then + # TODO: PRINT_ARRAY still contains "Linting [CFN] files..." + continue + fi + + # don't test CloudFormation files with {json,yaml}lint + if [ "$LINTER_NAME" == "jsonlint" ] || [ "$LINTER_NAME" == "yamllint" ] && DetectCloudFormationFile "$GITHUB_WORKSPACE/$FILE"; then + continue + fi + ############## # File print # ############## @@ -2054,6 +2116,15 @@ TestCodebase() # Set IFS back to default # ########################### IFS="$DEFAULT_IFS" + + # don't check yaml/json files with cnf-lint + # don't check CloudFormation files with json/yaml linters + if [ "$FILE_TYPE" == "CFN" ]; then + LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" ! -path "*./json*" ! -path "*./yml*" 2>&1)) + fi + if [ "$FILE_TYPE" == "JSON" ] || [ "$FILE_TYPE" == "YML" ]; then + LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" ! -path "*./cfn*" 2>&1)) + fi fi ################## @@ -2240,6 +2311,7 @@ Footer() [ "$ERRORS_FOUND_PERL" -ne 0 ] || \ [ "$ERRORS_FOUND_PHP" -ne 0 ] || \ [ "$ERRORS_FOUND_PYTHON" -ne 0 ] || \ + [ "$ERRORS_FOUND_CFN" -ne 0 ] || \ [ "$ERRORS_FOUND_COFFEESCRIPT" -ne 0 ] || \ [ "$ERRORS_FOUND_ANSIBLE" -ne 0 ] || \ [ "$ERRORS_FOUND_JAVASCRIPT_ES" -ne 0 ] || \ @@ -2319,6 +2391,7 @@ RunTestCases() TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" + TestCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" ################# # Footer prints # @@ -2357,6 +2430,8 @@ GetLinterRules "$YAML_FILE_NAME" "$YAML_LINTER_RULES" GetLinterRules "$MD_FILE_NAME" "$MD_LINTER_RULES" # Get Python rules GetLinterRules "$PYTHON_FILE_NAME" "$PYTHON_LINTER_RULES" +# Get CloudFormation rules +GetLinterRules "$CFN_FILE_NAME" "$CFN_LINTER_RULES" # Get Ruby rules GetLinterRules "$RUBY_FILE_NAME" "$RUBY_LINTER_RULES" # Get Coffeescript rules @@ -2475,6 +2550,17 @@ if [ "$VALIDATE_PYTHON" == "true" ]; then LintCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES -E" ".*\.\(py\)\$" "${FILE_ARRAY_PYTHON[@]}" 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 # ################ From eb8cf40bf500dfd3a8347bd390cf9aec1dd458ea Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Fri, 26 Jun 2020 21:43:44 +0200 Subject: [PATCH 2/9] Improve template detection --- .automation/test/cfn/cfn_bad_3.json | 16 ++++++++++++++++ .automation/test/cfn/cfn_good_3.json | 16 ++++++++++++++++ Dockerfile | 2 +- lib/linter.sh | 18 ++++++++++++++++-- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 .automation/test/cfn/cfn_bad_3.json create mode 100644 .automation/test/cfn/cfn_good_3.json diff --git a/.automation/test/cfn/cfn_bad_3.json b/.automation/test/cfn/cfn_bad_3.json new file mode 100644 index 00000000..37ae6b3a --- /dev/null +++ b/.automation/test/cfn/cfn_bad_3.json @@ -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" + } + } + } +} diff --git a/.automation/test/cfn/cfn_good_3.json b/.automation/test/cfn/cfn_good_3.json new file mode 100644 index 00000000..f8602d7a --- /dev/null +++ b/.automation/test/cfn/cfn_good_3.json @@ -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" + } + } + } +} diff --git a/Dockerfile b/Dockerfile index e332654c..9806ee49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,7 +53,7 @@ RUN mkdir -p /opt/microsoft/powershell/7 \ # Run Pip3 Installs # ##################### RUN pip3 --no-cache-dir install --upgrade --no-cache-dir \ - yamllint pylint yq cfn-lint + yamllint pylint yq cfn-lint shyaml #################### # Run NPM Installs # diff --git a/lib/linter.sh b/lib/linter.sh index 65f68b93..bf4a78e4 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -616,11 +616,25 @@ DetectOpenAPIFile() # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html DetectCloudFormationFile() { + # AWSTemplateFormatVersion is optional + # grep -E '("|)AWSTemplateFormatVersion("|):' if grep 'AWSTemplateFormatVersion' "${1}" > /dev/null; then return 0 - else - return 1 fi + if cat "${1}" | shyaml --quiet get-type AWSTemplateFormatVersion > /dev/null; then + return 0 + fi + + if cat "${1}" | jq -e 'has("Resources")' > /dev/null 2>&1; then + if cat "${1}" | jq ".Resources[].Type" 2>/dev/null | grep -q -E "(AWS|Alexa|Custom)"; then + return 0 + fi + fi + if cat "${1}" | shyaml values-0 Resources | grep -q -E "Type: (AWS|Alexa|Custom)"; then + return 0 + fi + + return 1 } ################################################################################ From 2a96444f7554f04f3dd5bf766ef6ffc3a7e1efd4 Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Fri, 26 Jun 2020 22:06:35 +0200 Subject: [PATCH 3/9] Add final yaml test cases --- .automation/test/cfn/cfn_bad_4.yaml | 10 ++++++++++ .automation/test/cfn/cfn_good_4.yaml | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 .automation/test/cfn/cfn_bad_4.yaml create mode 100644 .automation/test/cfn/cfn_good_4.yaml diff --git a/.automation/test/cfn/cfn_bad_4.yaml b/.automation/test/cfn/cfn_bad_4.yaml new file mode 100644 index 00000000..79a8e193 --- /dev/null +++ b/.automation/test/cfn/cfn_bad_4.yaml @@ -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 diff --git a/.automation/test/cfn/cfn_good_4.yaml b/.automation/test/cfn/cfn_good_4.yaml new file mode 100644 index 00000000..52d3a8c8 --- /dev/null +++ b/.automation/test/cfn/cfn_good_4.yaml @@ -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 From 234f8f93634100b283dbf1b66dcde9555def9625 Mon Sep 17 00:00:00 2001 From: Guillaume Delacour Date: Fri, 26 Jun 2020 22:09:44 +0200 Subject: [PATCH 4/9] Remove unnecessary comment --- lib/linter.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/linter.sh b/lib/linter.sh index bf4a78e4..f297295c 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -617,7 +617,6 @@ DetectOpenAPIFile() DetectCloudFormationFile() { # AWSTemplateFormatVersion is optional - # grep -E '("|)AWSTemplateFormatVersion("|):' if grep 'AWSTemplateFormatVersion' "${1}" > /dev/null; then return 0 fi From 5d3c4a99c136d1b081cfaa5456df447a5497d7eb Mon Sep 17 00:00:00 2001 From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com> Date: Mon, 29 Jun 2020 14:38:24 -0500 Subject: [PATCH 5/9] adding cloud formation --- lib/buildFileList.sh | 37 +++++++++++++++++++++++++++++-------- lib/linter.sh | 5 +++-- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/buildFileList.sh b/lib/buildFileList.sh index d39f7a64..dde4c70c 100755 --- a/lib/buildFileList.sh +++ b/lib/buildFileList.sh @@ -100,18 +100,26 @@ function BuildFileList() #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 # ################################ - FILE_ARRAY_YML+=("$FILE") - ############################ - # Check if file is OpenAPI # - ############################ - if DetectOpenAPIFile "$FILE"; then - FILE_ARRAY_OPENAPI+=("$FILE") + FILE_ARRAY_CFN+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + + ##################################### + # 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 # @@ -129,8 +137,21 @@ function BuildFileList() # Check if file is OpenAPI # ############################ if DetectOpenAPIFile "$FILE"; then + ################################ + # Append the file to the array # + ################################ FILE_ARRAY_OPENAPI+=("$FILE") 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 # ########################################################## diff --git a/lib/linter.sh b/lib/linter.sh index 11431dcd..62d0752f 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -450,11 +450,11 @@ DetectOpenAPIFile() return 1 fi } - +################################################################################ #### Function DetectCloudFormationFile ######################################### -# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html DetectCloudFormationFile() { + # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html # AWSTemplateFormatVersion is optional if grep 'AWSTemplateFormatVersion' "${1}" > /dev/null; then return 0 @@ -677,6 +677,7 @@ Footer() [ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] || \ [ "$ERRORS_FOUND_RUBY" -ne 0 ] || \ [ "$ERRORS_FOUND_CSS" -ne 0 ] || \ + [ "$ERRORS_FOUND_CFN" -ne 0 ] || \ [ "$ERRORS_FOUND_ENV" -ne 0 ] || \ [ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || \ [ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || \ From b3e44a5c7e4c8893e58eb7123d687b7140dc6179 Mon Sep 17 00:00:00 2001 From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com> Date: Mon, 29 Jun 2020 14:49:20 -0500 Subject: [PATCH 6/9] made it better to read --- lib/linter.sh | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/lib/linter.sh b/lib/linter.sh index 62d0752f..29e55d2f 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -454,24 +454,51 @@ DetectOpenAPIFile() #### 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 - if grep 'AWSTemplateFormatVersion' "${1}" > /dev/null; then - return 0 - fi - if cat "${1}" | shyaml --quiet get-type AWSTemplateFormatVersion > /dev/null; then + ####################################### + # Check if file has AWS Template info # + ####################################### + if grep 'AWSTemplateFormatVersion' "$FILE" > /dev/null; then + # Found it return 0 fi - if cat "${1}" | jq -e 'has("Resources")' > /dev/null 2>&1; then - if cat "${1}" | jq ".Resources[].Type" 2>/dev/null | grep -q -E "(AWS|Alexa|Custom)"; then + ################################################### + # 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 - if cat "${1}" | shyaml values-0 Resources | grep -q -E "Type: (AWS|Alexa|Custom)"; then + + ################################ + # 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 } From ae8836cfecef72845aef91942d62d9e05f8b6085 Mon Sep 17 00:00:00 2001 From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:22:52 -0500 Subject: [PATCH 7/9] making testing better --- lib/linter.sh | 2 ++ lib/worker.sh | 63 +++++++++++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/lib/linter.sh b/lib/linter.sh index 29e55d2f..1de5282a 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -775,6 +775,8 @@ GetLinterRules "$TERRAFORM_FILE_NAME" "$TERRAFORM_LINTER_RULES" GetLinterRules "$POWERSHELL_FILE_NAME" "$POWERSHELL_LINTER_RULES" # Get CSS rules GetLinterRules "$CSS_FILE_NAME" "$CSS_LINTER_RULES" +# Get CFN rules +GetLinterRules "$CFN_FILE_NAME" "$CFN_LINTER_RULES" ################################# # Check if were in verbose mode # diff --git a/lib/worker.sh b/lib/worker.sh index 1b879768..287215dc 100755 --- a/lib/worker.sh +++ b/lib/worker.sh @@ -209,10 +209,11 @@ function TestCodebase() #################### # Pull in the vars # #################### - 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_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_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_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) + INDVIDUAL_TEST_FOLDER="$5" # Folder for specific tests ################ # print header # @@ -274,7 +275,7 @@ function TestCodebase() # Get list of all files to lint # ################################# # 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 # @@ -442,31 +443,33 @@ function RunTestCases() ####################### # Test case languages # ####################### - TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$" - TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" - TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$" - TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$" - TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$" - TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" - TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$" - TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$" - TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$" - TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$" - TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" - TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" - TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard $JAVASCRIPT_STANDARD_LINTER_RULES" ".*\.\(js\)\$" - TestCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" - TestCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$" - TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$" - TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint" - TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" - TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" - TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" - TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" - TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" - TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" - TestCodebase "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$" - TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" + # TestCodebase "Language" "Linter" "Linter-command" "Regex to find files" "Test Folder" + TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$" "yml" + TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" "json" + TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$" "xml" + TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$" "markdown" + TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$" "shell" + TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" "python" + TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$" "perl" + TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$" "php" + TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$" "ruby" + TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$" "golang" + TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" "coffeescript" + TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" "javascript" + TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard $JAVASCRIPT_STANDARD_LINTER_RULES" ".*\.\(js\)\$" "javascript" + TestCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" "typescript" + TestCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$" "typescript" + TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$" "docker" + TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint" "ansible" + TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" "terraform" + TestCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" "cfn" + TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "powershell" + TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "css" + TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" "env" + TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "clojure" + 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 # From 24d5a77532d7d04463b93a1c7041f61c273b3503 Mon Sep 17 00:00:00 2001 From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:25:05 -0500 Subject: [PATCH 8/9] put in order to mack the Z happy --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4feb70f8..aecd7511 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,22 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | *Language* | *Linter* | | --- | --- | | **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/) | | **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) | | **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | | **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) | | **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | | **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | +| **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) | | **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) | | **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/) | | **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | | **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) | @@ -52,13 +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/) | | **XML** | [LibXML](http://xmlsoft.org/) | | **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) | -| **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint/) | - ## How to use To use this **GitHub** Action you will need to complete the following: From d12f5b541f998370aa9cd172e424c3e1207c4137 Mon Sep 17 00:00:00 2001 From: Lucas Gravley <29484535+admiralAwkbar@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:38:33 -0500 Subject: [PATCH 9/9] fixed spacing --- lib/linter.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/linter.sh b/lib/linter.sh index 1de5282a..e4d64c3c 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -798,6 +798,7 @@ if [[ "$TEST_CASE_RUN" != "false" ]]; then # Code will exit from inside this loop RunTestCases fi + ############################################# # check flag for validation of all codebase # ############################################# @@ -999,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[@]}" fi + ###################### # TYPESCRIPT LINTING # ######################