Merge pull request #369 from krowlandson/arm-ttk

Add support for Azure Resource Manager (ARM) linting with [arm-ttk]
This commit is contained in:
Lukas Gravley 2020-07-06 08:54:03 -05:00 committed by GitHub
commit 13427e3b67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 329 additions and 65 deletions

View file

@ -0,0 +1,13 @@
# ARM Test Cases
This folder holds the test cases for **Azure Resource Manager (ARM)**.
## 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.

View file

@ -0,0 +1,53 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "",
"parameters": {
"Network.Config": {
"type": "object",
"metadata": {
"description": "Properties object for the Virtual Network"
}
}
},
"variables": {
"Network.Name": "[parameters('Network.Config').name]",
"Network.Location": "[parameters('Network.Config').location]",
"Network.Tags": "[parameters('Network.Config').tags]",
"Network.Properties.AddressSpace.AddressPrefixes": "[parameters('Network.Config').addressPrefixes]",
"Network.Properties.DhcpOptions.DnsServers": "[parameters('Network.Config').dnsServers]",
"copy": [
{
"name": "Network.Properties.Subnets",
"count": "[length(parameters('Network.Config').subnetConfig)]",
"input": {
"name": "[concat(parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].aksId,'-',parameters('Network.Config').locationId)]",
"properties": "[parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].properties]"
}
}
],
"Test.Blank.Variable": []
},
"resources": [
{
"name": "[variables('Network.Name')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-12-01",
"tags": "[variables('Network.Tags')]",
"properties": {
"addressSpace": {
"addressPrefixes": "[variables('Network.Properties.AddressSpace.AddressPrefixes')]"
},
"dhcpOptions": {
"dnsServers": "[variables('Network.Properties.DhcpOptions.DnsServers')]"
},
"subnets": "[variables('Network.Properties.Subnets')]"
}
}
],
"outputs": {
"state": {
"type": "object",
"value": "[reference(resourceId('Microsoft.Network/virtualNetworks',variables('Network.Name')), '2019-12-01', 'Full')]"
}
}
}

View file

@ -0,0 +1,53 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"Network.Config": {
"type": "object",
"metadata": {
"description": "Properties object for the Virtual Network"
}
}
},
"variables": {
"Network.Name": "[parameters('Network.Config').name]",
"Network.Location": "[parameters('Network.Config').location]",
"Network.Tags": "[parameters('Network.Config').tags]",
"Network.Properties.AddressSpace.AddressPrefixes": "[parameters('Network.Config').addressPrefixes]",
"Network.Properties.DhcpOptions.DnsServers": "[parameters('Network.Config').dnsServers]",
"copy": [
{
"name": "Network.Properties.Subnets",
"count": "[length(parameters('Network.Config').subnetConfig)]",
"input": {
"name": "[concat(parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].aksId,'-',parameters('Network.Config').locationId)]",
"properties": "[parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].properties]"
}
}
]
},
"resources": [
{
"name": "[variables('Network.Name')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-12-01",
"location": "[variables('Network.Location')]",
"tags": "[variables('Network.Tags')]",
"properties": {
"addressSpace": {
"addressPrefixes": "[variables('Network.Properties.AddressSpace.AddressPrefixes')]"
},
"dhcpOptions": {
"dnsServers": "[variables('Network.Properties.DhcpOptions.DnsServers')]"
},
"subnets": "[variables('Network.Properties.Subnets')]"
}
}
],
"outputs": {
"state": {
"type": "object",
"value": "[reference(resourceId('Microsoft.Network/virtualNetworks',variables('Network.Name')), '2019-12-01', 'Full')]"
}
}
}

View file

