build(deps): bump FantasticFiasco/action-update-license-year from 3.0.3 to 3.0.4 #353
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| # This workflow will lint the code in the repository using various tools. Most linting tools in LizardByte | |
| # should be included in this workflow; however, there are cases where that is not true, such as with eslint. | |
| name: common lint (called) | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| workflow_call: | |
| jobs: | |
| lint: | |
| name: Common Lint | |
| runs-on: ubuntu-latest | |
| env: | |
| CLANG_FORMAT_VERSION: 20 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Get changed files | |
| id: changed_files | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const opts = github.rest.pulls.listFiles.endpoint.merge({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| }); | |
| const changedFiles = await github.paginate(opts); | |
| const changedFilesString = changedFiles.map(file => file.filename).join(' '); | |
| console.log(`Changed files: ${changedFilesString}`); | |
| core.setOutput('CHANGED_FILES', changedFilesString); | |
| - name: Download problem matchers | |
| shell: bash | |
| working-directory: .github | |
| run: | | |
| mkdir -p matchers | |
| cd matchers | |
| if [ "${{ github.repository }}" = "LizardByte/.github" ]; then | |
| # use the version from the same ref | |
| ref="${{ github.ref }}" | |
| else | |
| ref="master" | |
| fi | |
| gh_base_url="https://raw.githubusercontent.com/LizardByte/.github" | |
| gh_path="${gh_base_url}/${ref}/.github/matchers" | |
| declare -A files=( | |
| [actionlint]="https://raw.githubusercontent.com/rhysd/actionlint/main/.github/actionlint-matcher.json" | |
| [clang-format]="${gh_path}/clang-format.json" | |
| [cmake-lint]="${gh_path}/cmake-lint.json" | |
| [gcc]="${gh_path}/gcc.json" | |
| [hadolint]="${gh_path}/hadolint.json" | |
| [shellcheck-gcc]="${gh_path}/shellcheck-gcc.json" | |
| [yamllint]="${gh_path}/yamllint.json" | |
| ) | |
| for name in "${!files[@]}"; do | |
| if [ ! -f "${name}.json" ]; then | |
| echo "Downloading ${name}.json" | |
| url="${files[$name]}" | |
| curl \ | |
| -fsSL \ | |
| --retry 3 \ | |
| "$url" \ | |
| -o "${name}.json" | |
| else | |
| echo "Skipping download of ${name}.json, already exists" | |
| continue | |
| fi | |
| done | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install Python dependencies | |
| shell: bash | |
| run: | | |
| # shellcheck disable=SC2102 # this is triggered by the [toolchain] extra | |
| python -m pip install --upgrade \ | |
| "clang-format==${CLANG_FORMAT_VERSION}.*" \ | |
| pip \ | |
| setuptools \ | |
| wheel \ | |
| cmakelang \ | |
| flake8 \ | |
| flake8-github-annotations \ | |
| nb-clean \ | |
| nbqa[toolchain] \ | |
| yamllint | |
| - name: Install actionlint | |
| id: get_actionlint | |
| shell: bash | |
| run: | | |
| bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) | |
| if [ ! -f ".github/actionlint.yml" ]; then | |
| curl \ | |
| -fsSL \ | |
| --retry 3 \ | |
| -o ".github/actionlint.yml" \ | |
| "https://raw.githubusercontent.com/LizardByte/.github/master/.github/actionlint.yml" | |
| fi | |
| - name: Replace shell | |
| # for actionlint | |
| shell: bash | |
| run: | | |
| # Replace in workflow files | |
| find .github/workflows -type f -iname "*.yml" | while read -r file; do | |
| sed -i -e 's/msys2 {0}/bash/g' -e 's/freebsd {0}/sh/g' "${file}" | |
| done | |
| # Replace in all action.yml files anywhere | |
| find . -type f -iname "action.yml" | while read -r file; do | |
| sed -i -e 's/msys2 {0}/bash/g' -e 's/freebsd {0}/sh/g' "${file}" | |
| done | |
| - name: actionlint | |
| shell: bash | |
| if: always() | |
| run: | | |
| echo "::add-matcher::.github/matchers/actionlint.json" | |
| set +e | |
| error=0 | |
| ${{ steps.get_actionlint.outputs.executable }} -color | |
| error=$? | |
| set -e | |
| echo "::remove-matcher owner=actionlint::" | |
| exit ${error} | |
| - name: check-eol | |
| if: always() | |
| shell: bash | |
| run: | | |
| error=0 | |
| for file in ${{ steps.changed_files.outputs.CHANGED_FILES }}; do | |
| # Skip empty files | |
| if [[ ! -s "$file" ]]; then | |
| continue | |
| fi | |
| # Skip binary files using file --mime-encoding | |
| if file --mime-encoding "$file" | grep -q ": binary$"; then | |
| continue | |
| fi | |
| # Check if file ends with newline using tail -c 1 | |
| if [[ -n "$(tail -c 1 "$file")" ]]; then | |
| error=1 | |
| title="EOL linting error" | |
| message="File '$file' does not end with a newline character." | |
| line=$(($(wc -l < "$file") + 1)) | |
| echo "::error file=$file,line=$line,title=$title::$message" | |
| fi | |
| done | |
| exit ${error} | |
| - name: check-trailing-spaces | |
| if: always() | |
| uses: marcopaganini/check-trailing-spaces@8cb92e10874ed9bd54d89f2848f98308242527bd # v2.0.0 | |
| - name: C++ - find files | |
| id: cpp_files | |
| if: always() | |
| shell: bash | |
| run: | | |
| # find files | |
| found_files=$(find . -type f \ | |
| -iname "*.c" -o \ | |
| -iname "*.cpp" -o \ | |
| -iname "*.h" -o \ | |
| -iname "*.hpp" -o \ | |
| -iname "*.m" -o \ | |
| -iname "*.mm" \ | |
| ) | |
| ignore_files=$(find . -type f -iname ".clang-format-ignore") | |
| # Loop through each C++ file | |
| for file in $found_files; do | |
| for ignore_file in $ignore_files; do | |
| ignore_directory=$(dirname "$ignore_file") | |
| # if directory of ignore_file is beginning of file | |
| if [[ "$file" == "$ignore_directory"* ]]; then | |
| echo "ignoring file: ${file}" | |
| found_files="${found_files//${file}/}" | |
| break 1 | |
| fi | |
| done | |
| done | |
| # remove empty lines | |
| found_files=$(echo "$found_files" | sed '/^\s*$/d') | |
| echo "found cpp files: ${found_files}" | |
| # shellcheck disable=SC2086 # do not quote to keep this as a single line | |
| echo found_files=${found_files} >> "${GITHUB_OUTPUT}" | |
| - name: C++ - Update Clang format config | |
| if: always() && steps.cpp_files.outputs.found_files | |
| shell: bash | |
| run: | | |
| echo "LineEnding: LF" >> .clang-format | |
| - name: C++ - Clang format (diff) | |
| id: clang_format_diff | |
| if: always() && steps.cpp_files.outputs.found_files | |
| uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20 | |
| with: | |
| source: ${{ steps.cpp_files.outputs.found_files }} | |
| clangFormatVersion: '${{ env.CLANG_FORMAT_VERSION }}' | |
| extensions: 'c,cpp,h,hpp,m,mm' | |
| style: file | |
| inplace: false | |
| - name: C++ - Clang format (simple) | |
| if: always() && steps.clang_format_diff.outcome == 'failure' | |
| shell: bash | |
| run: | | |
| echo "::add-matcher::.github/matchers/clang-format.json" | |
| set +e | |
| error=0 | |
| clang-format \ | |
| --dry-run \ | |
| --style=file \ | |
| --Werror \ | |
| ${{ steps.cpp_files.outputs.found_files }} | |
| error=$? | |
| set -e | |
| echo "::remove-matcher owner=clang-format::" | |
| exit ${error} | |
| - name: CMake - find files | |
| id: cmake_files | |
| if: always() | |
| shell: bash | |
| run: | | |
| # find files | |
| found_files=$(find . -type f -iname "CMakeLists.txt" -o -iname "*.cmake") | |
| ignore_files=$(find . -type f -iname ".cmake-lint-ignore") | |
| # Loop through each C++ file | |
| for file in $found_files; do | |
| for ignore_file in $ignore_files; do | |
| ignore_directory=$(dirname "$ignore_file") | |
| # if directory of ignore_file is beginning of file | |
| if [[ "$file" == "$ignore_directory"* ]]; then | |
| echo "ignoring file: ${file}" | |
| found_files="${found_files//${file}/}" | |
| break 1 | |
| fi | |
| done | |
| done | |
| # remove empty lines | |
| found_files=$(echo "$found_files" | sed '/^\s*$/d') | |
| echo "found cmake files: ${found_files}" | |
| # shellcheck disable=SC2086 # do not quote to keep this as a single line | |
| echo found_files=${found_files} >> "${GITHUB_OUTPUT}" | |
| - name: CMake - cmake-lint | |
| if: always() && steps.cmake_files.outputs.found_files | |
| shell: bash | |
| run: | | |
| echo "::add-matcher::.github/matchers/cmake-lint.json" | |
| set +e | |
| error=0 | |
| cmake-lint --line-width 120 --tab-size 4 ${{ steps.cmake_files.outputs.found_files }} | |
| error=$? | |
| set -e | |
| echo "::remove-matcher owner=cmake-lint::" | |
| exit ${error} | |
| - name: Docker - find files | |
| id: docker_files | |
| if: always() | |
| shell: bash | |
| run: | | |
| found_files=$(find . -type f -iname "Dockerfile" -o -iname "*.dockerfile") | |
| echo "found_files: ${found_files}" | |
| # shellcheck disable=SC2086 # do not quote to keep this as a single line | |
| echo found_files=${found_files} >> "${GITHUB_OUTPUT}" | |
| - name: Docker - hadolint | |
| if: always() && steps.docker_files.outputs.found_files | |
| shell: bash | |
| run: | | |
| docker pull hadolint/hadolint | |
| # create hadolint config file | |
| cat <<EOF > .hadolint.yaml | |
| --- | |
| failure-threshold: style | |
| format: tty | |
| ignored: | |
| - DL3008 | |
| - DL3013 | |
| - DL3016 | |
| - DL3018 | |
| - DL3028 | |
| - DL3059 | |
| no-color: true | |
| no-fail: false | |
| strict-labels: true | |
| EOF | |
| error=0 | |
| echo "::add-matcher::.github/matchers/hadolint.json" | |
| set +e | |
| for file in ${{ steps.docker_files.outputs.found_files }}; do | |
| echo "file: ${file}" | |
| output=$(docker run --rm -i \ | |
| -e "NO_COLOR=0" \ | |
| -e "HADOLINT_VERBOSE=0" \ | |
| -v "$(pwd)"/.hadolint.yaml:/.config/hadolint.yaml \ | |
| hadolint/hadolint < "${file}" 2>&1) | |
| status=$? | |
| if [ ${status} -ne 0 ]; then | |
| error=1 | |
| echo "${output}" | |
| fi | |
| done | |
| set -e | |
| echo "::remove-matcher owner=hadolint::" | |
| exit ${error} | |
| - name: PowerShell - PSScriptAnalyzer | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| # PSScriptAnalyzer is already installed on GitHub runners | |
| # To see a list of available rules, run the following command: | |
| # Get-ScriptAnalyzerRule | Format-List | |
| # Create PSScriptAnalyzer config file only if it doesn't exist | |
| if (-not (Test-Path ./PSScriptAnalyzerSettings.psd1)) { | |
| @' | |
| @{ | |
| Severity=@( | |
| 'Error', | |
| 'Information', | |
| 'Warning' | |
| ) | |
| ExcludeRules=@( | |
| 'PSAlignAssignmentStatement' | |
| ) | |
| } | |
| '@ | Out-File -FilePath ./PSScriptAnalyzerSettings.psd1 | |
| } | |
| # Run PSScriptAnalyzer recursively on the whole repository | |
| $results = Invoke-ScriptAnalyzer -Path "." -Recurse | |
| Write-Host "::group::Analyzing PowerShell files" | |
| if ($results) { | |
| foreach ($result in $results) { | |
| $file = $result.ScriptPath | |
| $line = $result.Line | |
| $title = "[$($result.Severity)] $($result.RuleName)" | |
| $message = $result.Message | |
| # https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#setting-an-error-message | |
| Write-Output "::error file=$file,line=$line,title=$title::$message" | |
| } | |
| } | |
| Write-Host "::endgroup::" | |
| if ($results) { | |
| $results | Format-Table -AutoSize | |
| Write-Error "PSScriptAnalyzer found issues in PowerShell files" | |
| exit 1 | |
| } | |
| Write-Information "PSScriptAnalyzer found no issues in PowerShell files" | |
| - name: Python - flake8 | |
| if: always() | |
| shell: bash | |
| run: | | |
| echo "::group::problem matcher" | |
| set +e | |
| error=0 | |
| python -m flake8 \ | |
| --format github \ | |
| --verbose | |
| error=$? | |
| set -e | |
| echo "::endgroup::" | |
| # run flake8 again with human friendly output if there were errors | |
| if [ $error -ne 0 ]; then | |
| python -m flake8 \ | |
| --color=always \ | |
| --verbose | |
| fi | |
| - name: Python - nbqa flake8 | |
| if: always() | |
| shell: bash | |
| run: | | |
| echo "::group::problem matcher" | |
| set +e | |
| error=0 | |
| python -m nbqa flake8 \ | |
| --format=github \ | |
| --verbose \ | |
| . | |
| error=$? | |
| set -e | |
| echo "::endgroup::" | |
| # run nbqa flake8 again with human friendly output if there were errors | |
| if [ $error -ne 0 ]; then | |
| python -m nbqa flake8 \ | |
| --color=always \ | |
| --verbose \ | |
| . | |
| fi | |
| - name: Python - nb-clean | |
| if: always() | |
| shell: bash | |
| run: | | |
| output=$(find . -name '*.ipynb' -exec nb-clean check {} \;) | |
| # fail if there are any issues | |
| if [ -n "$output" ]; then | |
| echo "$output" | |
| exit 1 | |
| fi | |
| - name: Rust - find Cargo.toml | |
| id: run_cargo | |
| if: always() | |
| shell: bash | |
| run: | | |
| # check if Cargo.toml exists | |
| if [ -f "Cargo.toml" ]; then | |
| echo "found_cargo=true" >> "${GITHUB_OUTPUT}" | |
| else | |
| echo "found_cargo=false" >> "${GITHUB_OUTPUT}" | |
| fi | |
| - name: Setup Rust | |
| if: always() && steps.run_cargo.outputs.found_cargo == 'true' | |
| uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1.15.2 | |
| with: | |
| components: 'rustfmt' | |
| cache: false | |
| matcher: false # disable the built-in problem matcher | |
| toolchain: 'nightly' | |
| - name: Rust - cargo fmt | |
| if: always() && steps.run_cargo.outputs.found_cargo == 'true' | |
| shell: bash | |
| run: | | |
| set +e | |
| error=0 | |
| cargo +nightly fmt -- --check | |
| error=$? | |
| set -e | |
| if [ $error -ne 0 ]; then | |
| echo "::group::rustfmt github annotations" | |
| # https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#setting-an-error-message | |
| # each mismatch in mismatches has the following fields: | |
| # - original_begin_line | |
| # - original_end_line | |
| # - expected_begin_line | |
| # - expected_end_line | |
| # - original | |
| # - expected | |
| # note: original and expected may have \n which does not render properly, | |
| # so we will just tell the user to run `cargo +nightly fmt` | |
| cargo +nightly fmt -- --emit=json | jq -r ' | |
| .[] as $file | |
| | $file.mismatches[]? | |
| | "::error " | |
| + "file=\($file.name)," | |
| + "line=\(.original_begin_line)," | |
| + "endLine=\(.original_end_line)," | |
| + "title=rustfmt mismatch" | |
| + "::Run `cargo +nightly fmt` to fix formatting issues" | |
| ' | |
| echo "::endgroup::" | |
| exit ${error} | |
| fi | |
| - name: shellcheck - find files | |
| id: shellcheck_files | |
| if: always() | |
| shell: bash | |
| run: | | |
| found_files=$(find . -type f -iname "*.bash" -o -iname "*.sh") | |
| echo "found_files: ${found_files}" | |
| # shellcheck disable=SC2086 # do not quote to keep this as a single line | |
| echo found_files=${found_files} >> "${GITHUB_OUTPUT}" | |
| - name: shellcheck | |
| if: always() && steps.shellcheck_files.outputs.found_files | |
| shell: bash | |
| run: | | |
| echo "::add-matcher::.github/matchers/shellcheck-gcc.json" | |
| set +e | |
| error=0 | |
| shellcheck --format gcc ${{ steps.shellcheck_files.outputs.found_files }} | |
| error=$? | |
| set -e | |
| echo "::remove-matcher owner=shellcheck-gcc::" | |
| exit ${error} | |
| - name: YAML - find files | |
| id: yaml_files | |
| if: always() | |
| shell: bash | |
| run: | | |
| # space separated list of files | |
| FILES=.clang-format | |
| # empty placeholder | |
| found_files="" | |
| for FILE in ${FILES}; do | |
| if [ -f "$FILE" ] | |
| then | |
| found_files="$found_files $FILE" | |
| fi | |
| done | |
| echo "found_files=${found_files}" >> "${GITHUB_OUTPUT}" | |
| - name: YAML - yamllint | |
| id: yamllint | |
| if: always() | |
| shell: bash | |
| run: | | |
| if [ ! -f .yamllint.yml ]; then | |
| curl -sSL https://raw.githubusercontent.com/LizardByte/.github/master/.yamllint.yml -o .yamllint.yml | |
| fi | |
| echo "::add-matcher::.github/matchers/yamllint.json" | |
| set +e | |
| error=0 | |
| yamllint \ | |
| --config-file .yamllint.yml \ | |
| --format=standard \ | |
| --strict \ | |
| . ${{ steps.yaml_files.outputs.found_files }} | |
| error=$? | |
| set -e | |
| echo "::remove-matcher owner=yamllint::" | |
| exit ${error} |