Files
actions/pr-lint/action.yml

338 lines
13 KiB
YAML

# yaml-language-server: $schema=https://json.schemastore.org/github-action.json
# permissions:
# - contents: write # Required for committing linter fixes
# - pull-requests: write # Required for creating pull requests with fixes
---
# MegaLinter GitHub Action configuration file
# More info at https://megalinter.io
name: PR Lint
description: Runs MegaLinter against pull requests
author: Ismo Vuorinen
branding:
icon: check-circle
color: green
inputs:
token:
description: 'GitHub token for authentication'
required: false
default: ''
username:
description: 'GitHub username for commits'
required: false
default: 'github-actions'
email:
description: 'GitHub email for commits'
required: false
default: 'github-actions@github.com'
outputs:
validation_status:
description: 'Overall validation status (success/failure)'
value: ${{ steps.ml.outputs.has_updated_sources == '1' && 'failure' || 'success' }}
errors_found:
description: 'Number of linting errors found'
value: ${{ steps.ml.outputs.has_updated_sources }}
runs:
using: composite
steps:
- name: Validate Inputs
id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9
with:
action-type: pr-lint
token: ${{ inputs.token }}
username: ${{ inputs.username }}
email: ${{ inputs.email }}
# ╭──────────────────────────────────────────────────────────╮
# │ Git Checkout │
# ╰──────────────────────────────────────────────────────────╯
- name: Checkout Code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
token: ${{ inputs.token || github.token }}
# If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to
# improve performance
fetch-depth: 0
# ╭──────────────────────────────────────────────────────────╮
# │ Setup Git configuration │
# ╰──────────────────────────────────────────────────────────╯
- name: Setup Git Config
id: git-config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9
with:
token: ${{ inputs.token }}
username: ${{ inputs.username }}
email: ${{ inputs.email }}
# ╭──────────────────────────────────────────────────────────╮
# │ Install packages for linting │
# ╰──────────────────────────────────────────────────────────╯
# Node.js tests if package.json exists
- name: Detect package.json
id: detect-node
shell: bash
run: |
set -euo pipefail
if [ -f package.json ]; then
echo "found=true" >> $GITHUB_OUTPUT
fi
- name: Setup Node.js environment
if: steps.detect-node.outputs.found == 'true'
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9
with:
install: true
cache: true
# PHP tests if composer.json exists
- name: Detect composer.json
id: detect-php
shell: bash
run: |
set -euo pipefail
if [ -f composer.json ]; then
echo "found=true" >> $GITHUB_OUTPUT
fi
- name: Detect PHP Version
if: steps.detect-php.outputs.found == 'true'
id: php-version
uses: ivuorinen/actions/php-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9
- name: Setup PHP
if: steps.detect-php.outputs.found == 'true'
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
with:
php-version: ${{ steps.php-version.outputs.php-version }}
tools: composer
coverage: none
env:
GITHUB_TOKEN: ${{ inputs.token }}
- name: Setup problem matchers for PHP
if: steps.detect-php.outputs.found == 'true'
shell: bash
env:
RUNNER_TOOL_CACHE: ${{ runner.tool_cache }}
run: |
set -euo pipefail
echo "::add-matcher::$RUNNER_TOOL_CACHE/php.json"
- name: Install PHP dependencies
if: steps.detect-php.outputs.found == 'true'
shell: bash
run: |
set -euo pipefail
composer install --no-progress --prefer-dist --no-interaction
# Python tests if requirements.txt exists
- name: Detect requirements.txt
id: detect-python
shell: bash
run: |
set -euo pipefail
if [ -f requirements.txt ]; then
echo "found=true" >> $GITHUB_OUTPUT
fi
- name: Detect Python Version
if: steps.detect-python.outputs.found == 'true'
id: python-version
uses: ivuorinen/actions/python-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9
- name: Setup Python
if: steps.detect-python.outputs.found == 'true'
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ steps.python-version.outputs.python-version }}
cache: 'pip'
- name: Install Python dependencies
if: steps.detect-python.outputs.found == 'true'
shell: bash
run: |
set -euo pipefail
pip install -r requirements.txt
# Go tests if go.mod exists
- name: Detect go.mod
id: detect-go
shell: bash
run: |
set -euo pipefail
if [ -f go.mod ]; then
echo "found=true" >> $GITHUB_OUTPUT
fi
- name: Detect Go Version
if: steps.detect-go.outputs.found == 'true'
id: go-version
uses: ivuorinen/actions/go-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9
- name: Setup Go
if: steps.detect-go.outputs.found == 'true'
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: ${{ steps.go-version.outputs.go-version }}
cache: true
# ╭──────────────────────────────────────────────────────────╮
# │ MegaLinter │
# ╰──────────────────────────────────────────────────────────╯
- name: MegaLinter
# You can override MegaLinter flavor used to have faster performances
# More info at https://megalinter.io/latest/flavors/
uses: oxsecurity/megalinter/flavors/cupcake@62c799d895af9bcbca5eacfebca29d527f125a57 # v9.1.0
id: ml
# All available variables are described in documentation
# https://megalinter.io/latest/configuration/
env:
# Validates all source when push on main, else just the git diff with
# main. Override with true if you always want to lint all sources
#
# To validate the entire codebase, set to:
# VALIDATE_ALL_CODEBASE: true
#
# To validate only diff with main, set to:
# VALIDATE_ALL_CODEBASE: >-
# ${{
# github.event_name == 'push' &&
# contains(fromJSON('["refs/heads/main", "refs/heads/master"]'), github.ref)
# }}
VALIDATE_ALL_CODEBASE: >-
${{
github.event_name == 'push' &&
contains(fromJSON('["refs/heads/main", "refs/heads/master"]'), github.ref)
}}
GITHUB_TOKEN: ${{ steps.git-config.outputs.token || inputs.token }}
# Apply linter fixes configuration
#
# When active, APPLY_FIXES must also be defined as environment variable
# (in .github/workflows/mega-linter.yml or other CI tool)
APPLY_FIXES: all
# Decide which event triggers application of fixes in a commit or a PR
# (pull_request, push, all)
APPLY_FIXES_EVENT: pull_request
# If APPLY_FIXES is used, defines if the fixes are directly committed (commit)
# or posted in a PR (pull_request)
APPLY_FIXES_MODE: commit
# ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE
# .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY
# Uncomment to disable copy-paste and spell checks
DISABLE: COPYPASTE,SPELL
# Export env vars to make them available for subsequent expressions
- name: Export Apply Fixes Variables
shell: bash
run: |
echo "APPLY_FIXES_EVENT=pull_request" >> "$GITHUB_ENV"
echo "APPLY_FIXES_MODE=commit" >> "$GITHUB_ENV"
# Upload MegaLinter artifacts
- name: Archive production artifacts
if: success() || failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: MegaLinter reports
include-hidden-files: 'true'
path: |
megalinter-reports
mega-linter.log
# Set APPLY_FIXES_IF var for use in future steps
- name: Set APPLY_FIXES_IF var
shell: bash
env:
APPLY_FIXES_CONDITION: ${{ steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) }}
run: |
set -euo pipefail
# Sanitize by removing newlines to prevent env var injection
sanitized_condition="$(echo "$APPLY_FIXES_CONDITION" | tr -d '\n\r')"
printf 'APPLY_FIXES_IF=%s\n' "$sanitized_condition" >> "${GITHUB_ENV}"
# Set APPLY_FIXES_IF_* vars for use in future steps
- name: Set APPLY_FIXES_IF_* vars
shell: bash
env:
APPLY_FIXES_IF_PR_CONDITION: ${{ env.APPLY_FIXES_IF == 'true' && env.APPLY_FIXES_MODE == 'pull_request' }}
APPLY_FIXES_IF_COMMIT_CONDITION: ${{ env.APPLY_FIXES_IF == 'true' && env.APPLY_FIXES_MODE == 'commit' && (!contains(fromJSON('["refs/heads/main", "refs/heads/master"]'), github.ref)) }}
run: |
set -euo pipefail
# Sanitize by removing newlines to prevent env var injection
sanitized_pr="$(echo "$APPLY_FIXES_IF_PR_CONDITION" | tr -d '\n\r')"
sanitized_commit="$(echo "$APPLY_FIXES_IF_COMMIT_CONDITION" | tr -d '\n\r')"
printf 'APPLY_FIXES_IF_PR=%s\n' "$sanitized_pr" >> "${GITHUB_ENV}"
printf 'APPLY_FIXES_IF_COMMIT=%s\n' "$sanitized_commit" >> "${GITHUB_ENV}"
# Create pull request if applicable
# (for now works only on PR from same repository, not from forks)
- name: Create Pull Request with applied fixes
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
id: cpr
if: env.APPLY_FIXES_IF_PR == 'true'
with:
token: ${{ steps.git-config.outputs.token || inputs.token }}
commit-message: '[MegaLinter] Apply linters automatic fixes'
title: '[MegaLinter] Apply linters automatic fixes'
labels: bot
- name: Create PR output
if: env.APPLY_FIXES_IF_PR == 'true'
shell: bash
env:
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
PR_URL: ${{ steps.cpr.outputs.pull-request-url }}
run: |
set -euo pipefail
echo "PR Number - $PR_NUMBER"
echo "PR URL - $PR_URL"
# Push new commit if applicable
# (for now works only on PR from same repository, not from forks)
- name: Prepare commit
if: env.APPLY_FIXES_IF_COMMIT == 'true'
shell: bash
run: |
set -euo pipefail
sudo chown -Rc $UID .git/
- name: Commit and push applied linter fixes
uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0
if: env.APPLY_FIXES_IF_COMMIT == 'true'
with:
branch: >-
${{
github.event.pull_request.head.ref ||
github.head_ref ||
github.ref
}}
commit_message: '[MegaLinter] Apply linters fixes'
commit_user_name: ${{ steps.git-config.outputs.username }}
commit_user_email: ${{ steps.git-config.outputs.email }}