name: Proper linting on Bash, Python, and YAML files

on: [pull_request]

permissions:
  contents: read
  actions: read

jobs:
  format_python_files:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Python Files Formatting Guidelines
      run: |
        echo "### Python Files Formatting Guidelines ###
        If there is a formatting error in your python files,
        1. First install black
            It requires Python 3.8+ to run.
            Install with  'pip install black' and if you use pipx, install Black with 'pipx install black'.
            If you want to format Jupyter Notebooks, install with 'pip install black[jupyter]'.

        2. Run the command
            'python -m black {source_file_or_directory}' or
            'black {source_file_or_directory}'
            to format python files.
        "
    - uses: psf/black@stable
      with:
        src: |
          ./common
          ./example

  format_YAML_files:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Install yamllint
      run: python3 -m venv myenv && source myenv/bin/activate && pip install yamllint

    - name: YAML Formatting Guidelines
      run: |
        echo "### YAML Formatting Guidelines ###
        If there is a formatting error in your YAML file, you will see errors like the one below:
        'Error: 6:4 [indentation] wrong indentation: expected 2 but found 3'

        6:4 means line 6, column 4.

        To fix these errors, refer to the YAML formatting rules at:
        https://yamllint.readthedocs.io/en/stable/rules.html#

        Search for the keyword inside the brackets [] in the error message. In this example, it's 'indentation'.
        Note: Some rules have been customized in the '.yamllint.yaml' file. Below is the content of that file:

        extends: default

        rules:
          document-start:
            present: false
          document-end:
            present: false
          indentation:
            indent-sequences: false
          line-length:
            max: 400
        "

    - name: Fetch master branch
      run: git fetch origin master

    - name: Set up changed files
      id: changed_files
      run: |
        git diff --name-only --diff-filter=AM origin/master...HEAD \
        | grep -v 'upstream' \
        | grep -E '^common/.*\.ya?ml$|^example/.*\.ya?ml$|^hack/.*\.ya?ml$|^tests/.*\.ya?ml$|^.github/.*\.ya?ml$' \
        > changed_files_in_PR.txt || true
        if [ ! -s changed_files_in_PR.txt ]; then
          echo "No YAML files have changed in this PR." > changed_files_in_PR.txt
        fi

    - name: Display changed files
      run: cat changed_files_in_PR.txt

    - name: Run yamllint on changed files
      id: lint
      run: |
        if grep -q 'No YAML files have changed in this PR.' changed_files_in_PR.txt; then
          echo "No YAML files have changed in this PR."
        else
          cat changed_files_in_PR.txt | xargs -I {} yamllint {} || exit 1
        fi
      shell: bash

    - name: Check YAML lint results
      if: success() && steps.lint.outcome == 'success'
      run: echo "No styling issues with YAML files."
      shell: bash

  format_bash_files:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Install ShellCheck
      run: sudo apt install -y shellcheck

    - name: Bash Formatting Guidelines
      run: |
        echo "### Bash Files Formatting Guidelines ###
        If there are errors and warnings regarding your bash files,
        You can check the error code definitions at https://www.shellcheck.net/wiki/.
        You can correct them using the https://www.shellcheck.net/ site.
        You have to ignore disable errors in the .shellcheckrc file.
        "

    - name: Fetch master branch
      run: git fetch origin master

    - name: Set up changed files
      id: changed_files
      run: |
        git diff --name-only origin/master...HEAD | grep -E '^[AM].*\.sh$' | grep -v '^applications/' | awk '{print $2}' > changed_files_in_PR.txt || true
        if [ ! -s changed_files_in_PR.txt ]; then
          echo "No bash files have changed in this PR."
        fi

    - name: Display changed files
      if: always() # Always run this step
      run: cat changed_files_in_PR.txt || echo "No bash files have changed in this PR."

    - name: Run ShellCheck on changed files
      id: lint
      run: |
        if grep -q 'No bash files have changed in this PR.' changed_files_in_PR.txt; then
          echo "No bash files have changed in this PR."
        else
          cat changed_files_in_PR.txt | xargs -I {} shellcheck {} || exit 1
        fi
      shell: bash

    - name: Check Bash lint results
      if: success() && steps.lint.outcome == 'success'
      run: echo "No styling issues with Bash files."
      shell: bash