@ -18,6 +18,21 @@ LABEL com.github.actions.name="GitHub Super-Linter" \
com.github.actions.color="red" \ com.github.actions.color="red" \
maintainer="GitHub DevOps <github_devops@github.com>" maintainer="GitHub DevOps <github_devops@github.com>"
################################
# Set ARG values used in Build #
################################
# PowerShell & PSScriptAnalyzer
ARG PWSH_VERSION='latest'
ARG PWSH_DIRECTORY='/opt/microsoft/powershell'
ARG PSSA_VERSION='latest'
# arm-ttk
ARG ARM_TTK_URI='https://github.com/Azure/arm-ttk.git'
ARG ARM_TTK_DIRECTORY='/opt/microsoft/arm-ttk'
# clj-kondo
ARG CLJ_KONDO_VERSION='2020.06.21'
# Go Linter
ARG GO_VERSION='v1.27.0'
#################### ####################
# Run APK installs # # Run APK installs #
#################### ####################
@ -40,9 +55,6 @@ RUN apk add --no-cache \
# Reference: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7 # Reference: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7
# Slightly modified to always retrieve latest stable Powershell version # Slightly modified to always retrieve latest stable Powershell version
# If changing PWSH_VERSION='latest' to a specific version, use format PWSH_VERSION='tags/v7.0.2' # If changing PWSH_VERSION='latest' to a specific version, use format PWSH_VERSION='tags/v7.0.2'
ARG PWSH_VERSION='latest'
ARG PWSH_DIRECTORY='/opt/microsoft/powershell'
ARG PSSA_VERSION='latest'
RUN mkdir -p ${PWSH_DIRECTORY} \ RUN mkdir -p ${PWSH_DIRECTORY} \
&& curl -s https://api.github.com/repos/powershell/powershell/releases/${PWSH_VERSION} \ && curl -s https://api.github.com/repos/powershell/powershell/releases/${PWSH_VERSION} \
| grep browser_download_url \ | grep browser_download_url \
@ -50,9 +62,19 @@ RUN mkdir -p ${PWSH_DIRECTORY} \
| cut -d '"' -f 4 \ | cut -d '"' -f 4 \
| xargs -n 1 wget -O - \ | xargs -n 1 wget -O - \
| tar -xzC ${PWSH_DIRECTORY} \ | tar -xzC ${PWSH_DIRECTORY} \
&& ln -s ${PWSH_DIRECTORY}/pwsh /usr/bin/pwsh -f \ && ln -sf ${PWSH_DIRECTORY}/pwsh /usr/bin/pwsh \
&& pwsh -c 'Install-Module -Name PSScriptAnalyzer -RequiredVersion ${PSSA_VERSION} -Scope AllUsers -Force' && pwsh -c 'Install-Module -Name PSScriptAnalyzer -RequiredVersion ${PSSA_VERSION} -Scope AllUsers -Force'
#############################################################
# Install Azure Resource Manager Template Toolkit (arm-ttk) #
#############################################################
# Depends on PowerShell
# Reference https://github.com/Azure/arm-ttk
# Reference https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-toolkit
ENV ARM_TTK_PSD1="${ARM_TTK_DIRECTORY}/arm-ttk/arm-ttk.psd1"
RUN git clone "${ARM_TTK_URI}" "${ARM_TTK_DIRECTORY}" \
&& ln -sTf "$ARM_TTK_PSD1" /usr/bin/arm-ttk
##################### #####################
# Run Pip3 Installs # # Run Pip3 Installs #
##################### #####################
@ -121,7 +143,6 @@ RUN wget -qO- "https://github.com/koalaman/shellcheck/releases/download/stable/s
##################### #####################
# Install Go Linter # # Install Go Linter #
##################### #####################
ARG GO_VERSION='v1.27.0'
RUN wget -O- -nvq https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s "$GO_VERSION" RUN wget -O- -nvq https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s "$GO_VERSION"
################## ##################
@ -147,7 +168,6 @@ RUN wget "https://github.com/dotenv-linter/dotenv-linter/releases/latest/downloa
##################### #####################
# Install clj-kondo # # Install clj-kondo #
##################### #####################
ARG CLJ_KONDO_VERSION='2020.06.21'
RUN curl -sLO https://github.com/borkdude/clj-kondo/releases/download/v${CLJ_KONDO_VERSION}/clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ RUN curl -sLO https://github.com/borkdude/clj-kondo/releases/download/v${CLJ_KONDO_VERSION}/clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \
&& unzip clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ && unzip clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \
&& rm clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ && rm clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \
@ -191,6 +211,7 @@ ENV GITHUB_SHA=${GITHUB_SHA} \
VALIDATE_CLOJURE=${VALIDATE_CLOJURE} \ VALIDATE_CLOJURE=${VALIDATE_CLOJURE} \
VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \ VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \
VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \ VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \
VALIDATE_ARM=${VALIDATE_ARM} \
VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \ VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \
VALIDATE_PROTOBUF=${VALIDATE_PROTOBUF} \ VALIDATE_PROTOBUF=${VALIDATE_PROTOBUF} \
ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \ ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \

View file

