Files
actions/eslint-check/action.yml
renovate[bot] 245d8a9c98 fix(github-action): update github/codeql-action (v3.28.17 → v3.28.18) (#139)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-16 21:12:50 +00:00

262 lines
7.6 KiB
YAML

---
# yaml-language-server: $schema=https://json.schemastore.org/github-action.json
name: ESLint Check
description: 'Run ESLint check on the repository with advanced configuration and reporting'
author: Ismo Vuorinen
branding:
icon: check-circle
color: blue
inputs:
working-directory:
description: 'Directory containing files to lint'
required: false
default: '.'
eslint-version:
description: 'ESLint version to use'
required: false
default: 'latest'
config-file:
description: 'Path to ESLint config file'
required: false
default: '.eslintrc'
ignore-file:
description: 'Path to ESLint ignore file'
required: false
default: '.eslintignore'
file-extensions:
description: 'File extensions to lint (comma-separated)'
required: false
default: '.js,.jsx,.ts,.tsx'
cache:
description: 'Enable ESLint caching'
required: false
default: 'true'
max-warnings:
description: 'Maximum number of warnings allowed'
required: false
default: '0'
fail-on-error:
description: 'Fail workflow if issues are found'
required: false
default: 'true'
report-format:
description: 'Output format (stylish, json, sarif)'
required: false
default: 'sarif'
max-retries:
description: 'Maximum number of retry attempts'
required: false
default: '3'
outputs:
error-count:
description: 'Number of errors found'
value: ${{ steps.lint.outputs.error_count }}
warning-count:
description: 'Number of warnings found'
value: ${{ steps.lint.outputs.warning_count }}
sarif-file:
description: 'Path to SARIF report file'
value: ${{ steps.lint.outputs.sarif_file }}
files-checked:
description: 'Number of files checked'
value: ${{ steps.lint.outputs.files_checked }}
runs:
using: composite
steps:
- name: Validate Inputs
id: validate
shell: bash
run: |
set -euo pipefail
# Validate working directory
if [ ! -d "${{ inputs.working-directory }}" ]; then
echo "::error::Working directory does not exist: ${{ inputs.working-directory }}"
exit 1
fi
# Validate file extensions
if ! [[ "${{ inputs.file-extensions }}" =~ ^[.,a-zA-Z0-9]+$ ]]; then
echo "::error::Invalid file extensions format"
exit 1
fi
# Validate max warnings
if ! [[ "${{ inputs.max-warnings }}" =~ ^[0-9]+$ ]]; then
echo "::error::Invalid max warnings value"
exit 1
fi
- name: Setup Node.js
uses: ivuorinen/actions/node-setup@main
- name: Install Dependencies
shell: bash
run: |
set -euo pipefail
cd ${{ inputs.working-directory }}
# Install ESLint and required dependencies
echo "Installing ESLint dependencies..."
# Function to install with retries
install_with_retries() {
local attempt=1
local max_attempts=${{ inputs.max-retries }}
while [ $attempt -le $max_attempts ]; do
echo "Installation attempt $attempt of $max_attempts"
if npm install \
eslint@${{ inputs.eslint-version }} \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin \
eslint-plugin-import \
eslint-config-prettier \
typescript; then
return 0
fi
attempt=$((attempt + 1))
if [ $attempt -le $max_attempts ]; then
echo "Installation failed, waiting 10 seconds before retry..."
sleep 10
fi
done
echo "::error::Failed to install dependencies after $max_attempts attempts"
return 1
}
install_with_retries
- name: Prepare ESLint Configuration
id: config
shell: bash
run: |
set -euo pipefail
cd ${{ inputs.working-directory }}
# Create default config if none exists
if [ ! -f "${{ inputs.config-file }}" ]; then
echo "Creating default ESLint configuration..."
cat > "${{ inputs.config-file }}" <<EOF
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import"],
"env": {
"es2022": true,
"node": true
}
}
EOF
fi
# Create default ignore file if none exists
if [ ! -f "${{ inputs.ignore-file }}" ]; then
echo "Creating default ESLint ignore file..."
cat > "${{ inputs.ignore-file }}" <<EOF
node_modules/
dist/
build/
coverage/
*.min.js
EOF
fi
- name: Run ESLint Check
id: lint
shell: bash
run: |
set -euo pipefail
cd ${{ inputs.working-directory }}
# Create reports directory
mkdir -p reports
# Prepare file extensions for ESLint
IFS=',' read -ra EXTENSIONS <<< "${{ inputs.file-extensions }}"
ext_pattern=""
for ext in "${EXTENSIONS[@]}"; do
ext_pattern="$ext_pattern --ext $ext"
done
# Run ESLint
echo "Running ESLint..."
npx eslint \
$ext_pattern \
--config ${{ inputs.config-file }} \
--ignore-path ${{ inputs.ignore-file }} \
${{ inputs.cache == 'true' && '--cache' || '' }} \
--max-warnings ${{ inputs.max-warnings }} \
--format=${{ inputs.report-format }} \
--output-file=reports/eslint.${{ inputs.report-format }} \
. || {
error_code=$?
# Count errors and warnings
if [ "${{ inputs.report-format }}" = "json" ]; then
error_count=$(jq '[.[] | .errorCount] | add' reports/eslint.json)
warning_count=$(jq '[.[] | .warningCount] | add' reports/eslint.json)
else
error_count=$(grep -c '"level": "error"' reports/eslint.sarif || echo 0)
warning_count=$(grep -c '"level": "warning"' reports/eslint.sarif || echo 0)
fi
echo "error_count=${error_count}" >> $GITHUB_OUTPUT
echo "warning_count=${warning_count}" >> $GITHUB_OUTPUT
if [ "${{ inputs.fail-on-error }}" = "true" ] && [ $error_code -ne 0 ]; then
echo "::error::ESLint found ${error_count} errors and ${warning_count} warnings"
exit $error_code
fi
}
# Count checked files
files_checked=$(find . -type f \( $(printf -- "-name *%s -o " "${EXTENSIONS[@]}") -false \) | wc -l)
echo "files_checked=${files_checked}" >> $GITHUB_OUTPUT
echo "sarif_file=reports/eslint.sarif" >> $GITHUB_OUTPUT
- name: Upload ESLint Results
if: always() && inputs.report-format == 'sarif'
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: ${{ inputs.working-directory }}/reports/eslint.sarif
category: eslint
- name: Cache Cleanup
if: always()
shell: bash
run: |
set -euo pipefail
cd ${{ inputs.working-directory }}
# Clean up ESLint cache if it exists
if [ -f ".eslintcache" ]; then
rm .eslintcache
fi
# Remove temporary files
rm -rf reports/