@ -34,6 +34,7 @@ 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) |
| **Azure Resource Manager (ARM)** | [arm-ttk](https://github.com/azure/arm-ttk) |
| **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-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) |
@ -171,6 +172,7 @@ and won't run anything unexpected.
| **VALIDATE_DOCKER** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_DOCKER** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_GO** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_GO** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_POWERSHELL** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_POWERSHELL** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_ARM** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_TERRAFORM** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_TERRAFORM** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_CSS** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_CSS** | `true` | Flag to enable or disable the linting process of the language. |
| **VALIDATE_ENV** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_ENV** | `true` | Flag to enable or disable the linting process of the language. |

30
TEMPLATES/.arm-ttk.psd1 Normal file
View file

@ -0,0 +1,30 @@
# Documentation:
# - Test Parameters: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-toolkit#test-parameters
# - Test Cases: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-cases
@{
# Test = @(
# 'Parameters Property Must Exist',
# 'Parameters Must Be Referenced',
# 'Secure String Parameters Cannot Have Default',
# 'Location Should Not Be Hardcoded',
# 'Resources Should Have Location',
# 'VM Size Should Be A Parameter',
# 'Min And Max Value Are Numbers',
# 'artifacts-parameter',
# 'Variables Must Be Referenced',
# 'Dynamic Variable References Should Not Use Concat',
# 'apiVersions Should Be Recent',
# 'Providers apiVersions Is Not Permitted',
# 'Template Should Not Contain Blanks',
# 'IDs Should Be Derived From ResourceIDs',
# 'ResourceIds should not contain',
# 'DependsOn Must Not Be Conditional',
# 'Deployment Resources Must Not Be Debug',
# 'adminUsername Should Not Be A Literal',
# 'VM Images Should Use Latest Version',
# 'Virtual-Machines-Should-Not-Be-Preview',
# 'ManagedIdentityExtension must not be used',
# 'Outputs Must Not Contain Secrets'
# )
# Skip = @()
}

View file

@ -81,11 +81,6 @@ function BuildFileList() {
echo "----------------------------------------------" echo "----------------------------------------------"
echo "Files that have been modified in the commit(s):" echo "Files that have been modified in the commit(s):"
for FILE in "${RAW_FILE_ARRAY[@]}"; do for FILE in "${RAW_FILE_ARRAY[@]}"; do
##############
# Print file #
##############
echo "File:[$FILE]"
########################### ###########################
# Get the files extension # # Get the files extension #
########################### ###########################
@ -93,6 +88,11 @@ function BuildFileList() {
# reverse it back, substitute to lowercase # reverse it back, substitute to lowercase
FILE_TYPE=$(basename "$FILE" | rev | cut -f1 -d'.' | rev | awk '{print tolower($0)}') FILE_TYPE=$(basename "$FILE" | rev | cut -f1 -d'.' | rev | awk '{print tolower($0)}')
##############
# Print file #
##############
echo "File:[$FILE], File_type:[$FILE_TYPE]"
######### #########
# DEBUG # # DEBUG #
######### #########
@ -142,7 +142,15 @@ function BuildFileList() {
################################ ################################
FILE_ARRAY_OPENAPI+=("$FILE") FILE_ARRAY_OPENAPI+=("$FILE")
fi fi
############################
# Check if file is ARM #
############################
if DetectARMFile "$FILE"; then
################################
# Append the file to the array #
################################
FILE_ARRAY_ARM+=("$FILE")
fi
##################################### #####################################
# Check if the file is CFN template # # Check if the file is CFN template #
##################################### #####################################

View file

@ -22,26 +22,26 @@ source /action/lib/worker.sh # Source the function script(s)
# GLOBALS # # GLOBALS #
########### ###########
# Default Vars # Default Vars
DEFAULT_RULES_LOCATION='/action/lib/.automation' # Default rules files location DEFAULT_RULES_LOCATION='/action/lib/.automation' # Default rules files location
LINTER_RULES_PATH="${LINTER_RULES_PATH:-.github/linters}" # Linter Path Directory LINTER_RULES_PATH="${LINTER_RULES_PATH:-.github/linters}" # Linter Path Directory
# YAML Vars # YAML Vars
YAML_FILE_NAME='.yaml-lint.yml' # Name of the file YAML_FILE_NAME='.yaml-lint.yml' # Name of the file
YAML_LINTER_RULES="$DEFAULT_RULES_LOCATION/$YAML_FILE_NAME" # Path to the yaml lint rules YAML_LINTER_RULES="$DEFAULT_RULES_LOCATION/$YAML_FILE_NAME" # Path to the yaml lint rules
# MD Vars # MD Vars
MD_FILE_NAME='.markdown-lint.yml' # Name of the file MD_FILE_NAME='.markdown-lint.yml' # Name of the file
MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to the markdown lint rules MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to the markdown lint rules
# 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 # Cloudformation Vars
CFN_FILE_NAME='.cfnlintrc.yml' # Name of the file CFN_FILE_NAME='.cfnlintrc.yml' # Name of the file
CFN_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CFN_FILE_NAME" # Path to the python lint rules CFN_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CFN_FILE_NAME" # Path to the cloudformation 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
# Coffee Vars # Coffee Vars
COFFEESCRIPT_FILE_NAME='.coffee-lint.json' # Name of the file COFFEE_FILE_NAME='.coffee-lint.json' # Name of the file
COFFEESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEESCRIPT_FILE_NAME" # Path to the coffeescript lint rules COFFEESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEE_FILE_NAME" # Path to the coffeescript lint rules
# Javascript Vars # Javascript Vars
JAVASCRIPT_FILE_NAME="${JAVASCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # Name of the file JAVASCRIPT_FILE_NAME="${JAVASCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # Name of the file
JAVASCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$JAVASCRIPT_FILE_NAME" # Path to the Javascript lint rules JAVASCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$JAVASCRIPT_FILE_NAME" # Path to the Javascript lint rules
@ -51,32 +51,35 @@ TYPESCRIPT_FILE_NAME="${TYPESCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # Name o
TYPESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TYPESCRIPT_FILE_NAME" # Path to the Typescript lint rules TYPESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TYPESCRIPT_FILE_NAME" # Path to the Typescript lint rules
TYPESCRIPT_STANDARD_LINTER_RULES='' # ENV string to pass when running js standard TYPESCRIPT_STANDARD_LINTER_RULES='' # ENV string to pass when running js standard
# Ansible Vars # Ansible Vars
ANSIBLE_FILE_NAME='.ansible-lint.yml' # Name of the file ANSIBLE_FILE_NAME='.ansible-lint.yml' # Name of the file
ANSIBLE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ANSIBLE_FILE_NAME" # Path to the Ansible lint rules ANSIBLE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ANSIBLE_FILE_NAME" # Path to the Ansible lint rules
# Docker Vars # Docker Vars
DOCKER_FILE_NAME='.dockerfilelintrc' # Name of the file DOCKER_FILE_NAME='.dockerfilelintrc' # Name of the file
DOCKER_LINTER_RULES="$DEFAULT_RULES_LOCATION/$DOCKER_FILE_NAME" # Path to the Docker lint rules DOCKER_LINTER_RULES="$DEFAULT_RULES_LOCATION/$DOCKER_FILE_NAME" # Path to the Docker lint rules
# Golang Vars # Golang Vars
GO_FILE_NAME='.golangci.yml' # Name of the file GO_FILE_NAME='.golangci.yml' # Name of the file
GO_LINTER_RULES="$DEFAULT_RULES_LOCATION/$GO_FILE_NAME" # Path to the Go lint rules GO_LINTER_RULES="$DEFAULT_RULES_LOCATION/$GO_FILE_NAME" # Path to the Go lint rules
# Terraform Vars # Terraform Vars
TERRAFORM_FILE_NAME='.tflint.hcl' # Name of the file TERRAFORM_FILE_NAME='.tflint.hcl' # Name of the file
TERRAFORM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TERRAFORM_FILE_NAME" # Path to the Terraform lint rules TERRAFORM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TERRAFORM_FILE_NAME" # Path to the Terraform lint rules
# Powershell Vars # Powershell Vars
POWERSHELL_FILE_NAME='.powershell-psscriptanalyzer.psd1' # Name of the file POWERSHELL_FILE_NAME='.powershell-psscriptanalyzer.psd1' # Name of the file
POWERSHELL_LINTER_RULES="$DEFAULT_RULES_LOCATION/$POWERSHELL_FILE_NAME" # Path to the Powershell lint rules POWERSHELL_LINTER_RULES="$DEFAULT_RULES_LOCATION/$POWERSHELL_FILE_NAME" # Path to the Powershell lint rules
# Azure Resource Manager Vars
ARM_FILE_NAME='.arm-ttk.psd1' # Name of the file
ARM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ARM_FILE_NAME" # Path to the ARM lint rules
# CSS Vars # CSS Vars
CSS_FILE_NAME='.stylelintrc.json' # Name of the file CSS_FILE_NAME='.stylelintrc.json' # Name of the file
CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to the CSS lint rules CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to the CSS lint rules
# OpenAPI Vars # OpenAPI Vars
OPENAPI_FILE_NAME='.openapirc.yml' # Name of the file OPENAPI_FILE_NAME='.openapirc.yml' # Name of the file
OPENAPI_LINTER_RULES="$DEFAULT_RULES_LOCATION/$OPENAPI_FILE_NAME" # Path to the OpenAPI lint rules OPENAPI_LINTER_RULES="$DEFAULT_RULES_LOCATION/$OPENAPI_FILE_NAME" # Path to the OpenAPI lint rules
# Protocol Buffers Vars # Protocol Buffers Vars
PROTOBUF_FILE_NAME='.protolintrc.yml' # Name of the file PROTOBUF_FILE_NAME='.protolintrc.yml' # Name of the file
PROTOBUF_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PROTOBUF_FILE_NAME" # Path to the Protocol Buffers lint rules PROTOBUF_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PROTOBUF_FILE_NAME" # Path to the Protocol Buffers lint rules
# Clojure Vars # Clojure Vars
CLOJURE_FILE_NAME='.clj-kondo/config.edn' CLOJURE_FILE_NAME='.clj-kondo/config.edn' # Name of the file
CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" # Path to the Clojure lint rules
####################################### #######################################
# Linter array for information prints # # Linter array for information prints #
@ -84,7 +87,7 @@ 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" "pwsh" "ktlint" "protolint" "clj-kondo" "stylelint" "dotenv-linter" "pwsh" "arm-ttk" "ktlint" "protolint" "clj-kondo"
"spectral" "cfn-lint") "spectral" "cfn-lint")
############################# #############################
@ -93,7 +96,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' 'CFN') 'CSS' 'ENV' 'POWERSHELL' 'ARM' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' 'CFN')
################### ###################
# GitHub ENV Vars # # GitHub ENV Vars #
@ -127,6 +130,7 @@ VALIDATE_ENV="${VALIDATE_ENV}" # Boolean to vali
VALIDATE_CLOJURE="${VALIDATE_CLOJURE}" # Boolean to validate language VALIDATE_CLOJURE="${VALIDATE_CLOJURE}" # Boolean to validate language
VALIDATE_TERRAFORM="${VALIDATE_TERRAFORM}" # Boolean to validate language VALIDATE_TERRAFORM="${VALIDATE_TERRAFORM}" # Boolean to validate language
VALIDATE_POWERSHELL="${VALIDATE_POWERSHELL}" # Boolean to validate language VALIDATE_POWERSHELL="${VALIDATE_POWERSHELL}" # Boolean to validate language
VALIDATE_ARM="${VALIDATE_ARM}" # Boolean to validate language
VALIDATE_KOTLIN="${VALIDATE_KOTLIN}" # Boolean to validate language VALIDATE_KOTLIN="${VALIDATE_KOTLIN}" # Boolean to validate language
VALIDATE_OPENAPI="${VALIDATE_OPENAPI}" # Boolean to validate language VALIDATE_OPENAPI="${VALIDATE_OPENAPI}" # Boolean to validate language
TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases
@ -183,6 +187,7 @@ FILE_ARRAY_DOCKER=() # Array of files to check
FILE_ARRAY_GO=() # Array of files to check FILE_ARRAY_GO=() # Array of files to check
FILE_ARRAY_TERRAFORM=() # Array of files to check FILE_ARRAY_TERRAFORM=() # Array of files to check
FILE_ARRAY_POWERSHELL=() # Array of files to check FILE_ARRAY_POWERSHELL=() # Array of files to check
FILE_ARRAY_ARM=() # Array of files to check
FILE_ARRAY_CSS=() # Array of files to check FILE_ARRAY_CSS=() # Array of files to check
FILE_ARRAY_ENV=() # Array of files to check FILE_ARRAY_ENV=() # Array of files to check
FILE_ARRAY_CLOJURE=() # Array of files to check FILE_ARRAY_CLOJURE=() # Array of files to check
@ -213,6 +218,7 @@ ERRORS_FOUND_DOCKER=0 # Count of errors found
ERRORS_FOUND_GO=0 # Count of errors found ERRORS_FOUND_GO=0 # Count of errors found
ERRORS_FOUND_TERRAFORM=0 # Count of errors found ERRORS_FOUND_TERRAFORM=0 # Count of errors found
ERRORS_FOUND_POWERSHELL=0 # Count of errors found ERRORS_FOUND_POWERSHELL=0 # Count of errors found
ERRORS_FOUND_ARM=0 # Count of errors found
ERRORS_FOUND_CSS=0 # Count of errors found ERRORS_FOUND_CSS=0 # Count of errors found
ERRORS_FOUND_ENV=0 # Count of errors found ERRORS_FOUND_ENV=0 # Count of errors found
ERRORS_FOUND_CLOJURE=0 # Count of errors found ERRORS_FOUND_CLOJURE=0 # Count of errors found
@ -253,19 +259,24 @@ GetLinterVersions() {
echo "" echo ""
echo "---------------------------------------------" echo "---------------------------------------------"
echo "Linter Version Info:" echo "Linter Version Info:"
echo "---------------------------------------------"
echo ""
########################################################## ##########################################################
# Go through the array of linters and print version info # # Go through the array of linters and print version info #
########################################################## ##########################################################
for LINTER in "${LINTER_ARRAY[@]}"; do for LINTER in "${LINTER_ARRAY[@]}"; do
echo "---------------------------------------------"
echo "[$LINTER]:"
################### ###################
# Get the version # # Get the version #
################### ###################
mapfile -t GET_VERSION_CMD < <("$LINTER" --version 2>&1) if [[ "$LINTER" == "arm-ttk" ]]; then
# Need specific command for ARM
mapfile -t GET_VERSION_CMD < <(grep -iE 'version' "$ARM_TTK_PSD1" | xargs 2>&1)
elif [[ "$LINTER" == "protolint" ]]; then
# Need specific command for Protolint
mapfile -t GET_VERSION_CMD < <(echo "--version not supported")
else
# Standard version command
mapfile -t GET_VERSION_CMD < <("$LINTER" --version 2>&1)
fi
####################### #######################
# Load the error code # # Load the error code #
@ -276,16 +287,20 @@ GetLinterVersions() {
# Check the shell for errors # # Check the shell for errors #
############################## ##############################
if [ $ERROR_CODE -ne 0 ] || [ -z "${GET_VERSION_CMD[*]}" ]; then if [ $ERROR_CODE -ne 0 ] || [ -z "${GET_VERSION_CMD[*]}" ]; then
echo -e "${NC}${F[Y]}WARN!${NC} Failed to get version info for:[$LINTER]${NC}" echo -e "${NC}[$LINTER]: ${F[Y]}WARN!${NC} Failed to get version info for:${NC}"
echo "---------------------------------------------"
else else
########################## ##########################
# Print the version info # # Print the version info #
########################## ##########################
echo "${GET_VERSION_CMD[*]}" echo -e "${NC}${F[B]}Successfully found version for ${F[W]}[$LINTER]${F[B]}: ${F[W]}${GET_VERSION_CMD[*]}${NC}"
echo "---------------------------------------------"
fi fi
done done
#########################
# Print version footers #
#########################
echo "---------------------------------------------"
echo ""
} }
################################################################################ ################################################################################
#### Function GetLinterRules ################################################### #### Function GetLinterRules ###################################################
@ -435,6 +450,39 @@ DetectOpenAPIFile() {
fi fi
} }
################################################################################ ################################################################################
#### Function DetectARMFile ####################################################
DetectARMFile() {
################
# Pull in vars #
################
FILE="$1" # Name of the file/path we are validating
###############################
# Check the file for keywords #
###############################
grep -E 'schema.management.azure.com' "$FILE" > /dev/null
#######################
# Load the error code #
#######################
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ $ERROR_CODE -eq 0 ]; then
########################
# Found string in file #
########################
return 0
else
###################
# No string match #
###################
return 1
fi
}
################################################################################
#### Function DetectCloudFormationFile ######################################### #### Function DetectCloudFormationFile #########################################
DetectCloudFormationFile() { DetectCloudFormationFile() {
################ ################
@ -720,6 +768,7 @@ Footer() {
[ "$ERRORS_FOUND_GO" -ne 0 ] || [ "$ERRORS_FOUND_GO" -ne 0 ] ||
[ "$ERRORS_FOUND_TERRAFORM" -ne 0 ] || [ "$ERRORS_FOUND_TERRAFORM" -ne 0 ] ||
[ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] || [ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] ||
[ "$ERRORS_FOUND_ARM" -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_CFN" -ne 0 ] ||
@ -791,6 +840,8 @@ GetLinterRules "DOCKER"
GetLinterRules "TERRAFORM" GetLinterRules "TERRAFORM"
# Get PowerShell rules # Get PowerShell rules
GetLinterRules "POWERSHELL" GetLinterRules "POWERSHELL"
# Get ARM rules
GetLinterRules "ARM"
# Get CSS rules # Get CSS rules
GetLinterRules "CSS" GetLinterRules "CSS"
# Get CFN rules # Get CFN rules
@ -1121,6 +1172,17 @@ if [ "$VALIDATE_POWERSHELL" == "true" ]; then
LintCodebase "POWERSHELL" "pwsh" "Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "${FILE_ARRAY_POWERSHELL[@]}" LintCodebase "POWERSHELL" "pwsh" "Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "${FILE_ARRAY_POWERSHELL[@]}"
fi fi
########################
# ARM Template LINTING #
########################
if [ "$VALIDATE_ARM" == "true" ]; then
###############################
# Lint the ARM Template files #
###############################
# LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY"
LintCodebase "ARM" "arm-ttk" "Import-Module $ARM_TTK_PSD1 ; \$config = \$(Import-PowerShellDataFile -Path $ARM_LINTER_RULES) ; Test-AzTemplate @config -TemplatePath" ".*\.\(json\)\$" "${FILE_ARRAY_ARM[@]}"
fi
################### ###################
# OPENAPI LINTING # # OPENAPI LINTING #
################### ###################

View file

@ -65,6 +65,7 @@ function GetValidationInfo() {
VALIDATE_GO=$(echo "$VALIDATE_GO" | awk '{print tolower($0)}') VALIDATE_GO=$(echo "$VALIDATE_GO" | awk '{print tolower($0)}')
VALIDATE_TERRAFORM=$(echo "$VALIDATE_TERRAFORM" | awk '{print tolower($0)}') VALIDATE_TERRAFORM=$(echo "$VALIDATE_TERRAFORM" | awk '{print tolower($0)}')
VALIDATE_POWERSHELL=$(echo "$VALIDATE_POWERSHELL" | awk '{print tolower($0)}') VALIDATE_POWERSHELL=$(echo "$VALIDATE_POWERSHELL" | awk '{print tolower($0)}')
VALIDATE_ARM=$(echo "$VALIDATE_ARM" | awk '{print tolower($0)}')
VALIDATE_CSS=$(echo "$VALIDATE_CSS" | awk '{print tolower($0)}') VALIDATE_CSS=$(echo "$VALIDATE_CSS" | awk '{print tolower($0)}')
VALIDATE_ENV=$(echo "$VALIDATE_ENV" | awk '{print tolower($0)}') VALIDATE_ENV=$(echo "$VALIDATE_ENV" | awk '{print tolower($0)}')
VALIDATE_CLOJURE=$(echo "$VALIDATE_CLOJURE" | awk '{print tolower($0)}') VALIDATE_CLOJURE=$(echo "$VALIDATE_CLOJURE" | awk '{print tolower($0)}')
@ -95,6 +96,7 @@ function GetValidationInfo() {
$VALIDATE_GO || -n \ $VALIDATE_GO || -n \
$VALIDATE_TERRAFORM || -n \ $VALIDATE_TERRAFORM || -n \
$VALIDATE_POWERSHELL || -n \ $VALIDATE_POWERSHELL || -n \
$VALIDATE_ARM || -n \
$VALIDATE_CSS || -n \ $VALIDATE_CSS || -n \
$VALIDATE_ENV || -n \ $VALIDATE_ENV || -n \
$VALIDATE_CLOJURE || -n \ $VALIDATE_CLOJURE || -n \
@ -370,6 +372,20 @@ function GetValidationInfo() {
VALIDATE_POWERSHELL="true" VALIDATE_POWERSHELL="true"
fi fi
###################################
# Validate if we should check ARM #
###################################
if [[ "$ANY_SET" == "true" ]]; then
# Some linter flags were set - only run those set to true
if [[ -z "$VALIDATE_ARM" ]]; then
# ARM flag was not set - default to false
VALIDATE_ARM="false"
fi
else
# No linter flags were set - default all to true
VALIDATE_ARM="true"
fi
################################### ###################################
# Validate if we should check CSS # # Validate if we should check CSS #
################################### ###################################
@ -552,6 +568,11 @@ function GetValidationInfo() {
else else
PRINT_ARRAY+=("- Excluding [POWERSHELL] files in code base...") PRINT_ARRAY+=("- Excluding [POWERSHELL] files in code base...")
fi fi
if [[ $VALIDATE_ARM == "true" ]]; then
PRINT_ARRAY+=("- Validating [ARM] files in code base...")
else
PRINT_ARRAY+=("- Excluding [ARM] files in code base...")
fi
if [[ $VALIDATE_CSS == "true" ]]; then if [[ $VALIDATE_CSS == "true" ]]; then
PRINT_ARRAY+=("- Validating [CSS] files in code base...") PRINT_ARRAY+=("- Validating [CSS] files in code base...")
else else

View file

@ -55,8 +55,7 @@ function LintCodebase() {
else else
# Success # Success
if [[ $ACTIONS_RUNNER_DEBUG == "true" ]]; then if [[ $ACTIONS_RUNNER_DEBUG == "true" ]]; then
echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system${NC}" echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system location: ${F[W]}[$VALIDATE_INSTALL_CMD]${NC}"
echo "Location:[$VALIDATE_INSTALL_CMD]"
fi fi
fi fi
@ -156,17 +155,19 @@ function LintCodebase() {
#################### ####################
LINT_CMD='' LINT_CMD=''
####################################### ####################################
# Corner case for Powershell subshell # # Corner case for pwsh subshell #
####################################### # - PowerShell (PSScriptAnalyzer) #
if [[ $FILE_TYPE == "POWERSHELL" ]]; then # - ARM (arm-ttk) #
####################################
if [[ $FILE_TYPE == "POWERSHELL" ]] || [[ $FILE_TYPE == "ARM" ]]; then
################################ ################################
# Lint the file with the rules # # Lint the file with the rules #
################################ ################################
# Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell # Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell
LINT_CMD=$( LINT_CMD=$(
cd "$GITHUB_WORKSPACE" || exit cd "$GITHUB_WORKSPACE" || exit
pwsh -c "($LINTER_COMMAND $FILE)" pwsh -NoProfile -NoLogo -Command "$LINTER_COMMAND $FILE; if (\$Error.Count) { exit 1 }"
exit $? 2>&1 exit $? 2>&1
) )
else else
@ -248,8 +249,7 @@ function TestCodebase() {
exit 1 exit 1
else else
# Success # Success
echo -e "${NC}${F[B]}Successfully found binary in system${NC}" echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system location: ${F[W]}[$VALIDATE_INSTALL_CMD]${NC}"
echo "Location:[$VALIDATE_INSTALL_CMD]"
fi fi
########################## ##########################
@ -334,14 +334,14 @@ function TestCodebase() {
cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/$INDVIDUAL_TEST_FOLDER" || exit cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/$INDVIDUAL_TEST_FOLDER" || exit
$LINTER_COMMAND "$FILE" 2>&1 $LINTER_COMMAND "$FILE" 2>&1
) )
elif [[ $FILE_TYPE == "POWERSHELL" ]]; then elif [[ $FILE_TYPE == "POWERSHELL" ]] || [[ $FILE_TYPE == "ARM" ]]; then
################################ ################################
# Lint the file with the rules # # Lint the file with the rules #
################################ ################################
# Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell # Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell
LINT_CMD=$( LINT_CMD=$(
cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit
pwsh -c "($LINTER_COMMAND $FILE)" pwsh -NoProfile -NoLogo -Command "$LINTER_COMMAND $FILE; if (\$Error.Count) { exit 1 }"
exit $? 2>&1 exit $? 2>&1
) )
else else
@ -470,7 +470,8 @@ function RunTestCases() {
TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" ".*\.\(yml\|yaml\)\$" "ansible" TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" ".*\.\(yml\|yaml\)\$" "ansible"
TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" "terraform" 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 "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 "POWERSHELL" "pwsh" "Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "powershell"
TestCodebase "ARM" "arm-ttk" "Import-Module $ARM_TTK_PSD1 ; \$config = \$(Import-PowerShellDataFile -Path $ARM_LINTER_RULES) ; Test-AzTemplate @config -TemplatePath" ".*\.\(json\)\$" "arm"
TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "css" TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "css"
TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" "env" 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 "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "clojure"